Как я могу обработать объект JSON, в то время как некоторые значения не равны нулю (отсутствуют или не существуют) для Swift - PullRequest
0 голосов
/ 12 июня 2019

Привет всем, у меня есть объект 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 ]

2 голосов
/ 12 июня 2019

Просто объявите члены структуры как необязательные, которые могут быть 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?
}
0 голосов
/ 12 июня 2019

Используйте дополнительные значения для значений, которые вы не всегда будете получать, а в вашем 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)
}
0 голосов
/ 12 июня 2019

В вашем случае вы должны использовать контейнер и, задавая начальные значения для вашей модели, вы определяете их как константы, они должны быть переменными.Чтобы использовать вашу модель с контейнером:

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) ?? ""
    }

}

Я надеюсь, что это решит вашу проблему

0 голосов
/ 12 июня 2019

Используйте опциональный оператор

Ваша структура должна быть такой:

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

    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...