我正在向我的应用添加iOS inapp订阅。我正在关注Ray Wenderlich页面上的精彩教程:
https://www.raywenderlich.com/659-in-app-purchases-auto-renewable-subscriptions-tutorial
本教程基本上按照以下步骤操作:
完成本教程后,似乎一切正常,但是我遇到了两个问题。
用户每次进入应用程序时,都会检查它是否具有有效的sessionID和有效的收据:
guard SubscriptionService.shared.currentSessionId != nil,
SubscriptionService.shared.hasReceiptData else {
showRestoreAlert()
return
}
loadSelfies()
hasReceiptData执行此操作:
var hasReceiptData: Bool {
return loadReceipt() != nil
}
private func loadReceipt() -> Data? {
guard let url = Bundle.main.appStoreReceiptURL else {
return nil
}
do {
let data = try Data(contentsOf: url)
return data
} catch {
print("Error loading receipt data: \(error.localizedDescription)")
return nil
}
}
}
这些方法仅检查收据是否存在,而没有其他内容。
要检查currentSessionId,请使用以下方法:
var currentSessionId: String? {
didSet {
NotificationCenter.default.post(name: SubscriptionService.sessionIdSetNotification, object: currentSessionId)
}
}
并且当Apple响应收据验证时设置currentSessionId的值:
func uploadReceipt(completion: ((_ success: Bool) -> Void)? = nil) {
if let receiptData = loadReceipt() {
SelfieService.shared.upload(receipt: receiptData) { [weak self] (result) in
guard let strongSelf = self else { return }
switch result {
case .success(let result):
strongSelf.currentSessionId = result.sessionId
strongSelf.currentSubscription = result.currentSubscription
completion?(true)
case .failure(let error):
print(" Receipt Upload Failed: \(error)")
completion?(false)
}
}
}
}
好吧,我的疑问是这些:
每次用户进入应用程序时,它只会检查currentSessionId和收据是否存在,而没有其他内容,因此,如果它们存在但订阅已过期,则应用程序将不知道该内容,并且用户会继续使用它而不会任何有效的订阅。为避免这种情况该怎么办?本地存储在解析后的JSON收据的UserDefaults中,并检查到期日期?
并且由于currentSessionId不会永久存储,如果我终止了该应用程序并再次启动,则currentSessionId为null,则第一次检查失败,并且用户无法使用该应用程序。最好的管理方式是什么?再次在本地存储在UserDefaults中的currentSessionID?
编辑
看着一些类似的问题,似乎每次用户进入应用程序之前,在检查currentSessionID和收据之前我都必须验证本地存储的收据,对吗?