使用可选项将json解码为对象的泛型



我为Decodeable编写了一个扩展,希望为json字符串中的对象提供一个通用构造函数,它看起来像这样:

extension Decodable {
init?(with dictionary: [String: Any]) {
guard let data = try? JSONSerialization.data(
withJSONObject: dictionary,
options: .prettyPrinted
) else {
return nil
}
guard let result = try? JSONDecoder().decode(
Self.self,
from: data
) else {
return nil
}
self = result
}
}

一个示例用例如下:

guard let json = try? JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] else { return }
guard var goer = Goer(with: json) else { return }

我试图解码的对象看起来是这样的:

struct Goer: Codable {
let goerId: String
let created: Double
let username: String
let firstName: String
let lastName: String
let city: String
let bio: String
let isPrivate: Bool
let numFollowers: Int
let numFollowing: Int
let followers: [GoerFollow]
let following: [GoerFollow]
}

我的问题是,我想为这些对象引入一些选项,我试图解码的json字符串可能有密钥,也可能没有密钥。如果对象中的可选变量的json中没有key:value,则此泛型构造函数将失败。

我已经看到我可以为每个对象编写一个带有解码器的自定义构造函数,并使用decodeIfPresent函数,但我想知道是否有一种通用的方法。

if let jsonData = data {
do {
var model = try decoder.decode(Goer.self, from: jsonData)
print("model:(model)")
} catch {
print("error:(error)")
}
}

struct Goer: Codable {
let goerId: String?
let created: Double?
let username: String?
let firstName: String?
let lastName: String?
let city: String?
let bio: String?
let isPrivate: Bool?
let numFollowers: Int?
let numFollowing: Int?
let followers: [GoerFollow]?
let following: [GoerFollow]?
}

最新更新