这个软件包是 SNAP 套件的一部分。

SnapSettingsService

一个用于处理不同类型设置的单一接口。它为 String 类型的键存储一个 Codable 类型的值,可以本地存储 (UserDefaults)、同步存储 (NSUbiquitousKeyValueStore) 或自定义存储。

这个软件包提供了 SettingsService 类、SettingsStore 协议以及用于定义、保存和读取设置的辅助工具。

Documentation

设置

为了支持存储在 iCloud (`NSUbiquitousKeyValueStore`) 中的设置,你必须为目标 target 添加 iCloud Capability 并启用 `Key-value storage` 复选框。

示例

示例项目 展示了 SettingsService 在不同作用域中使用的例子。

如何使用

定义你的设置

extension SettingsService.SettingDefinition {
	static let exampleNumber = SettingsService.Setting<Int>("ExampleNumber", in: .defaults, default: 1)
}

读取和写入设置

let settings = SettingsService()
settings.set(.exampleNumber, to: 2)
let number = settings.get(.exampleNumber)

当你需要根据更改更新时,使用绑定。

struct MyView: View {
	let observableValue: SettingsService.Value<Int> = settings.value(.exampleNumber)
	var body: some View {
		Text("\(observableValue.value)")
		SomeView(binding: observableValue.binding)
	}
}

作用域

SettingsService 可以使用 SettingsStore 对象为 Scope 配置:.defaults、.ubiquitous、.custom(id:)

SettingsService.init(defaults: UserDefaults? = .standard, ubiquitous: NSUbiquitousKeyValueStore? = .default, storesForCustomScopes: [Scope : SettingsStore] = [:])

.defaults

本地存储在 UserDefaults 中。

// TODO: 如何处理隐私要求。

.ubiquitous

使用 NSUbiquitousKeyValueStore 存储在 iCloud 中。

如果用户未登录,则值将本地存储并记录警告。

要使用 NSUbiquitousKeyValueStore,你必须通过 App Store 或 Mac App Store 分发你的应用,并且你必须在你的 Xcode 项目中请求 com.apple.developer.ubiquity-kvstore-identifier entitlement 权限。NSUbiquitousKeyValueStore 文档

(参见 设置

.custom(id:)

你可以提供一个或多个实现 SettingsStore 的自定义存储。

如果作用域没有注册存储,则会记录警告。

SettingsStore

UserDefaults 和 NSUbiquitousKeyValueStore 被扩展为遵循 SettingsStore。

自定义

你可以通过实现 SettingsStore 来创建自定义存储。

public protocol SettingsStore {
	func get<T>(_ key: SettingsService.Setting<T>) -> Data?
	func set<T>(_ key: SettingsService.Setting<T>, to data: Data?)
}

访问设置

获取 & 设置

let settings = SettingsService()
settings.set(.exampleNumber, to: 2)
let number = settings.get(.exampleNumber)

可观察值

struct MyView: View {
	let observableValue: SettingsService.Value<Int> = settings.value(.exampleNumber)
	var body: some View {
		Text("\(observableValue.value)")
		SomeView(binding: observableValue.binding)
	}
}

Publisher

SettingsService 提供了一个 Combine publisher 以接收更新的值。如果设置存储在 `.ubiquitous` 作用域中,则 publisher 会在远程更改时更新 (`NSUbiquitousKeyValueStore.didChangeExternallyNotification`)。

Environment

SettingsService 可以通过提供的 EnvironmentKey 使用。

注入到 `@Environment` 中

@Environment(\.serviceSettings) private var settings

从 `@Environment` 访问

View().environment(\.serviceSettings, settings)

TODO

// TODO: App Groups?在 Widget 中访问?// TODO: 处理 iCloud 不可用情况。它确实本地存储并记录警告,但应该做些什么?// TODO: 与 https://github.com/kylehughes/PersistentKeyValueKit 比较 // TODO: 与 https://github.com/sindresorhus/Defaults 比较