struct Color: Codable {
let red, green, blue, alpha: CGFloat
}
extension Color {
var uiColor: UIColor { return UIColor(color: self) }
var cgColor: CGColor { return uiColor.cgColor }
var ciColor: CIColor { return CIColor(color: uiColor) }
var data: Data { return try! JSONEncoder().encode(self) }
}
extension UIColor {
convenience init(color: Color) {
self.init(red: color.red, green: color.green, blue: color.blue, alpha: color.alpha)
}
var color: Color {
let color = CIColor(color: self)
return Color(red: color.red, green: color.green, blue: color.blue, alpha: color.alpha)
}
}
extension Data {
var string: String {
return String(data: self, encoding: .utf8) ?? ""
}
}
Playground testing
let json = """
{"red": 0.5, "green": 0.0, "blue": 0.0, "alpha": 1.0}
"""
if let color = try? JSONDecoder().decode(Color.self, from: Data(json.utf8)) {
print(color) // "Color(red: 0.5, green: 0.0, blue: 0.0, alpha: 1.0)
"
print(color.uiColor) // "UIExtendedSRGBColorSpace 0.5 0 0 1
print(color.data) // "40 bytes
"
print(color.data.string) // "{"red":0.5,"alpha":1,"blue":0,"green":0}
"
}
let redColor = UIColor.red.color
let jsonData = redColor.data.string // "{"red":1,"alpha":1,"blue":0,"green":0}"
If you need to work with your array of CGFloats you can override JSON Encoder and Decoder initializers:
extension Color {
public init(from decoder: Decoder) throws {
var container = try decoder.unkeyedContainer()
red = try container.decode(CGFloat.self)
green = try container.decode(CGFloat.self)
blue = try container.decode(CGFloat.self)
alpha = try container.decode(CGFloat.self)
}
public func encode(to encoder: Encoder) throws {
var container = encoder.unkeyedContainer()
try container.encode(red)
try container.encode(green)
try container.encode(blue)
try container.encode(alpha)
}
}
Testing
let values: [CGFloat] = [0.5,0.0,0.0,1.0]
let jsonData = try JSONSerialization.data(withJSONObject: values) // 11 bytes
let json = jsonData.string // "[0.5,0,0,1]"
do {
let color = try JSONDecoder().decode(Color.self, from: jsonData)
print(color) // "Color(red: 0.5, green: 0.0, blue: 0.0, alpha: 1.0)
"
print(color.uiColor) // "UIExtendedSRGBColorSpace 0.5 0 0 1
print(color.data) // "11 bytes
"
print(color.data.string) // "[0.5,0,0,1]
"
let encodedData = try JSONEncoder().encode(color) // 11 bytes
print(encodedData == jsonData) // true
} catch {
print(error)
}