Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get the original_application_version (the first purchased version number) out of iOS Receipt in iOS 11?

I have a paid iOS App.

I need to get the original_application_version number (the first version purchased by the user) from the Apple AppStore Receipt.

To get the receipt, when my app loads, I use checkReceiptFromAppStore() function:

func checkReceiptFromAppStore() {
    let receipt = self.getReceipt()
    print("receipt Data is: \(receipt)") // prints this: receipt Data is: Optional(5141 bytes)       
}

getReceipt() function is the following:

func getReceipt() -> Data? {
    if Bundle.main.appStoreReceiptURL != nil {
        print("app receipt: \(Bundle.main.appStoreReceiptURL)")
        do {
            let receiptData = try Data(contentsOf: Bundle.main.appStoreReceiptURL!)

            return receiptData
        } catch {
            print("error converting receipt to Data: \(error.localizedDescription)")
        }
    }
    return nil
}

I've watched WWDC 2017 Advanced StoreKit video about In App purchases and receipt validation and WWDC 2013 Video about using Receipts, read different resources related to my problem (this, this, this, this, this, this, and this...), but I still don't understand what to do next to get the "original_application_version" from the App Store Receipt. I need only this field and don't understand why is it so hard to get it. I've read this too: https://developer.apple.com/library/content/releasenotes/General/ValidateAppStoreReceipt/Chapters/ReceiptFields.html

I think that the receipt is not nil as long at when I run print("receipt Data is: (receipt)") it prints this: receipt Data is: Optional(5141 bytes)

I can suppose that I should parse the receipt to get that field. Can I do it using Decodable? Is there the easiest way to get this original_application_version field? Is it possible to do this without a receipt validation?

I need to get the original_application_version field only to detect the number of the first version bought by the user. If you know any other solutions to get the first purchased version number, I'd be glad to hear them.

I'm developing in Xcode 9, Swift 4, iOS 11

Any answers appreciated, thanks.

like image 629
Adelmaer Avatar asked Dec 21 '17 11:12

Adelmaer


1 Answers

All receipt fields are in binary format within application receipt. You should use any kind of app receipt decoder in order to get original_application_version. It is always good thing to validate app receipt before using its contents. For example, you can use RMStore framework (RMStore). It contains receipt validator as well as decoder. Example Obj-C source:

RMAppReceipt *appReceipt = RMAppReceipt.bundleReceipt;

if (appReceipt != nil && 
    [appReceipt.originalAppVersion length] > 0 && 
    ![appReceipt.originalAppVersion isEqualToString:@"1.0"]) {
    //Process your original app version 
} else {
    //Probably it is sandbox mode or app install via Xcode
    //Or maybe you should force app receipt refresh
}
like image 74
izhylenko Avatar answered Sep 19 '22 20:09

izhylenko