Как узнать, активна ли подписка iOS - PullRequest
0 голосов
/ 02 октября 2018

Я добавляю подписку iOS inapp в свое приложение.Я следую этому замечательному учебнику со страницы Рэя Вендерлиха:

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

В основном учебник состоит из следующих шагов:

  1. подписка на покупку
  2. получить квитанцию ​​
  3. проверить квитанцию ​​в Apple (это должно быть сделано через бэкэнд, но для простоты учебник делает это в приложении).
  4. после проверки квитанции Apple отвечает сJSON обработал квитанцию.
  5. приложение локально хранит приобретенные товары и связывает их с sessionID (UUID создан).

После завершения урока кажется, что все работает хорошо, ноУ меня проблемы с двумя проблемами.

Каждый раз, когда пользователь входит в приложение, он проверяет, есть ли у него действительный идентификатор сессии и действительная квитанция:

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)
    }
  }

И value currentSessionId устанавливается, когда Apple отвечает на подтверждение получения:

  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 и квитанция, больше ничего, поэтому, если они существуют, но срок действия подписки истек, приложение не знает об этом, и пользователь продолжает использовать ее без какой-либо активной подписки.Что я должен сделать, чтобы избежать этого случая?Сохранять локально в UserDefaults обработанную JSON-квитанцию ​​и проверять дату истечения срока действия?

  2. И поскольку currentSessionId не сохраняется постоянно, если я убиваю приложение и снова запускаю его, currentSessionId будет нулевым, первымпроверка не удалась, и пользователь не может использовать приложение.Каков наилучший способ справиться с этим?Снова хранить локально в UserDefaults currentSessionID?

РЕДАКТИРОВАТЬ

Глядя на некоторые похожие вопросы, кажется, что каждый раз, когда пользователь входит в приложение, прежде чем проверять currentSessionID и квитанцию, я должен проверитьлокально хранится квитанция, это правильно?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...