Add support for SwiftUI `Color` (#84)
Co-authored-by: Sindre Sorhus <sindresorhus@gmail.com>
This commit is contained in:
parent
8a6e4a96fd
commit
55f3302c3a
|
@ -1,4 +1,5 @@
|
||||||
import Foundation
|
import Foundation
|
||||||
|
import SwiftUI
|
||||||
#if os(macOS)
|
#if os(macOS)
|
||||||
import AppKit
|
import AppKit
|
||||||
#else
|
#else
|
||||||
|
@ -296,6 +297,36 @@ extension Defaults {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extension Defaults {
|
||||||
|
@available(iOS 15.0, macOS 11.0, tvOS 15.0, watchOS 8.0, iOSApplicationExtension 15.0, macOSApplicationExtension 11.0, tvOSApplicationExtension 15.0, watchOSApplicationExtension 8.0, *)
|
||||||
|
public struct ColorBridge: Bridge {
|
||||||
|
public typealias Value = Color
|
||||||
|
public typealias Serializable = Data
|
||||||
|
|
||||||
|
#if os(macOS)
|
||||||
|
private typealias NativeColor = NSColor
|
||||||
|
#else
|
||||||
|
private typealias NativeColor = UIColor
|
||||||
|
#endif
|
||||||
|
|
||||||
|
public func serialize(_ value: Value?) -> Serializable? {
|
||||||
|
guard let value = value else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return NativeColor.bridge.serialize(NativeColor(value))
|
||||||
|
}
|
||||||
|
|
||||||
|
public func deserialize(_ object: Serializable?) -> Value? {
|
||||||
|
guard let nativeColor = NativeColor.bridge.deserialize(object) else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return Value(nativeColor)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
extension Defaults {
|
extension Defaults {
|
||||||
public struct AnyBridge: Defaults.Bridge {
|
public struct AnyBridge: Defaults.Bridge {
|
||||||
public typealias Value = Defaults.AnySerializable
|
public typealias Value = Defaults.AnySerializable
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import Foundation
|
import Foundation
|
||||||
import CoreGraphics
|
import CoreGraphics
|
||||||
|
import SwiftUI
|
||||||
#if os(macOS)
|
#if os(macOS)
|
||||||
import AppKit
|
import AppKit
|
||||||
#else
|
#else
|
||||||
|
@ -136,6 +137,12 @@ extension Dictionary: Defaults.Serializable where Key: LosslessStringConvertible
|
||||||
public static var bridge: Defaults.DictionaryBridge<Key, Value> { Defaults.DictionaryBridge() }
|
public static var bridge: Defaults.DictionaryBridge<Key, Value> { Defaults.DictionaryBridge() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@available(iOS 15.0, macOS 11.0, tvOS 15.0, watchOS 8.0, iOSApplicationExtension 15.0, macOSApplicationExtension 11.0, tvOSApplicationExtension 15.0, watchOSApplicationExtension 8.0, *)
|
||||||
|
extension Color: Defaults.Serializable {
|
||||||
|
public static let bridge = Defaults.ColorBridge()
|
||||||
|
}
|
||||||
|
|
||||||
#if os(macOS)
|
#if os(macOS)
|
||||||
/// `NSColor` conforms to `NSSecureCoding`, so it goes to `NSSecureCodingBridge`.
|
/// `NSColor` conforms to `NSSecureCoding`, so it goes to `NSSecureCodingBridge`.
|
||||||
extension NSColor: Defaults.Serializable {}
|
extension NSColor: Defaults.Serializable {}
|
||||||
|
|
|
@ -3,25 +3,35 @@ import Foundation
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
import Defaults
|
import Defaults
|
||||||
|
|
||||||
|
#if os(macOS)
|
||||||
|
typealias NativeColor = NSColor
|
||||||
|
#else
|
||||||
|
typealias NativeColor = UIColor
|
||||||
|
#endif
|
||||||
|
|
||||||
|
@available(macOS 11.0, iOS 15.0, tvOS 15.0, watchOS 8.0, *)
|
||||||
extension Defaults.Keys {
|
extension Defaults.Keys {
|
||||||
fileprivate static let hasUnicorn = Key<Bool>("swiftui_hasUnicorn", default: false)
|
fileprivate static let hasUnicorn = Key<Bool>("swiftui_hasUnicorn", default: false)
|
||||||
fileprivate static let user = Key<User>("swiftui_user", default: User(username: "Hank", password: "123456"))
|
fileprivate static let user = Key<User>("swiftui_user", default: User(username: "Hank", password: "123456"))
|
||||||
fileprivate static let setInt = Key<Set<Int>>("swiftui_setInt", default: Set(1...3))
|
fileprivate static let setInt = Key<Set<Int>>("swiftui_setInt", default: Set(1...3))
|
||||||
|
fileprivate static let color = Key<Color>("swiftui_color", default: .black)
|
||||||
}
|
}
|
||||||
|
|
||||||
@available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *)
|
@available(macOS 11.0, iOS 15.0, tvOS 15.0, watchOS 8.0, *)
|
||||||
struct ContentView: View {
|
struct ContentView: View {
|
||||||
@Default(.hasUnicorn) var hasUnicorn
|
@Default(.hasUnicorn) var hasUnicorn
|
||||||
@Default(.user) var user
|
@Default(.user) var user
|
||||||
@Default(.setInt) var setInt
|
@Default(.setInt) var setInt
|
||||||
|
@Default(.color) var color
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
Text("User \(user.username) has Unicorn: \(String(hasUnicorn))")
|
Text("User \(user.username) has Unicorn: \(String(hasUnicorn))")
|
||||||
|
.foregroundColor(color)
|
||||||
Toggle("Toggle Unicorn", isOn: $hasUnicorn)
|
Toggle("Toggle Unicorn", isOn: $hasUnicorn)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *)
|
@available(macOS 11.0, iOS 15.0, tvOS 15.0, watchOS 8.0, *)
|
||||||
final class DefaultsSwiftUITests: XCTestCase {
|
final class DefaultsSwiftUITests: XCTestCase {
|
||||||
override func setUp() {
|
override func setUp() {
|
||||||
super.setUp()
|
super.setUp()
|
||||||
|
@ -38,13 +48,17 @@ final class DefaultsSwiftUITests: XCTestCase {
|
||||||
XCTAssertFalse(view.hasUnicorn)
|
XCTAssertFalse(view.hasUnicorn)
|
||||||
XCTAssertEqual(view.user.username, "Hank")
|
XCTAssertEqual(view.user.username, "Hank")
|
||||||
XCTAssertEqual(view.setInt.count, 3)
|
XCTAssertEqual(view.setInt.count, 3)
|
||||||
|
XCTAssertEqual(NativeColor(view.color), NativeColor(Color.black))
|
||||||
view.user = User(username: "Chen", password: "123456")
|
view.user = User(username: "Chen", password: "123456")
|
||||||
view.hasUnicorn.toggle()
|
view.hasUnicorn.toggle()
|
||||||
view.setInt.insert(4)
|
view.setInt.insert(4)
|
||||||
|
view.color = Color(.sRGB, red: 100, green: 100, blue: 100, opacity: 1)
|
||||||
XCTAssertTrue(view.hasUnicorn)
|
XCTAssertTrue(view.hasUnicorn)
|
||||||
XCTAssertEqual(view.user.username, "Chen")
|
XCTAssertEqual(view.user.username, "Chen")
|
||||||
XCTAssertEqual(view.setInt, Set(1...4))
|
XCTAssertEqual(view.setInt, Set(1...4))
|
||||||
XCTAssertFalse(Default(.hasUnicorn).defaultValue)
|
XCTAssertFalse(Default(.hasUnicorn).defaultValue)
|
||||||
XCTAssertFalse(Default(.hasUnicorn).isDefaultValue)
|
XCTAssertFalse(Default(.hasUnicorn).isDefaultValue)
|
||||||
|
XCTAssertNotEqual(NativeColor(view.color), NativeColor(Color.black))
|
||||||
|
XCTAssertEqual(NativeColor(view.color), NativeColor(Color(.sRGB, red: 100, green: 100, blue: 100, opacity: 1)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue