Convert Swift Encodable class typed as Any to dictionary

后端 未结 2 442
暗喜
暗喜 2021-01-22 10:17

In connection with my previous questions, I decided to subclass NSArrayController in order to achieve the desired behavior.

class NSPresetArrayContr         


        
2条回答
  •  孤独总比滥情好
    2021-01-22 11:03

    The type of the value that you pass to encode(_:) has to be a concrete type that implements Encodable. This means you need to recover the object's real type from the Any that you have. In order to cast, you must have a statically-specified type to which you are casting. You can't say object as! type(of: object), in other words; you have to say object as? MyClass (or in a generic context you can say object as? T).

    Therefore, I believe that the only way to get around this is to statically enumerate the types you are working with, like so:

    import Foundation
    
    struct S : Encodable {
        let i: Int
    }
    
    struct T : Encodable {
        let f: Float
    }
    
    struct U : Encodable {
        let b: Bool
    }
    
    func plistObject(from encodable: Any) -> Any? {
        let encoded: Data?
        switch encodable {
            case let s as S:
                encoded = try? PropertyListEncoder().encode(s)
            case let t as T:
                encoded = try? PropertyListEncoder().encode(t)
            case let u as U:
                encoded = try? PropertyListEncoder().encode(u)
            default:
                encoded = nil
        }
    
        guard let data = encoded else { return nil }
    
        return try? PropertyListSerialization.propertyList(from: data,
                                                           options: [],
                                                           format: nil)
    }
    

    Needless to say, this is rather gross. It's inflexible, repetitive boilerplate. I'm not sure I can actually recommend its use. It's an answer to the literal question, not necessarily a solution to the problem.

提交回复
热议问题