13

我正在为我的应用(即将发布)实施应用内购买,并为 iOS6 和 iOS7 提供支持。我的问题与 iOS6 和 iOS7 之间的非续订订阅机制之间的差异有关,更具体地说,是关于如何实现恢复。为了同时适应 iOS6 和 iOS7,我实现了一个服务器端解决方案来启用恢复。我可以选择允许用户创建一个用户名/密码,该用户名/密码可用于不同的设备(如果数据丢失,则为同一设备)进行恢复。我的大部分工作基本上都在工作,但是随着我的测试的进行,我发现了一些奇怪的东西。

我的 iOS7 恢复过程的初始部分使用 SKReceiptRefreshRequest 来刷新应用程序中的收据。当我从 iOS7 设备上删除应用程序时,重新安装(此时没有收据;使用 iExplorer 测试)并进行恢复,SKReceiptRefreshRequest 恢复 10 次购买(我在测试期间为这个特定用户创建的) . 其中一张是非消耗品,九张收据是不可更新的。这让我很困惑。从 Apple 文档中,我只希望在刷新的收据中看到非消耗品购买。来自https://developer.apple.com/library/ios/releasenotes/General/ValidateAppStoreReceipt/Chapters/ValidateLocally.html

“消耗品和非续订订阅:在购买时将消耗品或非续订订阅的应用内购买收据添加到收据中。它会保存在收据中,直到您的应用完成该交易。在那之后,它会在下次更新收据时从收据中删除 - 例如,当用户进行另一次购买或您的应用显式刷新收据时。”</p>

关于非续订订阅,来自https://developer.apple.com/in-app-purchase/In-App-Purchase-Guidelines.pdf

使用 iCloud 或您自己的服务器来跟踪购买并允许用户将购买的订阅恢复到单个用户拥有的所有 iOS 设备

下表来自(https://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/StoreKitGuide/Chapters/Products.html

在此处输入图像描述

有人有任何见解吗?

问题:为什么 SKReceiptRefreshRequest 会在收据中留下非续订产品的购买?这是 Apple 文档中的错误还是发生了其他事情?

2014 年 2 月 23 日;更新:我最近向 Apple 提交了一份错误报告。还没有回音。虽然,实际上,我不希望这个“错误”消失!

2015 年 10 月 20 日;更新:看来苹果实际上已经解决了这个“错误”。现在,当我使用SKReceiptRefreshRequest(这似乎是 Apple 推荐的还原方法,请参阅https://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/StoreKitGuide/Chapters/Restoring.html)进行恢复时,我现在没有收到收据中显示的非续订订阅购买。我只得到非消耗品(我的应用只有非续订订阅和非消耗品购买)。在我写完这篇文章后,我将立即向 Apple 提交一份错误报告,因为他们的文档对预期的行为模棱两可。

到目前为止,我对此的测试包括我在 iOS 8.4 和 iOS9 上运行的应用程序(实际上是 9.1 测试版,因为我没有合适的设备运行生产版本),所以这似乎是 Apple 的服务器端更改,而不是严格说 iOS/设备方面的变化。另请注意,到目前为止,我的所有测试都是在我的应用程序的开发版本上进行的,在应用程序内购买沙箱中也是如此。我很快就会进行生产测试。

2015 年 12 月 3 日;更新; 在 Apple 技术支持的提示下,我进行了更多测试。这一次,在运行 iOS9.2 beta 4 (13C75) 的 iPad 上。看来我们现在已经恢复“正常”了,不再订阅了。也就是说,当我进行恢复时,我再次在收据中看到非续订订阅。

4

3 回答 3

4

请注意,App Receipt 中的持续非续订订阅不能保证您会被 App Store 审阅者接受。成功取决于特定的审稿人。我最近收到了来自 Apple 的这条消息:

我们发现您的应用包含一项功能,可通过输入用户的 Apple ID 和密码来恢复之前购买的应用内购买产品。但是,无法以这种方式恢复非续订应用内购买。

修改您的二进制文件以删除此功能是合适的。如果您希望用户能够恢复非续订订阅应用内购买产品,您将需要实施自己的恢复机制。

所以最后一次提交应用的尝试很不走运。与前几部不同。

所以现在,我的计划是将 App Receipt 存储在 iCloud Key-Value Storage 上并自动恢复所有购买。它将满足苹果的要求:

对于非续订订阅,请使用 iCloud 或您自己的服务器来保持永久记录。(c) 商店套件编程指南

这是为这些目的提供的 Apple 代码:

#if USE_ICLOUD_STORAGE
NSUbiquitousKeyValueStore *storage = [NSUbiquitousKeyValueStore defaultStore];
#else
NSUserDefaults *storage = [NSUserDefaults standardUserDefaults];
#endif

NSData *newReceipt = transaction.transactionReceipt;
NSArray *savedReceipts = [storage arrayForKey:@"receipts"];
if (!receipts) {
    // Storing the first receipt
    [storage setObject:@[newReceipt] forKey:@"receipts"];
} else {
    // Adding another receipt
    NSArray *updatedReceipts = [savedReceipts arrayByAddingObject:newReceipt];
    [storage setObject:updatedReceipts forKey:@"receipts"];
}

[storage synchronize];
于 2015-04-22T14:34:11.463 回答
2

这也让我很困惑。看了很多遍文档,终于在Receipt Validation Programming Guide的收据字段注释中看到了以下内容:

消费产品的应用内购买收据会在购买时添加到收据中。它会保存在收据中,直到您的应用完成该交易。在那之后,它会在下次更新收据时从收据中删除——例如,当用户进行另一次购买或您的应用显式刷新收据时。

非消耗品、自动续订订阅、非续订订阅或免费订阅的应用内购买收据将无限期保留在收据中。

而In-App Purchase Programming Guide中的“Persisting Using the App Receipt”部分仍然表明消耗品和非续订订阅的处理方式相同。

我从我们观察到的 IAP 文档已过时的行为中猜测?但愿如此。

于 2015-02-10T02:29:16.937 回答
1

Apple 推荐以下内容(在此处阅读概述)

...自动续订订阅的收据会随着时间的推移而增长,因为续订交易会永远保留在收据中。为了优化性能,App Store 可能会截断沙盒收据以删除旧交易。在验证沙盒环境中进行的交易的收据时,请考虑创建新的测试帐户,而不是重复使用旧帐户来测试订阅购买。

于 2021-02-03T19:08:54.133 回答