刷新iOS应用收据:如何确定用户是不是需要登录应用商店?

Posted

技术标签:

【中文标题】刷新iOS应用收据:如何确定用户是不是需要登录应用商店?【英文标题】:Refreshing iOS app receipt: How to determine if user will need to sign in for app store?刷新iOS应用收据:如何确定用户是否需要登录应用商店? 【发布时间】:2013-12-09 22:10:07 【问题描述】:

我正在 ios 7 上实现 Apple 的“大统一收据”,它允许应用程序在本地检查应用程序的购买收据,而无需联系 Apple 的服务器进行验证和验证。如果用户在应用程序中存储了收据,这将非常有用。如果应用缺少收据,最佳做法是请求应用刷新收据,如下所示:

SKReceiptRefreshRequest *request = [[SKReceiptRefreshRequest alloc] init];
[request setDelegate:self];
[request start];

问题是调用此代码将要求用户使用他或她的 Apple ID 登录。我不能 100% 确定这种情况是否一直发生,或者只有在用户的应用商店登录超时时才会发生。除非确实有必要,否则我不想向用户显示 Apple ID 登录屏幕——我不希望人们担心他们会被错误地收费。我想显示一个显示屏,告诉用户为什么会要求他们输入 Apple ID 密码,但前提是他们实际上需要输入密码。如果他们不需要输入密码,我希望它是一个无缝且隐藏的过程。最好的方法是什么?我认为最好的方法是检查用户是否需要登录应用商店,但我不确定这是否可能。

【问题讨论】:

【参考方案1】:

处理这个问题非常复杂,所以这个答案可能并不完全令人满意(我迟到了 - 我知道这一点),但仍然希望这能帮助你解决这个特殊问题.

我也有可能做的不对,但到目前为止一切正常并且对我来说很有意义,但是如果我在这里“说废话”,请随时纠正我。

但无论如何,您无法真正阻止身份验证警报的出现,但有几种方法可以最大限度地减少它的出现次数。

您无需重新下载您知道不存在的收据。如果用户没有购买或没有恢复收据,您可以避免尝试重新下载收据并完全避免警报视图。这是我做过的事情:

if([[NSFileManager defaultManager] fileExistsAtPath:[[[NSBundle mainBundle] appStoreReceiptURL] path]] != YES)

    SKReceiptRefreshRequest *refresh = [[SKReceiptRefreshRequest alloc] initWithReceiptProperties:nil];
    [refresh start];

我把它放在我的 main.m 文件中,在主应用程序循环之前,因为我的应用程序有许多可以通过 IAP 解锁的“专业”功能,但你真的可以把它放在你认为相关的地方。

主要思想是收据是存储在应用目录中的实际文件。所以我们在这里所做的一切都是检查收据是否真的存在。如果没有,我们就省去了重新刷新它的麻烦,从而省去了向用户显示身份验证屏幕的麻烦。

如果您愿意,您可以将此代码放在用户可能使用您应用的“专业”功能的任何地方。 SKReceiptRefreshRequest 继承自 SKRequest,因此它将调用 SKRequestDelegate 方法。因此,当用户导航到具有专业功能的屏幕时,您可以刷新收据,然后在调用委托方法时启用该功能(以及在完成检查收据内容的额外工作之后)。

这种方法的一大缺点是它确实需要互联网连接。如果您的应用离线工作,用户会期望其所有 IAP 也可以离线工作,因此在某些情况下重新下载收据将是一个问题。

【讨论】:

关于该主题的 Apple 文档非常糟糕(就像他们所做的所有文档一样,做过和将要做的 - 我有没有提到我讨厌他们的文档?)这里没有人会争论你是对还是错? 希望您的解决方案似乎有效。谢谢! @SpaceDog 除了收据问题,我完全不同意你的看法。我认为他们的文档是非常宝贵的资源。 苹果声明安装后收据确实存在!他们建议使用“恢复”按钮,以便用户仅在确定收据已过时时才刷新收据。 自从我两年前写下这个答案以来,情况可能已经发生了变化。 @AndyIbanez 你的意思是检查路径是否为 != YES?如果商店收据已经存在,您正在刷新...【参考方案2】:

在 App Store 应用中,收据通常存在。它与应用程序一起从 App Store 下载。如果用户使用 iTunes(即从备份)将您的应用加载到他们的设备上,则不会有收据。

收据不存在的主要用例是当您在 Xcode 中调试并且没有执行任何导致下载收据的操作(例如刷新收据或购买东西)。

在生产中,您只能在一些用户操作后获得新的(新鲜)收据(他们购买了东西,您刷新收据并登录,他们恢复购买并登录)。无法静默刷新收据。

如果您想在没有用户操作的情况下获得新收据,则必须走服务器路线。通过您的服务器将旧收据发送到 iTunes,取回最新收据。

【讨论】:

如果我们使用新用户帐户注册并且没有进行任何购买,应用收据网址是否存在???【参考方案3】:

我想分享我的经验。我一直在沙盒中工作,删除应用后应用收据丢失。 (然后重新Command-R-ing)我不知道这是否会在生产中发生,但听起来好像确实如此。在第一次启动应用程序时要求刷新,并提示用户输入密码是令人吃惊的。当然,这是一个问题。

似乎[[SKPaymentQueue defaultQueue] restoreCompletedTransactions] 也在静默刷新应用收据而不弹出对话框。意思是,在事务恢复后,请求 appReceiptURL + Data 返回一个非零值。这只是来自我的少量测试。请自行测试。

【讨论】:

刚试了一下,出现了 iTunes 登录提示 :( 所以至少在 iOS 12 中它不再沉默了......

以上是关于刷新iOS应用收据:如何确定用户是不是需要登录应用商店?的主要内容,如果未能解决你的问题,请参考以下文章

刷新 iOS IAP 收据以恢复购买始终会返回收据,即使未进行任何购买也是如此

iOS 7 自动续订订阅到期

iOS 测试应用收据验证

从 iOS 应用内购买收据中检索订单 ID/文件编号

iOS7应用收据中的交易ID何时更改?

防止重放攻击 appStoreReceiptURL 应用收据