'Sometimes Receipt Validation for In-App Purchase is taking to much time to give response Swift

This is my verification validation code:

func receiptValidation(completion: @escaping(_ isPurchaseSchemeActive: Bool, _ error: Error?) -> ()) {
    let receiptFileURL = Bundle.main.appStoreReceiptURL
    guard let receiptData = try? Data(contentsOf: receiptFileURL!) else {
        //This is the First launch app VC pointer call
        completion(false, nil)
        return
    }
    let recieptString = receiptData.base64EncodedString(options: NSData.Base64EncodingOptions(rawValue: 0))
    let jsonDict: [String: AnyObject] = ["receipt-data" : recieptString as AnyObject, "password" : AppSpecificSharedSecret as AnyObject]
    
    do {
        let requestData = try JSONSerialization.data(withJSONObject: jsonDict, options: JSONSerialization.WritingOptions.prettyPrinted)
        let storeURL = URL(string: self.verifyReceiptURL)!
        var storeRequest = URLRequest(url: storeURL)
        storeRequest.httpMethod = "POST"
        storeRequest.httpBody = requestData
        let session = URLSession(configuration: URLSessionConfiguration.default)
        let task = session.dataTask(with: storeRequest, completionHandler: { [weak self] (data, response, error) in
            do {
                if let jsonResponse = try JSONSerialization.jsonObject(with: data!, options: JSONSerialization.ReadingOptions.mutableContainers) as? NSDictionary {
                    if let latestInfoReceiptObjects = self?.getLatestInfoReceiptObjects(jsonResponse: jsonResponse) {
                        self?.getCurrentTimeFromServer(completionHandler: { currentDateFromServer in
                            let purchaseStatus = self?.isPurchaseActive(currentDateFromServer: currentDateFromServer, latestReceiptInfoArray: latestInfoReceiptObjects)
                            completion(purchaseStatus!, nil)
                        })
                    }
                }
            } catch let parseError {
                completion(false, parseError)
            }
        })
        task.resume()
    } catch let parseError {
        completion(false, parseError)
    }
}

I start calling the observer inside of didFinishLaunchingWithOptions:

IAPManager.shared.startObserving()

And then call the receiptValidation to check the subscription status of product:

IAPManager.shared.receiptValidation { isPurchaseSchemeActive, error in
    //Handle authentication based on isPurchaseSchemeActive status
}

I end calling the observer inside of applicationWillTerminate:

IAPManager.shared.stopObserving()

I am also calling the receiptValidation inside of the applicationWillEnterForeground to check the validity whenever user come from background to foreground:

IAPManager.shared.receiptValidation { isPurchaseSchemeActive, error in
    //Handle authentication based on isPurchaseSchemeActive status
}

My IAPManager in short:

class IAPManager: NSObject {
    static let shared = IAPManager()     
    private override init() { super.init() }

    func startObserving() {
        SKPaymentQueue.default().add(self)
    }

    func stopObserving() {
        SKPaymentQueue.default().remove(self)
    }
}

And obviously calling receiptValidation after each successful purchase transaction and restoring product transactions before SKPaymentQueue.default().finishTransaction(transaction).

It works perfectly. But sometimes the receiptValidation stuck at JSON response for more than 10 or higher minutes. In this case, I am trying to cancel the receiptValidation call with a 1 minute timer. A pop up alert will appear saying try again and It will request the call again if user tap on "Try again" button.

My question is If I want to cancel an ongoing receiptValidation call, should I turn off IAPManager.shared.stopObserving() observer and turn on IAPManager.shared.startObserving() observer again before calling it? Or simply recall the receiptValidation request?



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source