如何知道iOS订阅是否有效

时间:2018-10-02 12:50:55

标签: ios in-app-subscription

我正在向我的应用添加iOS inapp订阅。我正在关注Ray Wenderlich页面上的精彩教程:

https://www.raywenderlich.com/659-in-app-purchases-auto-renewable-subscriptions-tutorial

本教程基本上按照以下步骤操作:

  1. 购买订阅
  2. 收到收据
  3. 验证Apple中的收据(这应该通过后端完成,但为简单起见,本教程在应用程序中进行了验证)。
  4. 验证收据后,Apple会使用JSON解析的收据进行响应。
  5. 该应用在本地存储购买的商品,并将其与sessionID(创建的UUID)相关联。

完成本教程后,似乎一切正常,但是我遇到了两个问题。

用户每次进入应用程序时,都会检查它是否具有有效的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)
        }
      }
    }
  }

好吧,我的疑问是这些:

  1. 每次用户进入应用程序时,它只会检查currentSessionId和收据是否存在,而没有其他内容,因此,如果它们存在但订阅已过期,则应用程序将不知道该内容,并且用户会继续使用它而不会任何有效的订阅。为避免这种情况该怎么办?本地存储在解析后的JSON收据的UserDefaults中,并检查到期日期?

  2. 并且由于currentSessionId不会永久存储,如果我终止了该应用程序并再次启动,则currentSessionId为null,则第一次检查失败,并且用户无法使用该应用程序。最好的管理方式是什么?再次在本地存储在UserDefaults中的currentSessionID?

编辑

看着一些类似的问题,似乎每次用户进入应用程序之前,在检查currentSessionID和收据之前我都必须验证本地存储的收据,对吗?

0 个答案:

没有答案
相关问题