【问题标题】:How to handle Empty array in codable decode process如何在可编码解码过程中处理空数组
【发布时间】:2018-05-24 06:29:09
【问题描述】:

当“地址”数组不为空时效果很好。但是当“地址”数组为空时它会失败。任何帮助将不胜感激。我有地址对象的结构。基本上“地址”是“地址”类型的对象数组,但是当地址为空时它会失败。

{
    "success": "1",
    "message": "You have succesfully verified your mobile no",
    "details": {
        "customer_id": 825,
        "is_delivery_available": "0",
        "is_registration_complete": "0",
        "is_customer_verified": "0",
        "customer_status": "0",
        "cart_count": "0",
        "name_type": "mr",
        "firstname": "",
        "lastname": "",
        "full_name": "",
        "pincode": "",
        "profile_pic": "",
        "mobile": "8583846677",
        "email": "",
        "address": [

        ],
        "referral_code": ""
    }
}

以上是我尝试在 Swift4 中使用 Codable 解码的 JSON。

import Foundation

struct Signup: Codable {
    var success:String?
    var message:String?
    var details:Details?

    private enum CodingKeys: String, CodingKey { case success, message, details }

    init(from decoder: Decoder) throws {
        let values = try decoder.container(keyedBy: CodingKeys.self)
        success = try values.decode(String.self, forKey: .success)
        message = try values.decode(String.self, forKey: .message)
        if let _details = try? values.decode(Details.self, forKey: .details) {
            details = _details
        }
    }
}

struct Details: Codable {
    var address:[Address]?
    var cart_count:String?
    var customer_id:String?
    var customer_status:String?
    var email:String?
    var firstname:String?
    var full_name:String?
    var is_customer_verified:String?
    var is_delivery_available:String?
    var is_registration_complete:String?
    var lastname:String?
    var mobile:String?
    var name_type:String?
    var pincode:String?
    var profile_pic:String?
    var referral_code:String?

    private enum CodingKeys: String, CodingKey { case address, cart_count, customer_id, customer_status, email, firstname, full_name, is_customer_verified, is_delivery_available, is_registration_complete, lastname, mobile, name_type, pincode, profile_pic, referral_code }

    init(from decoder: Decoder) throws {
        let values = try decoder.container(keyedBy: CodingKeys.self)

        ****-->>> Issue is in this line. How to handle empty array while decoding. <<<--****
        address = try? values.decode([Address].self, forKey: .address) 

        cart_count = try values.decode(String.self, forKey: .cart_count)
        customer_id = try values.decode(String.self, forKey: .customer_id)
        customer_status = try values.decode(String.self, forKey: .customer_status)
        email = try values.decode(String.self, forKey: .email)
        firstname = try values.decode(String.self, forKey: .firstname)
        full_name = try values.decode(String.self, forKey: .full_name)
        is_customer_verified = try values.decode(String.self, forKey: .is_customer_verified)
        is_delivery_available = try values.decode(String.self, forKey: .is_delivery_available)
        is_registration_complete = try values.decode(String.self, forKey: .is_registration_complete)
        lastname = try values.decode(String.self, forKey: .lastname)
        mobile = try values.decode(String.self, forKey: .mobile)
        name_type = try values.decode(String.self, forKey: .name_type)
        pincode = try values.decode(String.self, forKey: .pincode)
        profile_pic = try values.decode(String.self, forKey: .profile_pic)
        referral_code = try values.decode(String.self, forKey: .referral_code)
    }
}

struct Address: Codable {
    var address_default:String?
    var address_id:String?
    var address_type:String?
    var city:String?
    var customer_id:String?
    var flat_or_house_or_office_no:String?
    var full_address:String?
    var full_name:String?
    var landmark:String?
    var lat:String?
    var lng:String?
    var mobile:String?
    var name_type:String?
    var pincode:String?
    var street_or_society_or_office_name:String?
}

我陷入了困境。如何在 Swift4 Codable 中解码 json 数据时处理空数组。

【问题讨论】:

  • decodeIfPresent(_:forKey:) 解码方法
  • CommonResponse:Signup(success: Optional("1"), message: Optional("You have succesfully verify your mobile no"), details: nil) - 无效。

标签: json swift codable


【解决方案1】:

我遇到了这个问题,我做了如下来解决这个问题。

if let _address = try? values.decode([Address].self, forKey: .address) {
    address = _address
} else {
    address = []
}

你可以试一试。

【讨论】:

  • 小幅改进:让_address = 试试? values.decode([Address].self, forKey: .address) ?? []
  • @andrew54069 很好,但是如果我在解析本身而不是空数组中出现问题怎么办?出于调试目的,我将无法捕获它。有什么建议吗?
  • 那你可以自己试试看。
【解决方案2】:

真正的问题是Details 中的customer_idInt 而不是String。解码一个空数组应该可以工作。

您的代码太复杂了。享受Codable 的魔力,省略所有 CodingKeys 和初始化程序,并将所有结构成员声明为非可选和常量

struct Signup: Decodable {
    let success : String
    let message : String
    let details : Details
}

struct Details : Decodable {
    let address : [Address]
    let cart_count : String
    let customer_id : Int
    let customer_status, email, firstname, full_name : String
    let is_customer_verified, is_delivery_available, is_registration_complete : String
    let lastname, mobile, name_type, pincode, profile_pic, referral_code : String
}

struct Address: Decodable {
    let address_default, address_id, address_type, city, customer_id : String
    let flat_or_house_or_office_no, full_address, full_name : String
    let landmark, lat, lng, mobile, name_type, pincode, street_or_society_or_office_name : String
}

你甚至可以命名成员camelCased

let cartCount : String
let customerId : Int
...
let isRegistrationComplete : String

并通过convertFromSnakeCase密钥解码策略

decoder.keyDecodingStrategy = .convertFromSnakeCase

仍然没有额外的代码!

【讨论】:

  • 如果您不确定数据是否存在,您真的可以摆脱可选项吗?我的代码无法解析空数组,如“foo”:[]。我应该如何编码?快速类型建议了很多疯狂的类和方法。数组的内容如果不为空,则始终为字符串,但是,[String] 会抛出错误 typeMismatch(Swift.Array, Swift.DecodingError.Context(codingPath: [], debugDescription: "Expected to decode Array 但是而是找到了字典。”,基础错误:无))
  • @user6631314 错误信息与根对象有关,与特定键无关。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-05-31
  • 1970-01-01
  • 1970-01-01
  • 2013-08-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多