Проблемы с Codable Arrays и Alamofire - PullRequest
0 голосов
/ 13 января 2020

Я пытаюсь отправить следующий запрос через Alamofire и получаю следующую ошибку:

2020-01-13 09: 41: 05.912103-0600 AFNetworkingDemo [29720: 604258] ** * Завершение приложения из-за необработанного исключения «NSInvalidArgumentException», причина: «Неверный тип в JSON write (__SwiftValue) '

Я предполагаю, что именно так я определяю массивы в объекте (Я следил за некоторыми материалами, найденными здесь: https://benscheirman.com/2017/06/swift-json)

struct ProgramRequest: Codable {
    var userID: Int
    var programData: ProgramData

    var json: Constants.Json {
        return [
            "userID": userID,
            "programData": programData.json,
        ]
    }
}

struct ProgramData: Codable {
    var airhotel: [AirHotel]
    var security: [Security]

    var json: Constants.Json {
        return [
            "airhotel": airhotel,
            "security": security
        ]
    }
}

struct AirHotel: Codable {
    var id: Int
    var loyaltyNumber: String

    var json: Constants.Json {
        return [
            "id": id,
            "loyaltyNumber": loyaltyNumber
        ]
    }
}

struct Security: Codable {
    var vendorCode: String
    var loyaltyNumber: String

    var json: [String: Any] {
        return [
            "vendorCode": vendorCode,
            "loyaltyNumber": loyaltyNumber
        ]
    }
}

Словарь json на каждом уровне предназначен для визуализации объектов соответствующим образом для Alamofire. Для данного примера, если я распечатаю его, используя:

let jsonEncoder = JSONEncoder()
jsonEncoder.outputFormatting = .prettyPrinted

let jsonData = try jsonEncoder.encode(programRequest)

if let jsonString = String(data: jsonData, encoding: .utf8) {
    print(jsonString) #1
}

print("IsValidJSON: ", JSONSerialization.isValidJSONObject(programRequest)) #2

print(programRequest.json) #3

urlRequest = try! JSONEncoding.default.encode(urlRequest, with: programRequest.json) #4 causes error

1 выход:

{
  "userID" : 10021,
  "programData" : {
    "airhotel" : [],
    "security" : [
    {
        "vendorCode" : "sty",
        "loyaltyNumber" : "Loyal1"
    }
    ]
  }
}

2 выход IsValid JSON: false

3 выход - Я заметил, что AFNetworkingDemo.Security в выходных данных - это то, для чего используется JSONEncoding Alamofire:

["programData": ["security": [AFNetworkingDemo.Security(vendorCode: "sty", loyaltyNumber: "Loyal1")], "airhotel": []], "userID": 10021]

Мой вопрос заключается в том, какие изменения мне нужно внести в разделы AirHotel и Security в ProgramRequest, чтобы решить мои проблемы с Alamofire?

1 Ответ

0 голосов
/ 13 января 2020

Шаг 1: Прекратить повторное изобретение Codable

Вычисленное свойство json не требуется и используется неправильно.

Удалите его.

struct ProgramRequest: Codable {
    var userID: Int
    var programData: ProgramData
}

struct ProgramData: Codable {
    var airhotel: [AirHotel]
    var security: [Security]
}

struct AirHotel: Codable {
    var id: Int
    var loyaltyNumber: String
}

struct Security: Codable {
    var vendorCode: String
    var loyaltyNumber: String
}

Шаг 2: Запустите используя Codable

Теперь дано programRequest, например. вот так

let programRequest = ProgramRequest(userID: 1, programData: ProgramData(airhotel: [AirHotel(id: 1, loyaltyNumber: "loyaltyNumber")], security: [Security(vendorCode: "loyaltyNumber", loyaltyNumber: "loyaltyNumber")]))

Вы можете сгенерировать правильное значение данных, представляющее собой JSON, просто записав

let data = try JSONEncoder().encode(programRequest)

И (если хотите) вы можете преобразовать данные в строку

let json = String(data: data, encoding: .utf8)

Вывод

Optional("{\"userID\":1,\"programData\":{\"airhotel\":[{\"id\":1,\"loyaltyNumber\":\"loyaltyNumber\"}],\"security\":[{\"vendorCode\":\"loyaltyNumber\",\"loyaltyNumber\":\"loyaltyNumber\"}]}}")

Вот и все

...