gpt4 book ai didi

swift4 - 使 UIColor 可编码

转载 作者:行者123 更新时间:2023-12-04 02:45:03 24 4
gpt4 key购买 nike

struct Task: Codable {
var content: String
var deadline: Date
var color: UIColor
...
}

有警告说“类型'Task'不符合协议(protocol)'Decodable'”和“类型'Task'不符合协议(protocol)'Encodable'”。查了一下发现这是因为UIColor不符合Codable。但我不知道如何解决这个问题。所以...

如何使 UIColor 可编码?

最佳答案

如果您只关心 4 个颜色组件,这是一个使用包装器结构的简单解决方案

struct Color : Codable {
var red : CGFloat = 0.0, green: CGFloat = 0.0, blue: CGFloat = 0.0, alpha: CGFloat = 0.0

var uiColor : UIColor {
return UIColor(red: red, green: green, blue: blue, alpha: alpha)
}

init(uiColor : UIColor) {
uiColor.getRed(&red, green: &green, blue: &blue, alpha: &alpha)
}
}
在这种情况下,您必须编写一个自定义初始化程序来转换 Color 中的 4 个颜色分量。至 UIColor反之亦然。
struct Task: Codable {

private enum CodingKeys: String, CodingKey { case content, deadline, color }

var content: String
var deadline: Date
var color : UIColor

init(content: String, deadline: Date, color : UIColor) {
self.content = content
self.deadline = deadline
self.color = color
}

init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
content = try container.decode(String.self, forKey: .content)
deadline = try container.decode(Date.self, forKey: .deadline)
color = try container.decode(Color.self, forKey: .color).uiColor
}

public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(content, forKey: .content)
try container.encode(deadline, forKey: .deadline)
try container.encode(Color(uiColor: color), forKey: .color)
}
}
现在您可以编码和解码 UIColor
let task = Task(content: "Foo", deadline: Date(), color: .orange)
do {
let data = try JSONEncoder().encode(task)
print(String(data: data, encoding: .utf8)!)
let newTask = try JSONDecoder().decode(Task.self, from: data)
print(newTask)
} catch { print(error) }

Swift 5.1 及更高版本的智能替代方案是属性包装器
@propertyWrapper
struct CodableColor {
var wrappedValue: UIColor
}

extension CodableColor: Codable {
init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
let data = try container.decode(Data.self)
guard let color = try NSKeyedUnarchiver.unarchivedObject(ofClass: UIColor.self, from: data) else {
throw DecodingError.dataCorruptedError(
in: container,
debugDescription: "Invalid color"
)
}
wrappedValue = color
}

func encode(to encoder: Encoder) throws {
var container = encoder.singleValueContainer()
let data = try NSKeyedArchiver.archivedData(withRootObject: wrappedValue, requiringSecureCoding: true)
try container.encode(data)
}
}
并用 @CodableColor 标记该属性
struct Task: Codable {
var content: String
var deadline: Date
@CodableColor var color: UIColor
...
}

关于swift4 - 使 UIColor 可编码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50928153/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com