gpt4 book ai didi

swift - 如何使用 Argo 和 Swift 创建子类?

转载 作者:搜寻专家 更新时间:2023-10-31 22:45:41 24 4
gpt4 key购买 nike

我在 Swift 应用程序中使用 Argo 将 JSON 解码为对象。我有这样的 JSON:

"activities": [
{
"id": "intro-to-the-program",
"type": "session",
"audio": "intro-to-the-program.mp3"
},
{
"id": "goal-setting",
"type": "session",
"audio": "goal-setting.mp3"
},
{
"id": "onboarding-quiz",
"type": "quiz"
}
]

基于“类型”,我实际上想实例化 Activity 类的子类(ActivitySession、ActivityQuiz 等)并让子类进行自己的解码。

我该怎么做?顶级 decode() 函数需要返回类型 Decoded<Activity> ,到目前为止,我的方法似乎都无法打败它。

最佳答案

这是一种方法,您可以通过打开类型来有条件地对其进行解码,并在给出无效类型时收到一条很好的错误消息。

struct ThingWithActivities: Decodable {
let activities: [Activity]

static func decode(json: JSON) -> Decoded<ThingWithActivities> {
return curry(ThingWithActivities.init)
<^> json <|| "activities"
}
}

class Activity: Decodable {
let id: String

init(id: String) {
self.id = id
}

class func decode(json: JSON) -> Decoded<Activity> {
let decodedType: Decoded<String> = json <| "type"
return decodedType.flatMap { type in
switch type {
case "session": return ActivitySession.decode(json)
case "quiz": return ActivityQuiz.decode(json)
default:
return .Failure(.Custom("Expected valid type, found: \(type)"))
}
}
}
}

class ActivitySession: Activity {
let audio: String

init(id: String, audio: String) {
self.audio = audio
super.init(id: id)
}

override static func decode(json: JSON) -> Decoded<Activity> {
return curry(ActivitySession.init)
<^> json <| "id"
<*> json <| "audio"
}

}

class ActivityQuiz: Activity {
override static func decode(json: JSON) -> Decoded<Activity> {
return curry(ActivityQuiz.init)
<^> json <| "id"
}
}

let activities: Decoded<ThingWithActivities>? = JSONFromFile("activities").flatMap(decode)
print(activities)
// => Optional(Success(ThingWithActivities(activities: [ActivitySession, ActivitySession, ActivityQuiz])))

关键部分是提取类型并 .flatMap 对其进行有条件地解码为应有的类型。

关于swift - 如何使用 Argo 和 Swift 创建子类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38460804/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com