美文网首页
Swift 使用 Codable 解析 JSON

Swift 使用 Codable 解析 JSON

作者: MonkeyBread | 来源:发表于2019-03-20 11:08 被阅读0次

    示例1:

    • JSON
    let jsonData: Data = """
    { 
      "name": "MonkeyBread",
      "address": "China",
      "email": "12345@gamil.com",
    } 
    """.data(using: .utf8)!
    
    • Model
    struct User: Codable {
        let name: String
        let address: String
        let email: String
    }
    
    • 解析
    let user = try? JSONDecoder().decode(User.self, from: jsonData)
    

    JSON 与 Model 完全一致,这是最基础的 JSON 解析。

    示例2:

    • JSON
    let jsonData: Data = """
    {
      "name": "MonkeyBread",
      "email": "12345@gamil.com",
      "addr": {
        "country": "China",
        "city": "Beijing",
        "lat": "123",
        "lng": "456",
        }
    }
    """.data(using: .utf8)!
    
    • Model
    struct Address: Codable {
        let country: String
        let city: String
        let latitude: String
        let longitude: String
    }
    
    struct User: Codable {
        let userName: String
        let email: String
        let address: Address
    }
    
    • 解析
    struct Address: Codable {
        let country: String
        let city: String
        let latitude: String
        let longitude: String
    
        private enum CodingKeys: String, CodingKey {
            case country
            case city
            case latitude = "lat"
            case longitude = "lng"
        }
    }
    
    struct User: Codable {
        let userName: String
        let email: String
        let address: Address
    
        private enum CodingKeys: String, CodingKey {
            case userName = "name"
            case email
            case address = "addr"
        }
    }
    
    let user = try? JSONDecoder().decode(User.self, from: jsonData)
    

    JSON 与 Model 不一致的情况,可通过 CodingKeys 枚举对应,多层嵌套的情况也同样适用。
    需要注意的是:如果重写 CodingKeys enum 需要包含 Model 中所有属性

    示例3:

    • JSON
    let jsonData: Data = """
    {
    "name": "MonkeyBread",
    "email": "12345@gamil.com",
    "addr": {
        "country": "China",
        "city": "Beijing",
        "lat": "123",
        "lng": "456"
        }
    }
    """.data(using: .utf8)!
    
    • Model
    struct User: Codable {
        let userName: String
        let email: String
    
        let country: String
        let city: String
        let latitude: String
        let longitude: String
    }
    
    • 解析:
    struct User: Codable {
        var userName: String = ""
        var email: String = ""
    
        var country: String = ""
        var city: String = ""
        var latitude: String = ""
        var longitude: String = ""
    
        private enum UserKeys: String, CodingKey {
            case userName = "name"
            case email
            case addr
        }
    
        private enum AddressKeys: String, CodingKey {
            case country
            case city
            case latitude = "lat"
            case longitude = "lng"
        }
    
        init(from decoder: Decoder) throws {
    
            if let userContainer = try? decoder.container(keyedBy: UserKeys.self) {
                self.userName = try userContainer.decode(String.self, forKey: .userName)
                self.email = try userContainer.decode(String.self, forKey: .email)
    
                if let addressContainer = try? userContainer.nestedContainer(keyedBy: AddressKeys.self, forKey: .addr) {
                    self.country = try addressContainer.decode(String.self, forKey: .country)
                    self.city = try addressContainer.decode(String.self, forKey: .city)
                    self.latitude = try addressContainer.decode(String.self, forKey: .latitude)
                    self.longitude = try addressContainer.decode(String.self, forKey: .longitude)
                }
            }
        }
    }
    
    if let user = try? JSONDecoder().decode(User.self, from: jsonData) {
        print(user.userName)
        print(user.email)
        print(user.country)
        print(user.latitude)
        print(user)
    }
    
    

    示例中的 addr 参数包含了地理位置信息,一般情况都会按照 示例2 的方式解析,但如果项目中仅用到了 country 参数,创建 Address 类来接收参数就显得很累赘了,此示例就是将 addr 参数与 User 参数合并成了一层,省去了 Address 类。

    相关文章

      网友评论

          本文标题:Swift 使用 Codable 解析 JSON

          本文链接:https://www.haomeiwen.com/subject/hdyamqtx.html