ios - 如何在 init 中捕获错误(来自解码器 :Decoder) from a Codable struct?

标签 ios swift swift4 option-type codable

let jsonString = """
                    {
                        "name":1,
                        "gender":"male",
                    }
                    """

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

    public init(from decoder: Decoder) throws {
        do {
            let container = try decoder.container(keyedBy: CodingKeys.self)
            name = try container.decode(String.self, forKey: .name)
            gender = try container.decode(String.self, forKey: .gender)
        } catch {
            print("XXXXXX \(error)")
        }
    }
}

从上面的代码来看,它不会编译,因为它会提示,

Return from initializer without initializing all stored properties.

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

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

最佳答案

你不需要 init(from decoder: Decoder) 中的 do-catch 因为它已经被标记为 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)

            return nil
        }
    }
}

let personData = Data("""
{
    "name": 1,
    "gender": "male"
}
""".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)

关于ios - 如何在 init 中捕获错误(来自解码器 :Decoder) from a Codable struct?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50403870/

相关文章:

iphone - Storyboard中制作的 UIScrollView 的帧值为零

ios - 迭代数组时 Swift 无限循环

xcode - 如何将应用程序中本地通知的时间设置为两次之间随机? ( swift )

swift - 无法在自定义 UserDefaults 中保存结构 - 错误编码

swift - 访问字典键/值时出现模棱两可的错误

IOS UIDynamicAnimator masksToBounds 不会将碰撞作为边界

ios - 如何仅通过邀请将 iOS 应用程序分发给 50k 用户?

swift - 向上或向下滚动时增加或减少 imageView 的高度

iOS如何安排任务并在应用程序关闭时随机执行

ios - 如何在 iOS 的多个 friend 墙上分享 google Plus 中的消息?