怎么做 - 从Codable结构中捕获init(来自解码器:Decoder)的错误?

时间:2018-05-18 04:36:18

标签: ios swift swift4 optional codable

ABCDDEE11

从上面的代码中,它不会编译因为它抱怨,

  

从初始化程序返回,而不初始化所有存储的属性。

我想抛出一些错误,但如果没有,我该怎么做呢

  1. 为每个属性设置默认值。
  2. 使它们全部可选。

1 个答案:

答案 0 :(得分:6)

您在do-catch中不需要init(from decoder: Decoder),因为它已标记为throws。所以就这样做:

public init(from decoder: Decoder) throws {
    let container = try decoder.container(keyedBy: CodingKeys.self)
    name = try container.decode(String.self, forKey: .name)
    gender = try container.decode(String.self, forKey: .gender)
}

解码可以使用do-catch来查看上述init(from:)方法中抛出的任何异常,如下例所示:

struct Person: Codable {
    var name: String
    var gender: String

    // Note: This is not a very good example because this init method
    // is not even necessary in this case, since the automatically-
    // synthesized `init(from:)` method does exactly the same thing. I've
    // left it here to illustrate that you don't need to have a `do-catch`
    // in this method and can instead just use `try`, since the method
    // is marked as `throws`.
    public init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        name = try container.decode(String.self, forKey: .name)
        gender = try container.decode(String.self, forKey: .gender)
    }
}

class PersonDecoder {
    func person(decodedFrom data: Data) -> Person? {
        do {
            // The `JSONDecoder.decode(_:from:)` method calls
            // `Person.init(from:)`, which can throw, which is why
            // `JSONDecoder.decode(_:from:)` also throws.
            let person = try JSONDecoder().decode(Person.self, from: data)
            return person
        } catch {
            // Inspect any thrown errors here.
            print(error.localizedDescription)

            return nil
        }
    }
}

let personData = """
{
    "name": 1,
    "gender": "male"
}
""".data(using: .utf8)!

let personDecoder = PersonDecoder()

// Prints: "The data couldn’t be read because it isn’t in the correct format."
// and `person` is nil.
let person = personDecoder.person(decodedFrom: personData)