2016-07-19 12 views
3

私はSwiftアプリケーションでArgoを使用してJSONをオブジェクトにデコードしています。 「タイプ」に基づいてArgoとSwiftを使用してサブクラスを作成するにはどうすればよいですか?

"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など)のサブクラスをインスタンス化し、サブクラスを持ちたい、独自のデコードを行います。私はこのようなJSONを持っています。

どうすればいいですか?最上位のdecode()関数は戻り値の型がDecoded<Activity>であると想定していますが、これまでの私のアプローチではそれを打ち破ることはできません。

答えて

2

これを行うには、条件をデコードして無効な型が指定されたときにエラーメッセージが表示されるように型を切り替える方法があります。

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 INGを引き出しています。

+0

あなたは天才です - それは動作します。 うわーこのスウィフトマラキーは確かに慣れるまでにかかる! –

関連する問題