iOS: How to detect if a user is subscribed to an auto-renewable subscription iOS: How to detect if a user is subscribed to an auto-renewable subscription ios ios

iOS: How to detect if a user is subscribed to an auto-renewable subscription


I know everyone was very concerned about me and how I was doing on this - fear not, solved my problem. Main problem was that I tried Apple's example code from the documentation, but it wasn't working so I gave up on it. Then I came back to it and implemented it with Alamofire and it works great. Here's the code solution:

Swift 3:

let receiptURL = Bundle.main.appStoreReceiptURLlet receipt = NSData(contentsOf: receiptURL!)let requestContents: [String: Any] = [    "receipt-data": receipt!.base64EncodedString(options: []),    "password": "your iTunes Connect shared secret"]let appleServer = receiptURL?.lastPathComponent == "sandboxReceipt" ? "sandbox" : "buy"let stringURL = "https://\(appleServer).itunes.apple.com/verifyReceipt"print("Loading user receipt: \(stringURL)...")Alamofire.request(stringURL, method: .post, parameters: requestContents, encoding: JSONEncoding.default)    .responseJSON { response in        if let value = response.result.value as? NSDictionary {            print(value)        } else {            print("Receiving receipt from App Store failed: \(response.result)")        }}


As some comments pointed out there's a couple flaws with these answers.

  1. Calling /verifyReceipt from the client isn't secure.
  2. Comparing expiration dates against the device clock can be spoofed by changing the time (always a fun hack to try after cancelling a free trial :) )

There are some other tutorials of how to set up a server to handle the receipt verification, but this is only part of the problem. Making a network request to unpack and validate a receipt on every app launch can lead to issues, so there should be some caching too to keep things running smoothly.

The RevenueCat SDK provides a good out-of-the box solution for this.

A couple reasons why I like this approach:

  • Validates receipt server side (without requiring me to set up a server)
  • Checks for an "active" subscription with a server timestamp so can't be spoofed by changing the device clock
  • Caches the result so it's super fast and works offline

There's some more details in this question: https://stackoverflow.com/a/55404121/3166209

What it works down to is a simple function that you can call as often as needed and will return synchronously in most cases (since it's cached).

subscriptionStatus { (subscribed) in    if subscribed {        // Show that great pro content    }}


What are you trying to achieve in particular? Do you want to check for a specific Apple ID?

I highly doubt that this is possible through the SDK. Referring to Is it possible to get the user's apple ID through the SDK? you can see that you can't even ask for the ID directly but rather services attached to it.

What would work is caching all transactions on your own server and search its database locally but that would require the app to ask for the user's Apple ID so the app could update the subscription state whenever it launches as it can check for IAP of the ID associated with the device.

However, the user could just type whatever he wanted - and it's unlikely to get this through Apple's app review process.