Сбой при разборе: JSONDecoder Swift - PullRequest
1 голос
/ 17 апреля 2020

Я пытаюсь декодировать json запрос с помощью Alamofire 5.2. Проблема в том, что я использую JSONDecoder, и у меня есть некоторые проблемы с преобразованием

API находится в Spani sh, а мои модели в Engli sh, поэтому я решил изменить этот тип значений, используя перечисление ключей

Но я не знаю, работает ли это ... Вот мой код:

API RESPONSE :( json переменная)

    {
  "sistemaOperativoId" : 0,
  "nombreUsuario" : "Coasnf_09",
  "menus" : [

  ],
  "acciones" : [

  ],
  "fechaRegistro" : "2020-04-15T09:46:24.0573154",
  "empresa" : null,
  "version" : null
}

МОЯ МОДЕЛЬ:

struct UserP: Decodable{
    var username : String
    var company : String

    private enum CodingKeys: String, CodingKey{
        case username = "nombreUsuario"
        case company = "empresa"
    }

    init(from decoder: Decoder) throws{
        let container = try decoder.container(keyedBy: CodingKeys.self)
        username = try container.decode(String.self, forKey: .username) ?? "null"
        company = try container.decode(String.self, forKey: .company)  ?? "null"
    }

    init(username: String, company: String){
        self.username = username
        self.company = company
    }
}

ПРЕОБРАЗОВАНИЕ:

   func login(user: User) -> UserP? {
        var userData: UserP! = nil
        AF.request(UserRouter.login(user: user)).responseJSON{ response in
            switch response.result {
            case .success(let response):
                print(response)
                let dict = (response as? [String : Any])!
                let json = dict["data"] as! [String: Any]

                if let jsonData = try? JSONSerialization.data(withJSONObject: json , options: .prettyPrinted)
                {
                    do {
                        var jsonString = String(data: jsonData, encoding: String.Encoding.utf8)!
                        print(jsonString)
                        userData = try JSONDecoder().decode(UserP.self, from: Data(jsonString.utf8))
                        print("Object Converted: ", userData.username)
                    } catch {
                        print("Parsing Failed: ", error.localizedDescription)
                    }
                }



                break

            case .failure(let error):
                print(error)
                break
            }
        }

        return userData
    }

1 Ответ

1 голос
/ 17 апреля 2020

Alamofire logi c связанные изменения:

response из Alamofire имеет свойство data, которое вы можете использовать напрямую:

let json = response.data
do {
    let user = try JSONDecoder().decode(UserP.self, from: json)
    print(user)
}
catch {
    print(error)
}

Далее, если ключи nombreUsuario и empresa не гарантированно входят в json, то рекомендуется пометить эти переменные как необязательные. При этом вам не нужно настраивать логик декодера c.

Изменение модели # 1:

struct UserP: Decodable {
    var username: String?
    var company: String?

    private enum CodingKeys: String, CodingKey{
        case username = "nombreUsuario"
        case company = "empresa"
    }
}

Изменение модели # 2:

Если если вы хотите задать некоторые значения по умолчанию, тогда может помочь пользовательский декодер:

struct UserP: Decodable {
    var username: String
    var company: String

    private enum CodingKeys: String, CodingKey{
        case username = "nombreUsuario"
        case company = "empresa"
    }

    init(from decoder: Decoder) throws{
        let container = try decoder.container(keyedBy: CodingKeys.self)
        username = try container.decodeIfPresent(String.self, forKey: .username) ?? "Default Name"
        company = try container.decodeIfPresent(String.self, forKey: .company) ?? "Default Company Name"
    }
}
...