Преобразование синтаксической структуры в кодируемую не работает должным образом - PullRequest
0 голосов
/ 04 февраля 2020

Я хотел бы проанализировать ответ от службы, используя codable, который сейчас можно разобрать. Текущая структура выглядит следующим образом:

{
    "service": {
        "categories": [
        {
        "categoryName": "category1",
        "fullName": "Federico",
        "id": "12345",
        "phone": "9787678684"
        }
        ],
        "type": "type"
    }
}

Моя проблема в том, что я не получаю сообщения об ошибках, отправленные сервером, которые будут иметь следующий формат

{
   errorType: “some errorType”,
   errorMessage: “some error message”
}

Как мне сделать модель, которая кодируется, которая удовлетворяет этим?

Ответы [ 4 ]

0 голосов
/ 04 февраля 2020

Разумным решением является перечисление со связанными типами, преимущество в том, что вы избавляетесь от необязательных

enum Response : Decodable {

    case success(Service)
    case failure(ResponseError)

    init(from decoder: Decoder) throws {
        let container = try decoder.singleValueContainer()
        do {
            let responseData = try container.decode(Service.self)
            self = .success(responseData)
        } catch DecodingError.typeMismatch {
            let errorData = try container.decode(ResponseError.self)
            self = .failure(errorData)
        }
    }
}

struct Service : Decodable {
    let categories : [Category]
}

struct ResponseError : Decodable {
    let errorType, errorMessage : String
}

struct Category : Decodable {
    ...
}

И используете его

do {
    let result = try JSONDecoder().decode(Response.self, from: data)
    switch result {
        case .success(let service): print(service)
        case .failure(let error): print(error)
    }
} else {
    print(error)
}
0 голосов
/ 04 февраля 2020

Вы можете сделать это так:

struct General: Decodable {
 let service: Service?
 let error: Error?
}
struct Service: Decodable {
 let categories: [Categories]
 let type: String
}
struct Categories: Decodable {
 let categoryName,fullName,id,phone: String
}
struct Error: Decodable {
 let errorType,errorMessage: String
}

Теперь вы можете проверить, есть ли ошибка.

guard let json = try? JSONDecoder().decode(General.self,from: data) else { print("Unable to parse response"); return }
if json.error.isEmpty {
//Show error
} else {
//Do your stuff
}
0 голосов
/ 04 февраля 2020

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

1. Модели успеха

struct Root: Decodable {
    let service: Service
}

struct Service: Decodable {
    let categories: [Category]
    let type: String
}

struct Category: Decodable {
    let categoryName, fullName, id, phone: String
}

2. Модели ошибок

struct Error: Decodable {
    let errorType: String
    let errorMessage: String
}

Сейчас парсинг JSON data вот так

do {
    let response = try JSONDecoder().decode(Root.self, from: data)
    print(response)
} catch {
    let error = try JSONDecoder().decode(Error.self, from: data)
    print(error)
}
0 голосов
/ 04 февраля 2020

Если я правильно понял, ответ будет либо

{
  "service": {
...

, либо

{
  "errorType": {
...

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

do {
    parsed = try JSONDecoder().decode(NormalStruct.self, from: data)
} catch {
    errorParsed = try! JSONDecoder().decode(ErrorStruct.self, from: data)
}
...