11

我正在按照苹果的示例代码来了解如何在 iOS 7 下实现收据验证,并且它可以工作,除非我在 iOS 6 下运行以下代码(基本上逐字从他们的示例中获取)

NSBundle *bundle =[NSBundle mainBundle];
if ([bundle respondsToSelector:@selector(appStoreReceiptURL)]) { // can do local device receipt validation
    NSURL *receiptURL = [bundle performSelector:@selector(appStoreReceiptURL)];
}

它对选择器的响应返回 true,因此尝试执行选择器,此时由于选择器不存在而崩溃……为什么我对不存在的选择器得到肯定的响应?

4

3 回答 3

7

的文档appStoreReceiptURL解释了这个方法在 iOS 7 之前作为私有方法存在,并且它在 iOS 7 调用之前的实现doesNotRecognizeSelector:。因此,您不能使用respondsToSelector:来检查是否可以调用该方法。

相反,您需要检查系统版本:

NSString *version = [UIDevice currentDevice].systemVersion;
if ([version compare:@"7.0" options:NSNumericSearch] != NSOrderedAscending) {
    // safe to use appStoreReceiptURL
} else {
    // not safe to use appStoreReceiptURL
}
于 2013-09-16T22:14:23.387 回答
5

我也被 WWDC 会议上给出的错误示例代码所困扰。看起来 Apple 已经用新的推荐示例代码更新了他们的文档:

if (floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_6_1) {
   // Load resources for iOS 6.1 or earlier
} else {
   // Load resources for iOS 7 or later
}

基于这个示例,如果您愿意,您可以像这样在单个分支中编写它,然后检查对象是否为 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)];
}
于 2013-11-13T19:49:21.047 回答
1

我在 WWDC 2013 的演讲中也看到了这一点(例如,“使用收据保护您的数字销售”)以及appStoreReceiptURL 文档中的冲突声明。appStoreReceiptURL 的 WWDC 2013 代码示例似乎未经测试。

于 2013-10-19T19:24:21.500 回答