Jam*_*mes 4 objective-c in-app-purchase ios in-app-subscription
我有一个带有订阅(非续订)的 iOS 应用程序(目标 C)。当用户重新启动应用程序时,如何检查它是否仍然处于活动状态?
我已经阅读了很多有关此内容的内容,但答案似乎不清楚如何正确执行此操作。
我目前所拥有的是当应用程序启动时我注册 TransactionObserver,
IAPManager* iapManager = [[IAPManager alloc] init];
[[SKPaymentQueue defaultQueue] addTransactionObserver: iapManager];
Run Code Online (Sandbox Code Playgroud)
然后当用户购买时我有,
- (void) paymentQueue: (SKPaymentQueue *)queue updatedTransactions: (NSArray *)transactions {
for (SKPaymentTransaction *transaction in transactions) {
switch (transaction.transactionState) {
case SKPaymentTransactionStatePurchasing:
[self showTransactionAsInProgress:transaction deferred:NO];
break;
case SKPaymentTransactionStateDeferred:
[self showTransactionAsInProgress:transaction deferred:YES];
break;
case SKPaymentTransactionStateFailed:
[self failedTransaction:transaction];
[queue finishTransaction: transaction];
break;
case SKPaymentTransactionStatePurchased:
[self persistPurchase: transaction];
[queue finishTransaction: transaction];
break;
case SKPaymentTransactionStateRestored:
[self restoreTransaction:transaction];
[queue finishTransaction: transaction];stopBusy];
break;
default:
break;
}
}
}
Run Code Online (Sandbox Code Playgroud)
所以当用户第一次订阅时这工作得很好。但我对如何存储/跟踪这次购买感到困惑。我将其存储在用户订阅的静态变量中以启用应用程序功能,但是当用户重新启动应用程序时,我应该如何检查他们是否具有活动订阅?
我使用的代码将订阅存储在 iCloud 或 NSUserDefaults 中。在 iCloud 中存储根本不起作用,当他们重新启动应用程序时,他们就失去了订阅。存储在 NSUserDefaults 中是可行的,但订阅最终会过期,并且可以退款或取消。如何检查是否处于活动状态?我可以存储订阅日期并假设持续时间并尝试检查自己,但这似乎非常错误。
另外,如果用户卸载应用程序并重新安装,或者购买新手机等,该怎么办?
- (void) persistPurchase: (SKPaymentTransaction*) transaction {
#if USE_ICLOUD_STORAGE
NSUbiquitousKeyValueStore *storage = [NSUbiquitousKeyValueStore defaultStore];
#else
NSUserDefaults *storage = [NSUserDefaults standardUserDefaults];
#endif
if ([transaction.payment.productIdentifier isEqualToString: SUBSCRIPTION]) {
[storage setBool: true forKey: SUBSCRIPTION];
[IAPManager upgrade];
}
[storage synchronize];
[self unlockPurchase: transaction];
}
Run Code Online (Sandbox Code Playgroud)
为此我想我需要调用restoreCompletedTransactions。我认为不将订阅存储在 NSUserDefaults 中,而是在每次应用程序启动时调用 RestoreCompletedTransactions 是有意义的。
但据我所知,苹果似乎希望你有一个“恢复购买”按钮来做到这一点?每次应用程序启动时调用它是否有意义?这将调用您处理过的每笔付款的回调(我认为??) 对于每笔付款,如何知道它们是否仍然有效?
我可以获取交易日期,但这并不能告诉我付款是否过期,除非我假设它没有取消并假设持续时间并自己检查日期?或者 Apple 只为您提供来自 RestoreCompletedTransactions 的有效订阅/付款?
我还需要再次调用 finishTransaction 进行恢复吗?
[[SKPaymentQueue defaultQueue] restoreCompletedTransactions];
Run Code Online (Sandbox Code Playgroud)
\n\n当用户重新启动应用程序时,如何检查它是否仍然处于活动状态?
\n
https://developer.apple.com/documentation/storekit/in-app_purchase/persisting_a_purchase
\n\n\n对于非续订订阅,请使用 iCloud 或您自己的服务器来保存\n持久记录。
\n
我认为最好使用服务器(这样你可以收到退款通知),而不是 iCloud(你不会收到通知)。
\n我猜你的意思是你想检查一下:
\n我假设您使用收据。这很重要,因为您将需要它来计算订阅的持续时间,以防用户选择在到期前续订非续订订阅。
\n\n\n所以当用户第一次订阅时这工作得很好。但我很困惑\不知道你应该如何存储/跟踪这次购买。我存储在用户订阅的静态变量中以启用应用程序功能,但是当用户重新启动应用程序时,我应该如何检查他们是否具有活动订阅?
\n
我认为正确的方法是检查服务器上存储的记录。这是因为,退款通知将由 Apple 发送到您在服务器上配置的 URL。
\n此链接解释了如何通知您的服务器退款。\n https://developer.apple.com/documentation/storekit/in-app_purchase/handling_refund_notifications
\n由于苹果不会直接通知您的应用程序退款,因此您必须向您的服务器检查是否已发出退款。您与服务器的通信方式取决于您(定期轮询、推送通知等)。关键是,您应该在服务器上存储一条记录,并通知您的应用已收到退款,以便您可以决定是否撤销该功能。\n因为您需要在服务器上存储一条记录来检查如需退款,您也可以询问您自己的服务器订阅是否已过期。为此,您只需在应用程序中存储一个标识符(NSUserDefaults 等),以便您可以询问服务器该期限是否已过期。
\n这比简单地将订阅的结束日期存储在应用程序中要好,因为如果您以不安全的方式存储结束日期,用户可以简单地编辑文件并继续延长结束日期。苹果在以下链接中声明:
\n\n\n存储收据需要更多应用程序逻辑,但可以防止\n持久记录被篡改。\n由于您需要实现服务器来检查退款,因此使用服务器来检查订阅是否已过期是很简单的。
\n
\n\n存储在 NSUserDefaults 中是可行的,但订阅最终\n会过期,并且可能会被退款或取消。如何检查它是否\n处于活动状态?我可以存储订阅日期并假设持续时间并尝试检查自己,但这似乎非常错误。
\n
……
\n是的,我认为在设备上存储订阅日期并不是最好的方法,原因如下:
\n正确的方法是查询你的服务器。这样,他将无法编辑设备上的时间来欺骗您的应用程序延长他的订阅时间。如果您存储的订阅日期不安全,他也无法“编辑”订阅日期。应用程序应该简单地向您的服务器发送一个标识符,并收到关于订阅是否有效的“是”或“否”响应。以下链接描述了如何执行此操作:
\n\n\n将收据副本连同凭据或标识符发送到您的服务器,\n以便您可以跟踪哪些收据属于\n特定用户。例如,让用户使用用户名和密码向您的服务器\n证明自己的身份。不要使用 UIDevice 的identifierForVendor\n属性。不同的设备\n此属性具有不同的值,因此您无法使用它来识别和恢复同一用户\n在不同设备上进行的购买。
\n
..
\n\n\n为此我想我需要调用restoreCompletedTransactions。我认为\n不将订阅存储在 NSUserDefaults 中是有意义的,\n而是在每次应用程序启动时\n调用restoreCompletedTransactions。
\n但据我所知,苹果似乎希望你有一个“恢复\n购买”按钮来执行此操作?每次应用程序启动时都调用它是否有意义?这将调用您曾经处理过的每笔付款的回调(我认为??) 对于每笔付款,\n如何知道它们是否仍然有效?
\n
不,每次应用启动时调用恢复购买并不是一个好主意。苹果明确表示不要:
\nhttps://developer.apple.com/documentation/storekit/in-app_purchase/restoring_purchased_products
\n\n\n重要 不要自动恢复购买,尤其是当您的应用程序启动时。恢复用户\xe2\x80\x99s App Store\ncredentials 的购买提示,这会中断应用程序的流程。
\n
它还说:
\n\n\n但是,在给定的情况下,应用程序可能需要采用替代方法:...\n您的应用程序使用非续订订阅\xe2\x80\x94 您的应用程序负责\n恢复过程。
\n
在我看来,没有必要在每次启动应用程序时恢复购买- 恢复购买适用于您在新设备上重新安装/安装的情况。它也不会告诉您订阅是否已退款或是否处于活动状态,因为如果退款已发出,Apple 只会通知您的服务器 URL。每次应用程序启动时,您应该做的是查询服务器。\n苹果本身表示,要在服务器上更新用户帐户的余额,以识别退款滥用情况。
\n\n\n通过将退款通知映射到您服务器上的玩家帐户,\n减少退款滥用并识别重复的退款购买。\n监控并分析您的数据以识别可疑的退款活动。\n如果您跨多个平台提供内容,\n请及时更新用户帐户的余额在您的服务器上。使用 App Store Server 通知\n获得影响客户的交易的近实时状态更新。
\n
您应该实现“恢复购买”按钮,以处理用户卸载/重新安装应用程序/安装在不同设备上的情况。当用户恢复购买时,您应该能够计算与服务器通信所需的标识符,以检查订阅是否仍然有效(您可能只使用原始交易 ID)\n您的收据将包含原始购买日期以及产品 ID,并将在每次购买非续订订阅时更新。您可以通过调用刷新收据 (SKReceiptRefreshRequest) 来访问此数据,以便任何设备都有收据,并且您可以计算订阅期限。
\n\n\n我可以获取交易日期,但这并不能告诉我付款是否已过期,除非我假设它没有被取消并\n假设持续时间并自己检查日期?或者Apple 是否仅通过restoreCompletedTransactions 向\n您提供有效的订阅/付款?
\n
当您实现订阅行为时,第一次启动订阅时,您应该将到期日期存储在服务器上。如前所述,Apple 会将退款通知发送到您的服务器,因此您应该让您的应用程序检查您的服务器是否订阅被退款或过期。另请记住 - 用户可以更改他的设备时间/日期,以避免您在设备上存储到期日期。但是,如果您正在检查自己的服务器,他就不能,因为他无法篡改您服务器上的时间。
\n\n\n我还需要再次调用 finishTransaction 进行恢复吗?
\n
我使用 swift,在 swift 中你只需调用restoreCompletedTransactions()。它很容易实现。
\n\n此时,您可能想知道收据是否包含每笔非续订订阅购买的记录,那么为什么我需要服务器来检查订阅是否处于活动状态?
\n记住:
\n每次您的用户购买非续订订阅时,您都应该确保服务器上的逻辑计算出正确的结束日期。例如,如果他选择在当前订阅结束之前购买非续订订阅,您应该通过让下一个订阅仅在当前订阅结束时开始来正确计算结束日期。
\n| 归档时间: |
|
| 查看次数: |
4492 次 |
| 最近记录: |