'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 |
---|