Ios 解码JSON响应

Ios 解码JSON响应,ios,json,swift,xcode,Ios,Json,Swift,Xcode,我试图从JSON响应中获取一些价格数据,并将其保存在用户默认值中 价格类别为: import Foundation struct Prices : Decodable{ let id, id_service: Int let nationality: String let price: Int let createdAt: String? let updatedAt: String? } class Price : NSObject, NSCoding { var id, id_serv

我试图从JSON响应中获取一些价格数据,并将其保存在用户默认值中

价格类别为:

  import Foundation

struct Prices : Decodable{
let id, id_service: Int
let nationality: String
let price: Int
let createdAt: String?
let updatedAt: String?
}

class Price : NSObject, NSCoding {
var id, id_service: Int
var nationality: String
var price: Int
var createdAt: String?
var updatedAt: String?


init(id: Int, id_service: Int, nationality: String, price: Int) {
    self.id = id
    self.id_service = id_service
    self.nationality = nationality
    self.price = price

}

required convenience init(coder aDecoder: NSCoder) {
    let id = aDecoder.decodeInteger(forKey: "id")
    let id_service = aDecoder.decodeInteger(forKey: "id_service")
    let nationality = aDecoder.decodeObject(forKey: "nationality") as! String
    let price = aDecoder.decodeInteger(forKey: "price")
    self.init(id: id, id_service: id_service, nationality: nationality, price: price)
}

func encode(with aCoder: NSCoder) {
    aCoder.encode(id, forKey: "id")
    aCoder.encode(id_service, forKey: "id_service")
    aCoder.encode(nationality, forKey: "nationality")
    aCoder.encode(price, forKey: "price")
}

}
我调用的方法是:

   func GetPrices() {

let todoEndpoint: String = "my link"
guard let url = URL(string: todoEndpoint) else {
    print("Error: cannot create URL")
    return
}
let urlRequest = URLRequest(url: url)

let config = URLSessionConfiguration.default
let session = URLSession(configuration: config)

let task = session.dataTask(with: urlRequest) {
    (data, response, error) in
    guard error == nil else {
        print("error calling GET on /public/api/services")
        print(error!)
        return
    }
    guard let responseData = data else {
        print("Error: did not receive data")
        return
    }
    do {

        let decoder = JSONDecoder()
        decoder.keyDecodingStrategy = .convertFromSnakeCase
        let prices1 = try decoder.decode([Prices].self, from: responseData)
        print("1")
        var prices = [Price]()
        for price in prices1{
            let newprice = Price(id: price.id, id_service: price.id_service,nationality: price.nationality, price: price.price)
            print("2")
            prices.append(newprice)
             print(newprice.nationality)
        }


        var userDefaults = UserDefaults.standard
        let encodedData: Data = NSKeyedArchiver.archivedData(withRootObject: prices)
        userDefaults.set(encodedData, forKey: "prices")
        userDefaults.synchronize()

        let decoded  = userDefaults.object(forKey: "prices") as! Data
        let decodedPrice = NSKeyedUnarchiver.unarchiveObject(with: decoded) as! [Price]

        for price in decodedPrice {
            print(price.nationality)
        }


    } catch  {
        print("error trying to convert data to JSON")
        return
    }
}
task.resume()
}
我的JSON是这样的(它现在只有一个..但它是一个数组):

问题是我总是收到这样的消息:尝试将数据转换为JSON时出错


为什么??我做错了什么?如何解决此问题?

您正在使用.convertFromSnakeCase进行解码,因此您的属性应采用驼峰大小写

decoder.keyDecodingStrategy = .convertFromSnakeCase
参考文献

因此,要进行修复,请将您的属性名称id\u服务更改为idService,如下所示

struct Prices : Decodable{
    let id, idService: Int
    let nationality: String
    let price: Int
    let createdAt: String?
    let updatedAt: String?
}

为了更好地理解,您可以在catch块
print(error.localizedDescription)
中查看.useDefaultKeys也

,无需循环查看价格1并创建新数组,它已经是一个array@Scriptable出现此错误:无法读取数据,因为它已丢失。是否已丢失?尝试打印数据或数据。计数
convertFromSnakeCase
选项将
id\u服务
解码为
idService
,为什么要使用包含相同数据的类和结构?在
UserDefaults
中将JSON另存为
Data
,并在阅读时将其解码到结构中。非常感谢!
struct Prices : Decodable{
    let id, idService: Int
    let nationality: String
    let price: Int
    let createdAt: String?
    let updatedAt: String?
}