JSON 解码器返回 没有与密钥编码密钥关联的值,例如 IAP 收据中的"expires_date"



我在大约 2 个月前Auto-Renewable subscriptions实现的,它们工作正常。

但是,当我现在回来在沙盒中测试它们时,我最终得到了No value with key expires_date found.

我调试并打印了latest_receipt_info,它显然是一个字符串。为什么会这样?我再次查看了收据,Apple更改了一些键以Int但我的expires日期仍然保持不变。我哪里出错了?

这是我的代码和收据。错误说

"没有与键 CodingKeys(stringValue: \"expires_date\", intValue: nil) (\"expires_date\")关联的值。">

最新收据

"latest_receipt_info" =     (
{
"expires_date" = "2019-02-06 15:50:21 Etc/GMT";
"expires_date_ms" = 1549468221000;
"expires_date_pst" = "2019-02-06 07:50:21 America/Los_Angeles";
"is_in_intro_offer_period" = false;
"is_trial_period" = false;
"original_purchase_date" = "2019-03-21 08:37:40 Etc/GMT";
"original_purchase_date_ms" = 1553157460000;
"original_purchase_date_pst" = "2019-03-21 01:37:40 America/Los_Angeles";
"original_transaction_id" = 1000000495291060;
"product_id" = "com.myApp.myApp.autoRenewableSubscription";
"purchase_date" = "2019-02-06 15:45:21 Etc/GMT";
"purchase_date_ms" = 1549467921000;
"purchase_date_pst" = "2019-02-06 07:45:21 America/Los_Angeles";
quantity = 1;
"transaction_id" = 1000000512208509;
"web_order_line_item_id" = 1000000042609485;
}

收据信息

struct IAPReceiptInfo: Decodable {
let expiresDate: String
private enum CodingKeys: String, CodingKey {
case expiresDate = "expires_date"
}
}
struct IAPReceipt: Decodable {
let latestReceipt: String
let status: Int
var receiptInfo = [IAPReceiptInfo]()
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: Codingkeys.self)
self.latestReceipt = try container.decode(String.self, forKey: .latestReceipt)
self.status = try container.decode(Int.self, forKey: .status)
self.receiptInfo = try container.decode([IAPReceiptInfo].self, forKey: .latestInfos)
}
var latestInfo: IAPReceiptInfo? {
return self.receiptInfo.last
}
var IAPLatestReceipt: String {
return self.latestReceipt
}
private enum Codingkeys: String, CodingKey {
case latestReceipt = "latest_receipt"
case status
case latestInfos = "latest_receipt_info"
}
}

IAPReceiptAPI

func sendReceiptForToServer(completion pCompletion: @escaping (([IAPReceiptInfo]?, Error?) -> Void)) {
let receiptData = self.getReceipt?.base64EncodedString()
let requestReceiptDict = ["receipt": receiptData]
if receiptData == nil {
let error = NSError(domain: "No Rec", code: 0, userInfo: nil)
pCompletion(nil, error)
}
do {
let data = try requestReceiptDict.vyEncode()
guard let validationUrl = URL(string: "https://us-central1-myApp-a8e27.cloudfunctions.net/receiptValidation") else { return }
let session = URLSession(configuration: .default)
var request = URLRequest(url: validationUrl, cachePolicy: .reloadIgnoringLocalCacheData)
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.httpMethod = "POST"
request.httpBody = data
let task = session.uploadTask(with:request, from: data) { (data, response, error) in
guard let data = data, error == nil else { return }
do {
let receipt = try IAPReceipt.vyDecode(data: data)
if let receiptLatestInfo = receipt.latestInfo {
pCompletion([receiptLatestInfo], nil)
}
} catch let error {
pCompletion(nil, error)
}
}
task.resume()
} catch let error {
pCompletion(nil, error)
}
}
}

刚刚发现expires_date已被更改,在某些情况下可能会丢失,不得不将其设为optional并立即工作。

struct IAPReceiptInfo: Decodable {
let expiresDate: String?
private enum CodingKeys: String, CodingKey {
case expiresDate = "expires_date"
}
}

最新更新