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

时间:2017-07-26 08:53:07

标签: swift nscoding swift4 codable

我有以下结构...

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)
    }
}

编码Photo失败了......

  

可选不符合Encodable,因为UIImage可以   不符合Encodable

解码失败了......

  

期望非可选类型时找不到键可选   编码密钥\"图像\""))

有没有办法对包含符合NSObject NSCodingUIImageUIColor子类属性的Swift对象进行编码?

1 个答案:

答案 0 :(得分:9)

感谢@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)
        }
    }
}