Проверьте, действует ли автоматически возобновляемая подписка
Я хотел бы проверять состояние подписки с автоматическим продлением при каждом открытии приложения.
Это сделано для того, чтобы убедиться, что пользователь все еще подписан на услугу. Как мне этого добиться?
Какие-нибудь мысли? Спасибо
PS: я использую SwiftyStoreKit
2 ответа
Вот несколько способов проверки квитанций, чтобы проверить, предоставляется ли пользователю подписка. Вот два способа сделать это правильно:
- Сделайте подтверждение квитанции локально, как написано здесь.
Подтвердите квитанцию удаленно, как написано здесь. Упоминается, что квитанцию не следует отправлять в App Store белым приложением. Краткое содержание:
- Ваше приложение отправляет квитанцию на ваш бэкэнд.
- Ваш бэкэнд отправляет чек в бэкэнд Apple для проверки.
- Ваш бэкэнд получает ответ от яблока.
- Ваш бэкэнд отправляет результат обратно в ваше приложение, чек действителен или недействителен.
В обоих случаях вы получите список покупок в приложении. Он также будет содержать просроченные подписки. Вам нужно будет пройти через все подписки и проверить сроки годности. Если он все еще действителен, вы должны предоставить пользователю подписку.
Как я понимаю, вы используете SwiftyStoreKit, и здесь открытое задание для проверки локальной квитанции.
Вы можете проверить с помощью этой функции. его работы с swift4
func receiptValidation() {
let SUBSCRIPTION_SECRET = "yourpasswordift"
let receiptPath = Bundle.main.appStoreReceiptURL?.path
if FileManager.default.fileExists(atPath: receiptPath!){
var receiptData:NSData?
do{
receiptData = try NSData(contentsOf: Bundle.main.appStoreReceiptURL!, options: NSData.ReadingOptions.alwaysMapped)
}
catch{
print("ERROR: " + error.localizedDescription)
}
//let receiptString = receiptData?.base64EncodedString(options: NSData.Base64EncodingOptions(rawValue: 0))
let base64encodedReceipt = receiptData?.base64EncodedString(options: NSData.Base64EncodingOptions.endLineWithCarriageReturn)
print(base64encodedReceipt!)
let requestDictionary = ["receipt-data":base64encodedReceipt!,"password":SUBSCRIPTION_SECRET]
guard JSONSerialization.isValidJSONObject(requestDictionary) else { print("requestDictionary is not valid JSON"); return }
do {
let requestData = try JSONSerialization.data(withJSONObject: requestDictionary)
let validationURLString = "https://sandbox.itunes.apple.com/verifyReceipt" // this works but as noted above it's best to use your own trusted server
guard let validationURL = URL(string: validationURLString) else { print("the validation url could not be created, unlikely error"); return }
let session = URLSession(configuration: URLSessionConfiguration.default)
var request = URLRequest(url: validationURL)
request.httpMethod = "POST"
request.cachePolicy = URLRequest.CachePolicy.reloadIgnoringCacheData
let task = session.uploadTask(with: request, from: requestData) { (data, response, error) in
if let data = data , error == nil {
do {
let appReceiptJSON = try JSONSerialization.jsonObject(with: data)
print("success. here is the json representation of the app receipt: \(appReceiptJSON)")
// if you are using your server this will be a json representation of whatever your server provided
} catch let error as NSError {
print("json serialization failed with error: \(error)")
}
} else {
print("the upload task returned an error: \(error)")
}
}
task.resume()
} catch let error as NSError {
print("json serialization failed with error: \(error)")
}
}
}
Я хотел предложить альтернативное решение, использующее Доходный SDK для тех, кто все еще сталкивается с этим вопросом.
AppDelegate.swift
Сконфигурируйте SDK RevenueCat Закупки с вашим ключом API и необязательным идентификатором пользователя.
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
Purchases.configure(withAPIKey: "<...>", appUserID: "<...>")
...
return true
}
Функция статуса подписки
Функция ниже проверяет PurchaserInfo
чтобы увидеть, есть ли у пользователя еще "активные права" (или вы можете напрямую проверить активный идентификатор продукта).
func subscriptionStatus(completion: @escaping (Bool)-> Void) {
Purchases.shared.purchaserInfo { (info, error) in
// Check if the purchaserInfo contains the pro feature ID you configured
completion(info?.activeEntitlements.contains("pro_feature_ID") ?? false)
// Alternatively, you can directly check if there is a specific product ID
// that is active.
// completion(info?.activeSubscriptions.contains("product_ID") ?? false)
}
}
Получение статуса подписки
Вы можете вызывать вышеуказанную функцию так часто, как это необходимо, так как результат кэшируется SDK для покупок, в большинстве случаев он будет возвращаться синхронно и не требует сетевого запроса.
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
subscriptionStatus { (subscribed) in
if subscribed {
// Show that great pro content
}
}
}
Если вы используете SwiftyStoreKit, синтаксис RevenueCat довольно похож, и есть руководство по миграции, чтобы помочь переключиться.
Еще одно решение для обработки автоматически возобновляемой подписки iOS с помощью Qonversion SDK.
AppDelegate.swift
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
Qonversion.launch(withKey: "yourProjectKey")
return true
}
Получить статус подписки
Свяжите подписку App Store с продуктом Qonversion и свяжите продукт с разрешением. Тогда вам просто нужно вызвать
checkPermissions
в начале вашего приложения, чтобы проверить, действительна ли подписка пользователя. Этот метод проверит квитанцию пользователя и вернет текущие разрешения. А затем для все еще активной подписки вы можете получить подробную информацию, если подписчик отключил автоматическое продление, находится ли он в льготном периоде (состояние повторного выставления счета) и т. Д.
Qonversion.checkPermissions { (permissions, error) in
if let error = error {
// handle error
return
}
if let premium = permissions["premium"], premium.isActive {
switch premium.renewState {
case .willRenew, .nonRenewable:
// .willRenew is the state of an auto-renewable subscription
// .nonRenewable is the state of consumable/non-consumable IAPs that could unlock lifetime access
break
case .billingIssue:
// Grace period: permission is active, but there was some billing issue.
// Prompt the user to update the payment method.
break
case .cancelled:
// The user has turned off auto-renewal for the subscription, but the subscription has not expired yet.
// Prompt the user to resubscribe with a special offer.
break
default: break
}
}
}
Вы можете проверить наш образец приложения, демонстрирующий реализацию автоматически возобновляемой подписки здесь.