当一些值甚至不为零(丢失或不存在)时,如何处理JSON对象?

时间:2019-06-12 08:45:06

标签: json swift

大家好,我有一个不规则响应问题的json对象,有时它不发送模型中的某些键和值,例如:

struct GetComments: Codable {
   let name, surname: String
   let photoPath: String
   let commentid, comment, date: String
   let commentOwner: String
   let id : String
   let email: String
}

我尝试为模型提供一些初始值,如下所示,但仍然崩溃:

struct GetComments: Codable {
   let name, surname: String = “”
   let photoPath: String = “”
   let commentid, comment, date: String = “”
   let commentOwner: String = “”
   let id : String = “”
   let email: String = “”
}

充满了我的json对象,例如:

{
   “name”:"Calvin",
   “surname”:“Harris”,
   “photoPath”: "https://image.flaticon.com/icons/png/128/181/181549.png",
   “commentid”: “ASHF579OTUJKDH475870987NBMVK”,
   “comment”: “hello everyone”,
   “date”: “11/06/2019",
   “commentOwner”: “Calvin Harris”,
   “id”: “LHKHOYIYU9OTUJKDH475870987NBMVK”,
   “email”: “calvin@test.com”
}

当我收到如下消息时问题就开始了:

{
       “name”:“Calvin”,
       “surname”:“Harris”,
       “commentid”: “ASHF579OTUJKDH475870987NBMVK”,
       “comment”: “hello everyone”,
       “date”: “11/06/2019",
       “commentOwner”: “Calvin Harris”,
       “id”: “LHKHOYIYU9OTUJKDH475870987NBMVK”,
    }

4 个答案:

答案 0 :(得分:2)

只需将struct成员声明为可选成员即可,它们可以为nil

struct GetComments: Codable {
   let name, surname: String
   let photoPath: String? // can also be decoded as URL?
   let commentid, comment, date: String
   let commentOwner: String
   let id : String
   let email: String?
}

答案 1 :(得分:0)

使用可选的运算符

您的结构应类似于:

struct GetComments: Codable {
   var name: String?
   var surname: String?
   var photoPath: String?
   var commentid: String?
   var comment: String?
   var date: String?
   var commentOwner: String?
   var id : String?
   var email: String?

   // method actually defines the key
   enum CodingKeys: String, CodingKey {
       case name // = " your actual key name"
       case surname
       case last_name
   }

   // methods actually parsing the data
   required public init(from decoder: Decoder) throws {
       let values = try decoder.container(keyedBy: CodingKeys.self)

       name  = try values.decodeIfPresent(Int.self, forKey: .name)
       surname = try values.decodeIfPresent(String.self, forKey: .surname)

     // rest of the parsing data

    }
}

答案 2 :(得分:0)

使用可选值表示您不会总是收到的值,并且在您的required init(from decoder: Decoder)中使用decodeIfPresent作为可选值

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

        photoPath = try container.decodeIfPresent(String.self, forKey: .photoPath)
}

答案 3 :(得分:-2)

在这种情况下,您应该使用容器,并在为模型提供初始值时将其定义为常量,它们应该是可变的。要将模型与容器一起使用:

struct GetComments: Codable {
    let name, surname: String?
    let photoPath: String?
    let commentid, comment, date: String?
    let commentOwner: String?
    let id : String?
    let email: String?

    init (from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        self.name = try container.decodeIfPresent(String.self, forKey: .name) ?? ""
        self.surname = try container.decodeIfPresent(String.self, forKey: .surname) ?? ""
        self.photoPath = try container.decodeIfPresent(String.self, forKey: .photoPath) ??  "maybe a place holder url or empty string"
        self.commentid = try container.decodeIfPresent(String.self, forKey: .commentid) ?? ""
        self.comment = try container.decodeIfPresent(String.self, forKey: .comment) ?? ""
        self.date = try container.decodeIfPresent(String.self, forKey: .date) ?? ""
        self.commentOwner = try container.decodeIfPresent(String.self, forKey: .commentOwner) ?? ""
        self.email = try container.decodeIfPresent(String.self, forKey: .email) ?? ""
        self.id = try container.decodeIfPresent(String.self, forKey: .id) ?? ""
    }

}

我希望这能解决您的问题