Skip to content

Commit

Permalink
Target macOS 11, iOS 13, tvOS 14, watchOS 7, visionOS 1 and later
Browse files Browse the repository at this point in the history
  • Loading branch information
sindresorhus committed Jan 18, 2024
1 parent d8a9f51 commit fcdf196
Show file tree
Hide file tree
Showing 10 changed files with 40 additions and 49 deletions.
6 changes: 3 additions & 3 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ jobs:
test:
runs-on: macos-13
steps:
- uses: actions/checkout@v3
- run: sudo xcode-select -switch /Applications/Xcode_15.0.app
- uses: actions/checkout@v4
- run: sudo xcode-select -switch /Applications/Xcode_15.2.app
- run: swift test
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- uses: norio-nomura/[email protected]
9 changes: 5 additions & 4 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@ import PackageDescription
let package = Package(
name: "Defaults",
platforms: [
.macOS(.v10_15),
.iOS(.v13),
.tvOS(.v13),
.watchOS(.v6)
.macOS(.v11),
.iOS(.v14),
.tvOS(.v14),
.watchOS(.v7),
.visionOS(.v1)
],
products: [
.library(
Expand Down
15 changes: 7 additions & 8 deletions Sources/Defaults/Defaults+Bridge.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ extension Defaults.CodableBridge {
return nil
}

return Value(jsonString: object)
return try? Value(jsonString: object)
}
}

Expand Down Expand Up @@ -373,15 +373,14 @@ extension Defaults {
It is unsafe to convert `SwiftUI.Color` to `UIColor` and use `UIColor.bridge` to serialize it, because `UIColor` does not hold a color space, but `Swift.Color` does (which means color space might get lost in the conversion). The bridge will always try to preserve the color space whenever `Color#cgColor` exists. Only when `Color#cgColor` is `nil`, will it use `UIColor.bridge` to do the serialization and deserialization.
*/
@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 = Any

#if os(macOS)
private typealias NativeColor = NSColor
private typealias XColor = NSColor
#else
private typealias NativeColor = UIColor
private typealias XColor = UIColor
#endif

public func serialize(_ value: Value?) -> Serializable? {
Expand All @@ -394,15 +393,15 @@ extension Defaults {
let colorSpace = cgColor.colorSpace?.name as? String,
let components = cgColor.components
else {
return NativeColor.bridge.serialize(NativeColor(value))
return XColor.bridge.serialize(XColor(value))
}

return [colorSpace, components] as [Any]
}

public func deserialize(_ object: Serializable?) -> Value? {
if let object = object as? NativeColor.Serializable {
guard let nativeColor = NativeColor.bridge.deserialize(object) else {
if let object = object as? XColor.Serializable {
guard let nativeColor = XColor.bridge.deserialize(object) else {
return nil
}

Expand All @@ -419,7 +418,7 @@ extension Defaults {
return nil
}

if #available(macOS 12.0, macOSApplicationExtension 12.0, *) {
if #available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, iOSApplicationExtension 15.0, macOSApplicationExtension 12.0, tvOSApplicationExtension 15.0, watchOSApplicationExtension 8.0, *) {
return Value(cgColor: cgColor)
}

Expand Down
1 change: 0 additions & 1 deletion Sources/Defaults/Defaults+Extensions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,6 @@ extension UUID: Defaults.Serializable {
public static let bridge = Defaults.UUIDBridge()
}

@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()
}
Expand Down
3 changes: 0 additions & 3 deletions Sources/Defaults/SwiftUI.swift
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,6 @@ extension Default where Value: Equatable {
public var isDefaultValue: Bool { wrappedValue == defaultValue }
}

@available(macOS 11, iOS 14, tvOS 14, watchOS 7, *)
extension Defaults {
/**
A SwiftUI `Toggle` view that is connected to a ``Defaults/Key`` with a `Bool` value.
Expand Down Expand Up @@ -211,15 +210,13 @@ extension Defaults {
}
}

@available(macOS 11, iOS 14, tvOS 14, watchOS 7, *)
extension Defaults.Toggle<Text> {
public init(_ title: some StringProtocol, key: Defaults.Key<Bool>) {
self.label = { Text(title) }
self.observable = .init(key)
}
}

@available(macOS 11, iOS 14, tvOS 14, watchOS 7, *)
extension Defaults.Toggle {
/**
Do something when the value changes to a different value.
Expand Down
25 changes: 13 additions & 12 deletions Sources/Defaults/Utilities.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,22 @@ import OSLog
#endif
#endif

extension Decodable {
init?(jsonData: Data) {
guard let value = try? JSONDecoder().decode(Self.self, from: jsonData) else {
return nil
}

self = value
}
extension String {
/**
Get the string as UTF-8 data.
*/
var toData: Data { Data(utf8) }
}

init?(jsonString: String) {
guard let data = jsonString.data(using: .utf8) else {
return nil
}

self.init(jsonData: data)
extension Decodable {
init(jsonData: Data) throws {
self = try JSONDecoder().decode(Self.self, from: jsonData)
}

init(jsonString: String) throws {
try self.init(jsonData: jsonString.toData)
}
}

Expand Down
2 changes: 1 addition & 1 deletion Tests/DefaultsTests/DefaultsNSColorTests.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#if canImport(AppKit)
#if os(macOS)
import Foundation
import Defaults
import XCTest
Expand Down
13 changes: 5 additions & 8 deletions Tests/DefaultsTests/DefaultsSwiftUITests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,18 @@ import SwiftUI
import Defaults

#if os(macOS)
typealias NativeColor = NSColor
typealias XColor = NSColor
#else
typealias NativeColor = UIColor
typealias XColor = 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 11.0, iOS 15.0, tvOS 15.0, watchOS 8.0, *)
struct ContentView: View {
@Default(.hasUnicorn) var hasUnicorn
@Default(.user) var user
Expand All @@ -31,7 +29,6 @@ struct ContentView: View {
}
}

@available(macOS 11.0, iOS 15.0, tvOS 15.0, watchOS 8.0, *)
final class DefaultsSwiftUITests: XCTestCase {
override func setUp() {
super.setUp()
Expand All @@ -48,7 +45,7 @@ final class DefaultsSwiftUITests: XCTestCase {
XCTAssertFalse(view.hasUnicorn)
XCTAssertEqual(view.user.username, "Hank")
XCTAssertEqual(view.setInt.count, 3)
XCTAssertEqual(NativeColor(view.color), NativeColor(Color.black))
XCTAssertEqual(XColor(view.color), XColor(Color.black))
view.user = User(username: "Chen", password: "123456")
view.hasUnicorn.toggle()
view.setInt.insert(4)
Expand All @@ -58,7 +55,7 @@ final class DefaultsSwiftUITests: XCTestCase {
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)))
XCTAssertNotEqual(XColor(view.color), XColor(Color.black))
XCTAssertEqual(XColor(view.color), XColor(Color(.sRGB, red: 100, green: 100, blue: 100, opacity: 1)))
}
}
2 changes: 1 addition & 1 deletion license
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) Sindre Sorhus <[email protected]> (sindresorhus.com)
Copyright (c) Sindre Sorhus <[email protected]> (https://sindresorhus.com)

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

Expand Down
13 changes: 5 additions & 8 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,17 +30,16 @@ It's used in production by [all my apps](https://sindresorhus.com/apps) (1 milli

## Compatibility

- macOS 10.15+
- iOS 13+
- tvOS 13+
- watchOS 6+
- macOS 11+
- iOS 14+
- tvOS 14+
- watchOS 7+
- visionOS 1+

## Install

Add `https://github.com/sindresorhus/Defaults` in the [“Swift Package Manager” tab in Xcode](https://developer.apple.com/documentation/xcode/adding_package_dependencies_to_your_app).

**Requires Xcode 14.1 or later**

## Support types

- `Int(8/16/32/64)`
Expand Down Expand Up @@ -233,8 +232,6 @@ struct ShowAllDayEventsSetting: View {
}
```

*Requires at least macOS 11, iOS 14, tvOS 14, watchOS 7.*

### Observe changes to a key

```swift
Expand Down

0 comments on commit fcdf196

Please sign in to comment.