简体   繁体   English

Swift Codable协议...编码/解码NSCoding类

[英]Swift Codable protocol… encoding / decoding NSCoding classes

I have the following struct… 我有以下结构......

struct Photo: Codable {

    let hasShadow: Bool
    let image: UIImage?

    enum CodingKeys: String, CodingKey {
        case `self`, hasShadow, image
    }

    init(hasShadow: Bool, image: UIImage?) {
        self.hasShadow = hasShadow
        self.image = image
    }

    init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        hasShadow = try container.decode(Bool.self, forKey: .hasShadow)

        // This fails
        image = try container.decode(UIImage?.self, forKey: .image) 
    }

    func encode(to encoder: Encoder) throws {
        var container = encoder.container(keyedBy: CodingKeys.self)
        try container.encode(hasShadow, forKey: .hasShadow)

        // This also fails
        try container.encode(image, forKey: .image)
    }
}

Encoding a Photo fails with … 编码Photo失败了......

Optional does not conform to Encodable because UIImage does not conform to Encodable 可选不符合Encodable,因为UIImage不符合Encodable

Decoding fails with… 解码失败了......

Key not found when expecting non-optional type Optional for coding key \\"image\\"")) 期待非可选类型时找不到键可选择编码键\\“image \\”“))

Is there a way to encode Swift objects that include NSObject subclass properties that conform to NSCoding ( UIImage , UIColor , etc)? 有没有办法编码包含符合NSCodingUIImageUIColor等)的NSObject子类属性的Swift对象?

Thanks to @vadian pointing me in the direction of encoding/decoding Data 感谢@vadian指点我编码/解码Data ...

class Photo: Codable {

    let hasShadow: Bool
    let image: UIImage?

    enum CodingKeys: String, CodingKey {
        case hasShadow, imageData
    }

    init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        hasShadow = try container.decode(Bool.self, forKey: .hasShadow)

        if let imageData = try container.decodeIfPresent(Data.self, forKey: .imageData) {
            image = NSKeyedUnarchiver.unarchiveObject(with: imageData) as? UIImage
        } else {
            image = nil
        }
    }

    func encode(to encoder: Encoder) throws {
        var container = encoder.container(keyedBy: CodingKeys.self)
        try container.encode(hasShadow, forKey: .hasShadow)

        if let image = image {
            let imageData = NSKeyedArchiver.archivedData(withRootObject: image)
            try container.encode(imageData, forKey: .imageData)
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM