首页 文章

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

提问于
浏览
7

我有以下结构......

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 失败了......

Optional不符合Encodable,因为UIImage不符合Encodable

解码失败了......

期望非可选类型时找不到键可选编码键\“image \”“))

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

1 回答

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

相关问题