I'm following apple's example code to the letter for how to implement receipt validation under iOS 7, and it works, except when I run the following code (taken basically verbatim from their sample) under iOS 6
NSBundle *bundle =[NSBundle mainBundle];
if ([bundle respondsToSelector:@selector(appStoreReceiptURL)]) { // can do local device receipt validation
NSURL *receiptURL = [bundle performSelector:@selector(appStoreReceiptURL)];
}
It returns true to the responds to selector, and therefore tries to perform the selector at which point it crashes because the selector doesn't exist... Why am I getting a positive response to a selector that doesn't exist?
The documentation for appStoreReceiptURL
explains that this method existed as a private method before iOS 7, and that its implementation prior to iOS 7 calls doesNotRecognizeSelector:
. Therefore you cannot use respondsToSelector:
to check whether it's ok to call the method.
Instead, you need to check the system version:
NSString *version = [UIDevice currentDevice].systemVersion;
if ([version compare:@"7.0" options:NSNumericSearch] != NSOrderedAscending) {
// safe to use appStoreReceiptURL
} else {
// not safe to use appStoreReceiptURL
}
I also got bitten by the bad sample code given at the WWDC session. It looks like Apple has updated their documentation with new reccomended sample code:
if (floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_6_1) {
// Load resources for iOS 6.1 or earlier
} else {
// Load resources for iOS 7 or later
}
Based on this sample, you could write it in a single branch like so if you prefer, and check afterwards if the object is nil:
NSURL* url = nil;
if (floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_6_1) {
//iOS 7 or later, safe to use appStoreReceiptURL
url = [[NSBundle mainBundle] performSelector:@selector(appStoreReceiptURL)];
}
I saw that in the WWDC 2013 talk (e.g., “Using Receipts to Protect Your Digital Sales”) too. And the conflicting statement in the appStoreReceiptURL docs. It seems that the WWDC 2013 code example for appStoreReceiptURL was untested.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With