'How to test receipt when Migrating iOS app from Paid to Freemium/Free in SwiftUI
I'm planning to update my app from a Paid app to a Free app with possible IAPs. I've come across the Receipt Validation, but I'm finding it very confusing. All I want to do is check the original_purchase_date
of the Application, (NOT an IAP). All of those who purchased before the update, will have the original features unlocked automatically.
I've got this so far for loading the receipt:
#if DEBUG
private let appStoreValidationURL = URL(string: "https://sandbox.itunes.apple.com/verifyReceipt")!
#else
private let appStoreValidationURL = URL(string: "https://buy.itunes.apple.com/verifyReceipt")!
#endif
private func loadReceipt() {
print("LOAD RECEIPT")
// Get the receipt if it's available
if let appStoreReceiptURL = Bundle.main.appStoreReceiptURL,
FileManager.default.fileExists(atPath: appStoreReceiptURL.path) {
do {
let receiptData = try Data(contentsOf: appStoreReceiptURL, options: .alwaysMapped)
print(receiptData)
// Handle the try. I skipped that to make easier to read
let base64String = receiptData.base64EncodedString(options: [])
// Encode data in JSON
let content: [String : Any] = ["receipt-data" : base64String,
"password" : sharedSecret,
"exclude-old-transactions" : true]
let json = try! JSONSerialization.data(withJSONObject: content, options: [])
// build request
let storeURL = self.appStoreValidationURL
var request = URLRequest(url: storeURL)
request.httpMethod = "POST"
request.httpBody = json
// Make request to app store
URLSession.shared.dataTask(with: request) { (data, res, error) in
guard error == nil, let data = data else {
return
}
do {
let decoder = JSONDecoder()
let response = try decoder.decode(ReceiptAppStoreResponse.self, from: data)
} catch {
// Handle error
}
}.resume()
// Read receiptData
}
catch { print("Couldn't read receipt data with error: " + error.localizedDescription) }
}
}
The problem here is that it doesn't go past if let appStoreReceiptURL
as there seems to be no receipt, even if I download the app from the app store and then build on top of it. Is there a way to test this? I need to see if the rest of the code is working to decode the receipt and get the original_purchase_date
Here is the rest:
private struct ReceiptAppStoreResponse: Decodable {
let status: Int?
let receipt: String?
let latestReceipt: String?
let latestReceiptInfo: [ReceiptInfo]?
enum CodingKeys: String, CodingKey {
case status
case receipt
case latestReceipt = "latest_receipt"
case latestReceiptInfo = "latest_receipt_info"
}
}
struct ReceiptInfo: Decodable {
let originalTransactionID: String?
let productID: String?
let expiresDateMS: String?
let originalPurchaseDateMS: String?
let isTrialPeriod: String?
let isInIntroOfferPeriod: String?
let purchaseDateMS: String?
enum CodingKeys: String, CodingKey {
case originalTransactionID = "original_transaction_id"
case productID = "product_id"
case expiresDateMS = "expires_date_ms"
case originalPurchaseDateMS = "original_purchase_date_ms"
case isTrialPeriod = "is_trial_period"
case isInIntroOfferPeriod = "is_in_intro_offer_period"
case purchaseDateMS = "purchase_date_ms"
}
func getExpireDate() -> Date? {
let nf = NumberFormatter()
guard let expDateString = self.expiresDateMS, let expDateValue = nf.number(from: expDateString) else {
return nil
}
/// It's expressed as milliseconds since 1970!!!
let date = Date(timeIntervalSince1970: expDateValue.doubleValue / 1000)
return date
}
}
How can I test this to make sure that I am able to get the date and that I can correctly set up the app depending on when they originally purchased it?
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|