I am verifying in-app-purchase receipts using the following code:
- (void) completeTransaction:(SKPaymentTransaction*) transaction
{
NSData* receipt = nil;
// 1. Attempt <app receipt> first (iOS 7.x)
NSBundle* mainBundle = [NSBundle mainBundle];
if ([mainBundle respondsToSelector:@selector(appStoreReceiptURL)]) {
NSURL* appStoreReceiptURL = [mainBundle appStoreReceiptURL]; // <- CRASH
receipt = [NSData dataWithContentsOfURL:appStoreReceiptURL];
}
// 2. Fallback to <transaction receipt> (iOS < 7.0)
if (!receipt) {
receipt = [transaction transactionReceipt];
}
// 3. Have server verify it with iTunes:
[self verifyReceipt:receipt forTransaction:transaction];
}
On an iOS 6 device, the execution stops at the line NSURL* appStoreReceiptURL = [mainBundle appStoreReceiptURL];
and the console spits:
-[NSBundle appStoreReceiptURL]: unrecognized selector sent to instance 0x208492d0
Am I missing something? Wasn't -respondsToSelector:
supposed to take care of this? Must I fall back to checking the OS version directly??
YES you should check version number directly in case of this appStoreReceiptURL Method. appStoreReceiptURL
In iOS, use the following code to detect whether this method is available:
if (floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_6_1) {
// Load resources for iOS 6.1 or earlier
} else {
// Load resources for iOS 7 or later
}
Note: The general best practice of weak linking using the respondsToSelector: method cannot be used here. Prior to iOS 7, the method (appStoreReceiptURL) was implemented as private API, but that implementation called the doesNotRecognizeSelector: method.
Reference:NSBundle Class reference
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