如何从 json 对象初始化结构 [英] How to initialize a struct from a json object

查看:23
本文介绍了如何从 json 对象初始化结构的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是 swift 任何想法的新手.如何从 json 对象初始化结构体.我不知道我该怎么做.

HI i am new to swift any idea . How to initialize a struct from a json object . i could not figure out how can i do it .

{用户":{"name": "cruskuaka","email": "cristlika@gmail.com",电话号码":018833455"},地址": {"房子": "100","街道": "B",镇":{"town_id": "1","town_name": "戈尔韦市中心"},城市":{"city_id": "10","city_name": "戈尔韦"},"address_id":"200","full_address":"100, B, Galway city center,Galway"},"delivery_instruction": "没有电话","delivery_method": "1"}

{ "user": { "name": "cruskuaka", "email": "cristlika@gmail.com", "phoneNo":"018833455" }, "address": { "house": "100", "street": "B", "town": { "town_id": "1", "town_name": "Galway city center" }, "city": { "city_id": "10", "city_name": "Galway" }, "address_id":"200", "full_address":"100, B, Galway city center,Galway" }, "delivery_instruction": "no call", "delivery_method": "1" }

这里是所有结构:

struct Contact  {
    let user : User
    let address : Address
    let deliveryInstruction : String
    let deliveryMethod : String
    init(dictionary: [String: Any]) {
        self.deliveryInstruction = dictionary["delivery_instruction"] as? String ?? ""
        self.deliveryMethod = dictionary["delivery_method"] as? String ?? ""
        self.address = Address(dictionary: dictionary["address"] as? [String:Any] ?? [:])
        self.user =  User(dictionary: dictionary["address"] as? [String:Any] ?? [:])
    }
  }

<小时>

struct User {
    let name : String
    let email : String
    let phoneNo : String
    init(dictionary : [String:Any] ) {
        self.name = dictionary["name"] as? String ?? ""
        self.email = dictionary["email"] as? String ?? ""
        self.phoneNo = dictionary["phoneNo"] as? String ?? ""
    }
}

<小时>

struct Address  {
    let city : City
    let town : Town
    let addressId : String
    let fullAddress : String
    let house : String
    let street: String
    init(dictionary : [String:Any] ) {
        self.addressId = dictionary["address_id"] as? String ?? ""
        self.fullAddress = dictionary["full_address"] as? String ?? ""
        self.house = dictionary["house"] as? String ?? ""
        self.street = dictionary["street"] as? String ?? ""
        self.city = City(dictionary: dictionary["address"] as? [String:Any] ?? [:])
        self.town = Town(dictionary: dictionary["address"] as? [String:Any] ?? [:])  
    }
}

<小时>

struct City {
    let cityId : String
    let cityName : String
    init(dictionary : [String:Any] ) {
        self.cityId = dictionary["city_id"] as? String ?? ""
        self.cityName = dictionary["city_name"] as? String ?? ""
    }
}

<小时>

struct Town {
    let townId : String
    let townName : String
    init(dictionary : [String:Any]) {
        self.townId = dictionary["town_id"] as? String ?? ""
        self.townName = dictionary["town_name"] as? String ?? ""
    }
} 

推荐答案

编辑/更新:Swift 4 或更高版本您可以使用 Codable 协议:

edit/update: Swift 4 or later you can use Codable Protocol:

struct Root: Codable {
    let user: User
    let address: Address
    let deliveryInstruction, deliveryMethod: String
}


struct Address: Codable {
    let house, street, addressId, fullAddress: String
    let town: Town
    let city: City
}


struct City: Codable {
    let cityId, cityName: String
}


struct Town: Codable {
    let townId, townName: String
}


struct User: Codable {
    let name, email, phoneNo: String
}


extension Decodable {
    init(data: Data, using decoder: JSONDecoder = .init()) throws {
        self = try decoder.decode(Self.self, from: data)
    }
    init(json: String, using decoder: JSONDecoder = .init()) throws {
        try self.init(data: Data(json.utf8), using: decoder)
    }
}

不要忘记将 JSONDecoder 属性 keyDecodingStrategy 设置为 .convertFromSnakeCase:

Just don't forget to set the JSONDecoder property keyDecodingStrategy to .convertFromSnakeCase:

let json = """
{"user": {"name": "crst","email": "crat@gmail.com","phoneNo":"018833455"},"address": {"house": "100","street": "B","town":{"town_id": "1","town_name": "Galway city center"},"city":{"city_id": "10","city_name": "Galway"},"address_id":"200", "full_address":"100, B, Galway city center,Galway" },"delivery_instruction": "no call","delivery_method": "1" }
"""

do {
    let decoder = JSONDecoder()
    decoder.keyDecodingStrategy = .convertFromSnakeCase
    let root = try decoder.decode(Root.self, from: Data(json.utf8))
    print(root)
} catch {
    print(error)
}

或者简单地说:

do {
    let decoder = JSONDecoder()
    decoder.keyDecodingStrategy = .convertFromSnakeCase
    let root = try Root(json: json, using: decoder)  // or  Root(data: data, using: decoder) 
    print(root)
} catch {
    print(error)
}

这将打印

Root(user: __lldb_expr_112.User(name: "cruskuaka", email:cristlika@gmail.com",电话号码:018833455"),地址:__lldb_expr_112.Address(house: "100", street: "B", addressId: "200", fullAddress: "100, B, Galway city center,Galway", town:__lldb_expr_112.Town(townId: "1", townName: "Galway city center"), city: __lldb_expr_112.City(cityId: "10", cityName: "Galway")),DeliveryInstruction: "no call", deliveryMethod: "1")

Root(user: __lldb_expr_112.User(name: "cruskuaka", email: "cristlika@gmail.com", phoneNo: "018833455"), address: __lldb_expr_112.Address(house: "100", street: "B", addressId: "200", fullAddress: "100, B, Galway city center,Galway", town: __lldb_expr_112.Town(townId: "1", townName: "Galway city center"), city: __lldb_expr_112.City(cityId: "10", cityName: "Galway")), deliveryInstruction: "no call", deliveryMethod: "1")



原始答案(在 Codable 协议之前)



Original Answer (before Codable protocol)

斯威夫特 3

您的代码中存在多个错误,但您走在正确的道路上.您在初始化用户、城市和城镇结构时使用了错误的密钥.我还创建了另外两个初始值设定项,因此您可以使用字典、json 字符串或其数据来初始化您的结构:

You have more than one error in your code, but you are in the right path. You are using the wrong key when initializing your user, city and town structs. I have also created two more initializers so you can initialize your struct with a dictionary, the json string or just its data:

struct Contact: CustomStringConvertible  {
    let user: User
    let address: Address
    let deliveryInstruction: String
    let deliveryMethod: String
    // customize the description to your needs
    var description: String { return "(user.name) (deliveryInstruction) (deliveryMethod)" }
    init(dictionary: [String: Any]) {
        self.deliveryInstruction = dictionary["delivery_instruction"] as? String ?? ""
        self.deliveryMethod = dictionary["delivery_method"] as? String ?? ""
        self.address = Address(dictionary: dictionary["address"] as? [String: Any] ?? [:])
        self.user =  User(dictionary: dictionary["user"] as? [String: Any] ?? [:])
    }
    init?(data: Data) {
        guard let json = (try? JSONSerialization.jsonObject(with: data)) as? [String: Any] else { return nil }
        self.init(dictionary: json)
    }
    init?(json: String) {
        self.init(data: Data(json.utf8))
    }

}


struct User: CustomStringConvertible {
    let name: String
    let email: String
    let phone: String
    let description: String
    init(dictionary: [String: Any]) {
        self.name = dictionary["name"] as? String ?? ""
        self.email = dictionary["email"] as? String ?? ""
        self.phone = dictionary["phoneNo"] as? String ?? ""
        self.description = "name: (name) - email: (email) - phone: (phone)"
    }
}


struct Address: CustomStringConvertible  {
    let id: String
    let street: String
    let house: String
    let city: City
    let town: Town
    let description: String
    init(dictionary: [String: Any] ) {
        self.id = dictionary["address_id"] as? String ?? ""
        self.description = dictionary["full_address"] as? String ?? ""
        self.house = dictionary["house"] as? String ?? ""
        self.street = dictionary["street"] as? String ?? ""
        self.city = City(dictionary: dictionary["city"] as? [String: Any] ?? [:])
        self.town = Town(dictionary: dictionary["town"] as? [String: Any] ?? [:])
    }
}


struct City: CustomStringConvertible {
    let id: String
    let name: String
    // customize the description to your needs
    var description: String { return name }
    init(dictionary: [String: Any] ) {
        self.id = dictionary["city_id"] as? String ?? ""
        self.name = dictionary["city_name"] as? String ?? ""
    }
    
}


struct Town: CustomStringConvertible {
    let id: String
    let name: String
    // customize the description to your needs
    var description: String { return name }
    init(dictionary: [String: Any]) {
        self.id = dictionary["town_id"] as? String ?? ""
        self.name = dictionary["town_name"] as? String ?? ""
    }
}

从 JSON 测试初始化​​:

Testing the initialization from JSON:

let contact = Contact(json: json)   // crst no call 1

contact               // crst no call 1
contact?.user         // name: crst - email: crat@gmail.com - phone: 018833455
contact?.user.name    //  "crst"
contact?.user.email   //  "crat@gmail.com"
contact?.user.phone   //  "018833455"
contact?.address      //  100, B, Galway city center,Galway
contact?.address.id           //  200
contact?.address.street       //  B
contact?.address.town         // Galway city center
contact?.address.city         //  Galway
contact?.deliveryInstruction  // "no call"
contact?.deliveryMethod       //    1

这篇关于如何从 json 对象初始化结构的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆