为UIColor实现Codable
是否可以为UIColor
实现Encodable
和Decodable
属性
当我尝试添加可Decodable
扩展时,我收到错误
extension UIColor : Decodable { public required init(from decoder: Decoder) throws { self.init(red: 1, green: 1, blue: 1, alpha: 1) } }
错误:ColorStuff.playground:98:21:错误:初始化程序要求’init(from :)’只能通过非最终类’UIColor’定义中
required
初始化程序来满足公共所需的init(来自解码器:解码器)抛出{
我错过了一些明显的东西吗?
我对Encodable
扩展没有任何问题 – 它似乎是一个可Decodable
问题。
错误消息告诉我,由于无法访问UIColor
类定义,我无法执行此操作
由于编译器给出的错误,您无法在扩展中使UIColor
符合Decodable
。
一种解决方案是制作Codable
包装类型并使用它。
由于UIColor
已经符合NSCoding
,我们只需编写一个generics类型,这样我们就可以编码和解码符合NSCoding
任何内容。
import UIKit struct WrapperOfNSCoding: Codable where Wrapped: NSCoding { var wrapped: Wrapped init(_ wrapped: Wrapped) { self.wrapped = wrapped } init(from decoder: Decoder) throws { let container = try decoder.singleValueContainer() let data = try container.decode(Data.self) guard let object = NSKeyedUnarchiver.unarchiveObject(with: data) else { throw DecodingError.dataCorruptedError(in: container, debugDescription: "failed to unarchive an object") } guard let wrapped = object as? Wrapped else { throw DecodingError.typeMismatch(Wrapped.self, DecodingError.Context(codingPath: container.codingPath, debugDescription: "unarchived object type was \(type(of: object))")) } self.wrapped = wrapped } func encode(to encoder: Encoder) throws { let data = NSKeyedArchiver.archivedData(withRootObject: wrapped) var container = try encoder.singleValueContainer() try container.encode(data) } } let colors = [UIColor.red, UIColor.brown] print(colors) let jsonData = try! JSONEncoder().encode(colors.map({ WrapperOfNSCoding($0) })) let colors2 = try! JSONDecoder().decode([WrapperOfNSCoding].self, from: jsonData).map({ $0.wrapped }) print(colors2)