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 SwiftUI
|
||||
#if os(macOS)
|
||||
import AppKit
|
||||
#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 {
|
||||
public struct AnyBridge: Defaults.Bridge {
|
||||
public typealias Value = Defaults.AnySerializable
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import Foundation
|
||||
import CoreGraphics
|
||||
import SwiftUI
|
||||
#if os(macOS)
|
||||
import AppKit
|
||||
#else
|
||||
|
@ -136,6 +137,12 @@ extension Dictionary: Defaults.Serializable where Key: LosslessStringConvertible
|
|||
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)
|
||||
/// `NSColor` conforms to `NSSecureCoding`, so it goes to `NSSecureCodingBridge`.
|
||||
extension NSColor: Defaults.Serializable {}
|
||||
|
|
|
@ -3,25 +3,35 @@ import Foundation
|
|||
import SwiftUI
|
||||
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 {
|
||||
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 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 {
|
||||
@Default(.hasUnicorn) var hasUnicorn
|
||||
@Default(.user) var user
|
||||
@Default(.setInt) var setInt
|
||||
@Default(.color) var color
|
||||
|
||||
var body: some View {
|
||||
Text("User \(user.username) has Unicorn: \(String(hasUnicorn))")
|
||||
.foregroundColor(color)
|
||||
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 {
|
||||
override func setUp() {
|
||||
super.setUp()
|
||||
|
@ -38,13 +48,17 @@ final class DefaultsSwiftUITests: XCTestCase {
|
|||
XCTAssertFalse(view.hasUnicorn)
|
||||
XCTAssertEqual(view.user.username, "Hank")
|
||||
XCTAssertEqual(view.setInt.count, 3)
|
||||
XCTAssertEqual(NativeColor(view.color), NativeColor(Color.black))
|
||||
view.user = User(username: "Chen", password: "123456")
|
||||
view.hasUnicorn.toggle()
|
||||
view.setInt.insert(4)
|
||||
view.color = Color(.sRGB, red: 100, green: 100, blue: 100, opacity: 1)
|
||||
XCTAssertTrue(view.hasUnicorn)
|
||||
XCTAssertEqual(view.user.username, "Chen")
|
||||
XCTAssertEqual(view.setInt, Set(1...4))
|
||||
XCTAssertFalse(Default(.hasUnicorn).defaultValue)
|
||||
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