Как определить, что значение данных равно nil, когда свойства структуры являются необязательными - PullRequest
0 голосов
/ 03 апреля 2019

Синтаксический анализ данных с использованием Codable не приводит к сбою.

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

struct someStruct: Codable {
    var name: String?
    var age: Int?
}

JSON :
{
    "some_key": 123
}

Ответы [ 3 ]

0 голосов
/ 03 апреля 2019

Вы можете просто использовать Codable со своей структурой и когда вы анализируете данные JSON, и поскольку ваши свойства в struct необязательны , вы можете безопасно развернуть значения, используя if-let. Я предоставил образец примера для того же

import Foundation

let jsonData = """
    {
        "some_key": 123
    }
"""

let data = Data(jsonData.utf8)

struct someStruct: Codable {
    var name: String?
    var age: Int?
}

let decoder = JSONDecoder()

do {
    let decodedData = try decoder.decode(someStruct.self, from: data)

    // Either use this
    print(decodedData.name ?? "Name not specified")

    // Or use this
    if let name = decodedData.name {
        // Name is not nil
        // Sample Example
        print(name)
    }
    else {
        // Name is nil , Handle the situation accordingly
        // Sample Example
        print("Name not specified")
    }

} catch  {
    print("Could not parse JSON Data")
}
0 голосов
/ 03 апреля 2019

Таким образом, вы хотите throw, если поле отсутствует, но продолжить, когда поле указано, но nil. Вам нужно реализовать пользовательскую кодировку, чтобы решить это:

enum EncodingError: Error {
    case missing
}

struct Struct: Codable {
    let age: Int
    let name: String?

    enum CodingKeys: CodingKey {
        case age
        case name
    }

    init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        // normal decoding
        age = try container.decode(Int.self, forKey: .age)
        // check if key exists or throw
        guard container.contains(.name) else {
            throw EncodingError.missing
        }
        name = try container.decode(String?.self, forKey: .name)
     }
}

let correctData = """
{
    "age": 34,
    "name": null
}
""".data(using: .utf8)!

let failData = """
{
    "age": 33
}
""".data(using: .utf8)!

do {
    let decoder = JSONDecoder()
    let encoded = try decoder.decode(Struct.self, from: correctData) // succeeds
    let fail = try decoder.decode(Struct.self, from: failData) // fails
} catch(let error) where error is EncodingError {
    error
} catch {
    error
}
0 голосов
/ 03 апреля 2019

Вы должны использовать Codable для анализа данных, независимо от того, является ли он нулевым или нет.И после этого вы можете проверить Struct, как показано ниже, для значения ноль-

if let name = yourStruct.name as? String {

} else {
  //nil
}
...