Недавно мы перевели приобретаемое приложение на модель «freemium».Мы используем Bundle.main.appStoreReceiptURL, чтобы вытащить квитанцию и затем проверить «original_application_version», чтобы узнать, загрузил ли пользователь более старую платную версию из App Store, или же он загрузил более новую бесплатную версию с расходным материалом при покупке приложения.обновить до полной версии.
Это прекрасно работает при тестировании Sandbox, но в Production более старые версии приложения не проверяют должным образом, что они были загружены до версии freemium.
Следующий код вызывается с productionStoreURL и квитанцией, полученной от Bundle.main.appStoreReceiptURL:
private let productionStoreURL = URL(string: "https://buy.itunes.apple.com/verifyReceipt")
private let sandboxStoreURL = URL(string: "https://sandbox.itunes.apple.com/verifyReceipt")
private func verifyIfPurchasedBeforeFreemium(_ storeURL: URL, _ receipt: Data) {
do {
let requestContents:Dictionary = ["receipt-data": receipt.base64EncodedString()]
let requestData = try JSONSerialization.data(withJSONObject: requestContents, options: [])
var storeRequest = URLRequest(url: storeURL)
storeRequest.httpMethod = "POST"
storeRequest.httpBody = requestData
URLSession.shared.dataTask(with: storeRequest) { (data, response, error) in
DispatchQueue.main.async {
if data != nil {
do {
let jsonResponse = try JSONSerialization.jsonObject(with: data!, options: []) as! [String: Any?]
if let statusCode = jsonResponse["status"] as? Int {
if statusCode == 21007 {
print("Switching to test against sandbox")
self.verifyIfPurchasedBeforeFreemium(self.sandboxStoreURL!, receipt)
}
}
if let receiptResponse = jsonResponse["receipt"] as? [String: Any?], let originalVersion = receiptResponse["original_application_version"] as? String {
if self.isPaidVersionNumber(originalVersion) {
// Update to full paid version of app
UserDefaults.standard.set(true, forKey: upgradeKeys.isUpgraded)
NotificationCenter.default.post(name: .UpgradedVersionNotification, object: nil)
}
}
} catch {
print("Error: " + error.localizedDescription)
}
}
}
}.resume()
} catch {
print("Error: " + error.localizedDescription)
}
}
private func isPaidVersionNumber(_ originalVersion: String) -> Bool {
let pattern:String = "^\\d+\\.\\d+"
do {
let regex = try NSRegularExpression(pattern: pattern, options: [])
let results = regex.matches(in: originalVersion, options: [], range: NSMakeRange(0, originalVersion.count))
let original = results.map {
Double(originalVersion[Range($0.range, in: originalVersion)!])
}
if original.count > 0, original[0]! < firstFreemiumVersion {
print("App purchased prior to Freemium model")
return true
}
} catch {
print("Paid Version RegEx Error.")
}
return false
}
Первая версия freemium - 3.2, которая является нашей текущей сборкой.Все предыдущие сборки были 3.1.6 или более ранние.
Рабочий URL-адрес не должен быть проблемой, иначе он не отбросит код состояния 21007, чтобы вызвать проверку Sandbox для нас.Тем не менее, поиск и устранение неисправностей является особенно сложной задачей, поскольку мы не можем проверить сам производственный URL-адрес Apple.
Кто-нибудь знает, почему это работает в песочнице, но не в производственной?