为什么我的json响应对象返回nil?

问题描述 投票:1回答:2

我有一些json:

   {
   "wallets":[
      {
         "fundingProviderName":"tns_cof",
         "authLimit":75,
         "pinRequired":true,
         "wallets":[
            {
               "authLimit":75,
               "isCardSupported":true,
               "paymentProcessorId":6,
               "mainDisplayText":"...0013",
               "imageUrl":"https://az755244.vo.msecnd.net/paymentimages/visa2.png",
               "userPaymentSourceId":9756,
               "secondaryDisplayText":"12/30",
               "expDate":"2030-12-31T23:59:59Z",
               "cardIssuer":"Visa"
            },
            {
               "authLimit":75,
               "isCardSupported":true,
               "paymentProcessorId":7,
               "mainDisplayText":"...1020",
               "imageUrl":"https://az755244.vo.msecnd.net/paymentimages/mastercard2.png",
               "userPaymentSourceId":9757,
               "secondaryDisplayText":"12/25",
               "expDate":"2025-12-31T23:59:59Z",
               "cardIssuer":"Mastercard"
            },
            {
               "authLimit":75,
               "isCardSupported":true,
               "paymentProcessorId":8,
               "mainDisplayText":"...3025",
               "imageUrl":"https://az755244.vo.msecnd.net/paymentimages/amex.png",
               "userPaymentSourceId":9758,
               "secondaryDisplayText":"12/27",
               "expDate":"2027-12-31T23:59:59Z",
               "cardIssuer":"Amex"
            }
         ],
         "isSupported":true
      }
   ]
}

我的结构看起来像这样:

struct CreditCard: Codable {
    var authLimit: Int?
    var isCardSupported: Bool?
    var paymentProcessorId: Int?
    var mainDisplayText: String?
    var imageUrl: String?
    var userPaymentSourceId: Int?
    var secondaryDisplayText: String?
    var expDate: String?
    var cardIssuer: String?

    enum CodingKeys: String, CodingKey {
        case cardIssuer = "cardIssuer"
        case authLimit = "authLimit"
        case isCardSupported = "isCardSupported"
        case paymentProcessorId = "paymentProcessorId"
        case mainDisplayText = "mainDisplayText"
        case imageUrl = "imageUrl"
        case userPaymentSourceId = "userPaymentSourceId"
        case secondaryDisplayText = "secondaryDisplayText"
        case expDate = "expDate"
    }

    init(from decoder: Decoder) throws {
        let values = try decoder.container(keyedBy: CodingKeys.self)
        authLimit = try values.decodeIfPresent(Int.self, forKey: .authLimit)
        isCardSupported = try values.decodeIfPresent(Bool.self, forKey: .isCardSupported)
        paymentProcessorId = try values.decodeIfPresent(Int.self, forKey: .paymentProcessorId)
        mainDisplayText = try values.decodeIfPresent(String.self, forKey: .mainDisplayText)
        imageUrl = try values.decodeIfPresent(String.self, forKey: .imageUrl)
        userPaymentSourceId = try values.decodeIfPresent(Int.self, forKey: .userPaymentSourceId)
        secondaryDisplayText = try values.decodeIfPresent(String.self, forKey: .secondaryDisplayText)
        expDate = try values.decodeIfPresent(String.self, forKey: .expDate)
        cardIssuer = try values.decodeIfPresent(String.self, forKey: .cardIssuer)
    }
}

我的json解码器代码如下:

do {
if let jsonData = response?.responseData {
let jsonDecoder = JSONDecoder()
let creditCards = try jsonDecoder.decode(CreditCard.self, from: jsonData)
print("credit cards \(creditCards)")
completion(nil, creditCards)
}
} catch {
print(error)
}

我敢肯定,对于该模型为何仍然为零的情况,可能存在明显的疏忽。任何帮助将非常感激。谢谢!

ios json swift xcode codable
2个回答
1
投票
struct Wallet: Decodable {
 let wallets: [WalletDetails]
}
struct WalletDetails: Decodable {
 let fundingProviderName: String
 let authLimit: Int
 let pinRequired: Bool
 let wallets: [CreditCard]
}
struct CreditCard: Codable {
var authLimit: Int?
var isCardSupported: Bool?
var paymentProcessorId: Int?
var mainDisplayText: String?
var imageUrl: String?
var userPaymentSourceId: Int?
var secondaryDisplayText: String?
var expDate: String?
var cardIssuer: String?

enum CodingKeys: String, CodingKey {
    case cardIssuer = "cardIssuer"
    case authLimit = "authLimit"
    case isCardSupported = "isCardSupported"
    case paymentProcessorId = "paymentProcessorId"
    case mainDisplayText = "mainDisplayText"
    case imageUrl = "imageUrl"
    case userPaymentSourceId = "userPaymentSourceId"
    case secondaryDisplayText = "secondaryDisplayText"
    case expDate = "expDate"
}

init(from decoder: Decoder) throws {
    let values = try decoder.container(keyedBy: CodingKeys.self)
    authLimit = try values.decodeIfPresent(Int.self, forKey: .authLimit)
    isCardSupported = try values.decodeIfPresent(Bool.self, forKey: .isCardSupported)
    paymentProcessorId = try values.decodeIfPresent(Int.self, forKey: .paymentProcessorId)
    mainDisplayText = try values.decodeIfPresent(String.self, forKey: .mainDisplayText)
    imageUrl = try values.decodeIfPresent(String.self, forKey: .imageUrl)
    userPaymentSourceId = try values.decodeIfPresent(Int.self, forKey: .userPaymentSourceId)
    secondaryDisplayText = try values.decodeIfPresent(String.self, forKey: .secondaryDisplayText)
    expDate = try values.decodeIfPresent(String.self, forKey: .expDate)
    cardIssuer = try values.decodeIfPresent(String.self, forKey: .cardIssuer)
}
}

您尚未添加顶级键,这就是为什么它不起作用的原因。试试这个:

 do {
    if let jsonData = response?.responseData {
    let jsonDecoder = JSONDecoder()
    let creditCards = try jsonDecoder.decode(Wallet.self, from: jsonData)
    print("credit cards \(creditCards)")
    completion(nil, creditCards)
    }
    } catch {
    print(error)
    }

0
投票

要么从JSON的顶部解码(如@Rob回答),要么遍历JSON并获取wallets密钥,然后对其进行解码。

if let jsonData = response?.responseData as? Dictionary<String,Any> {
    if let walletData = jsonData["wallet"] as? [Dictionary<String,Any>] {
        if let mainWalletData = walletData[0]["wallets"] as? [Dictionary<String,Any>] {
            do {
                let jsonDecoder = JSONDecoder()
                let creditCards = try jsonDecoder.decode([CreditCard].self, from: mainWalletData)
                print("credit cards \(creditCards)")
                completion(nil, creditCards)
            }
        } catch {
            print(error)
        }
    }
}
}
© www.soinside.com 2019 - 2024. All rights reserved.