为UIColor实现Codable [英] Implementing Codable for UIColor

查看:227
本文介绍了为UIColor实现Codable的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否可以为 UIColor Encodable Decodable 属性c $ c>

Is it possible to implement the Encodable and Decodable properties for UIColor

当我尝试添加 Decodable 扩展名时,我收到错误

When I try to add a Decodable extension I get an error

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 :)'只能通过必需初始化程序来满足在非final类的定义'UIColor'
public required init(来自解码器:Decoder)抛出{

error: ColorStuff.playground:98:21: error: initializer requirement 'init(from:)' can only be satisfied by a required initializer in the definition of non-final class 'UIColor' public required init(from decoder: Decoder) throws {

Am我在这里遗漏了一些明显的东西?

Am I missing something obvious here?

我对 Encodable 扩展名没有任何问题 - 它似乎是可解码问题。

I have no issues with the Encodable extension - it seems its a Decodable issue.

错误消息告诉我,由于没有我不能这样做有权访问 UIColor 类定义

The error message implies to me that I cannot do this due to not having access to the UIColor class definition

推荐答案

你无法制作<由于编译器给出错误,code> UIColor 在扩展名中符合 Decodable

You cannot make UIColor conform to Decodable in an extension because of the error given by the compiler.

一种解决方案是制作一个 Codable 包装类型并改为使用它。

One solution is to make a Codable wrapper type and use that instead.

UIColor 已经符合 NSCoding ,让我们写一个泛型类型,这样我们就可以编码和解码任何符合<$ c的符号$ c> NSCoding 。

Since UIColor already conforms to NSCoding, let's just write a generic type so we can encode and decode anything that conforms to NSCoding.

import UIKit

struct WrapperOfNSCoding<Wrapped>: 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<UIColor>].self, from: jsonData).map({ $0.wrapped })
print(colors2)

这篇关于为UIColor实现Codable的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆