0

XCode version = 26 && macOS version = 26

Running the app from XCode (not in release mode)

I want to implement in app purchases for my macOS application, for that i want to first test it locally through StoreKit config file.

Steps i have done uptill now:

  1. Added the capability in target-> Signing & Capabilities -> In_App Purchase(while adding this i had got the popup: Make changes to In-App Purchase by changing all configurations - i have no idea about it, Researched on it - didnt got something)
  2. Added the storekit config file -> added Group for autorenewable subscription -> reference name & product ID (i have used same Bundle ID and product ID, also i have used different both but still the same issue in both case) - also added it to scheme
  3. Added the storeManager implementation that is:
import StoreKit

class IAPManager {
    
    // Shared instance (optional singleton pattern)
    static let shared = IAPManager()
    
    private init() { }
    
    // Array to store fetched products
    var products: [Product] = []
    
    // MARK: - Fetch Products
    func fetchProducts() async {
        let productIDs = ["com.app.yearly"] 
        
        do {
            // Fetch products from StoreKit
            let fetchedProducts = try await Product.products(for: productIDs)
            self.products = fetchedProducts
            
            print("✅ Successfully fetched products:")
            
            for product in fetchedProducts {
                print("----------------------------")
                print("Product ID: \(product.id)")
                print("Display Name: \(product.displayName)")
                print("Description: \(product.description)")
                print("Price: \(product.displayPrice)")
                print("Subscription Type: \(product.type)")
//                if let subscription = product.subscription {
//                    print("Subscription Duration: \(product.duration)")
//                    print("Intro Offer: \(subscription.introductoryOffer?.description ?? "None")")
//                }
            }
            
        } catch {
            print("❌ Failed to fetch products: \(error)")
        }
    }
}

extension IAPManager {
    
    func observeTransactions() {
        Task.detached(priority: .background) {
            for await result in Transaction.updates {
                switch result {
                case .verified(let transaction):
                    print("🔄 Transaction updated: \(transaction.productID)")
                    // Finish transaction to mark as delivered
                    await transaction.finish()
                    
                case .unverified(_, let error):
                    print("⚠️ Transaction unverified: \(error.localizedDescription)")
                }
            }
        }
    }

    // MARK: - Purchase Product
    func purchase(product: Product) async {
        do {
            let result = try await product.purchase()
            
            switch result {
                
            case .success(let verification):
                // Check if transaction is verified
                switch verification {
                case .verified(let transaction):
                    print("✅ Purchase successful!")
                    print("Product ID: \(transaction.productID)")
                    print("Transaction ID: \(transaction.id)")
                    print("Purchase Date: \(transaction.purchaseDate)")
                    
                    // Finish transaction to update entitlements
                    await transaction.finish()
                    
                case .unverified(_, let error):
                    print("⚠️ Purchase verification failed: \(error.localizedDescription)")
                }
                
            case .userCancelled:
                print("❌ Purchase cancelled by user")
                
            case .pending:
                print("⏳ Purchase is pending...")
                
            @unknown default:
                print("❓ Unknown purchase result")
            }
            
        } catch {
            print("❌ Purchase failed with error: \(error.localizedDescription)")
        }
    }
}
  1. I triggered the function from my Viewcontroller:
// in viewDidLoad
Task {
      await IAPManager.shared.fetchProducts()
}

// in button action
Task {
     // Wait until products are fetched
     while IAPManager.shared.products.isEmpty {
         try? await Task.sleep(nanoseconds: 200_000_000) // 0.2s
     }
            
     guard let product = IAPManager.shared.products.first else {
         print("❌ No product available")
         return
     }
     print("Product to be purchased \(product)")
     await IAPManager.shared.purchase(product: product)
}
  1. In App Delegate:
// in applicationDidFinishLaunching
IAPManager.shared.observeTransactions()

Problem: Although the product is getting fetched correctly, but while purchasing it shows me the error in terminal as:

Error handling payment sheet request: Error Domain=NSCocoaErrorDomain Code=4099 
"The connection to service created from an endpoint was invalidated from this process." UserInfo={NSDebugDescription=The connection to service created from an endpoint was invalidated from this process.}

Purchase did not return a transaction: Error Domain=ASDErrorDomain Code=5115 "Received failure in response from Xcode" UserInfo={NSDebugDescription=Received failure in response from Xcode, NSUnderlyingError=0x600000c30c60 {Error Domain=NSCocoaErrorDomain Code=4099 "The connection to service created from an endpoint was invalidated from this process." UserInfo={AMSDescription=An unknown error occurred. Please try again., AMSURL=http://localhost:49409/WebObjects/MZBuy.woa/wa/inAppBuy, NSDebugDescription=The connection to service created from an endpoint was invalidated from this process., AMSStatusCode=200, AMSServerPayload=
    "app-list" =     (
    );
dialog =     
        cancelButtonString = Cancel;
        defaultButton = Buy;
        explanation = "Subscribe to\U00a0myApp.\U00a0This subscription will automatically renew every week for $45.99.\n\n[Environment: Xcode]";
        initialCheckboxValue = 1;
        "m-allowed" = 0;
        message = "Subscription Terms";
        okButtonAction =         
            buyParams = "bid=&bvrs=10.1.7&offerName=com.k.yearly&productType=A&quantity=1&deviceVerification=ab5eb999-1e70-5c91-9c69-6adf7a641e86";
            itemName = "com..yearly";
            kind = Buy;
        okButtonString = Continue;
        paymentSheetInfo =         
            caseControl = true;
            confirmationTitle = Subscribe;
            countryCode = US;
            currency = USD;
            designVersion = 2;
            flexList =             
                    value =                    
                                                
                            style = priceMain;
                            value = "$45.99 per week";
                               
                    header = "$null";
                    value = "For testing purposes only. You will not be charged for confirming this purchase.";
            );
            requestor = AppStore;
            salableIcon = "http://localhost:49409/StoreKit/AppIcon?bid=[myappID- that i added]";
            salableIconType = app;
            salableInfo =             (
                "my app Pro %%image_0%%",
                my app,
                Subscription
            );
           
    "download-queue-item-count" = 0;
    dsid = 17322632127;
    failureType = 5115;
    jingleAction = inAppBuy;
    jingleDocType = inAppSuccess;
    pings =     (
    );

Purchase failed with error: Couldn’t communicate with a helper application.

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.