DCSettings

Swift Package Manager iOS | Mac Mastodon: @caddy

欢迎使用 DCSettings,这是一个 Swift 包,它通过易于使用的结果构建器语法和可直接使用的 SwiftUI 用户界面,简化了用户偏好设置的配置。

您可以像这样在 UserDeafultsNSUbiquitousKeyValueStore 或自定义键值存储中配置设置。

DCSettingsManager.shared.configure {
    DCSettingGroup("General") {
        DCSetting(key: "refreshInterval") {
            DCSettingOption(value: 5, label: "5 mins")
            DCSettingOption(value: 10, label: "10 mins")
            DCSettingOption(value: 15, label: "15 mins")
            DCSettingOption(value: 30, label: "30 mins").default()
            DCSettingOption(value: 60, label: "60 mins")
        }
        DCSetting(key: "articleListLayout") {
            DCSettingOption(value: "List", label: "List", systemImage: "list.bullet")
            DCSettingOption(value: "Grid", label: "Grid", systemImage: "square.grid.2x2")
        }
        DCSetting(key: "showImages", defaultValue: true)
        DCSetting(key: "showFullContent", defaultValue: false)
        DCSetting(key: "markAsReadOnScroll", defaultValue: true)
        DCSetting(key: "maxSyncItems", defaultValue: 1000)
    }
    DCSettingGroup("Appearance") {
        DCSetting(key: "theme", label: "Theme", options: ["Light", "Dark"])
        DCSetting(key: "fontSize", options: [12, 14, 16, 18, 20], defaultIndex: 2)
        DCSetting(key: "lineSpacing", defaultValue: 1.2, lowerBound: 1.0, upperBound: 1.6, step: 0.1)
        DCSetting(key: "highlightColor", defaultValue: Color.blue)
    }
}

然后使用 DCSettingsView 在列表视图中显示设置。

Settings View Settings View

DCSettingsView()

安装

要安装 DCSettings,请将以下行添加到您的 Package.swift 文件中。

dependencies: [
    .package(url: "https://github.com/davidcaddy/DCSettings.git", from: "0.1.0")
]

使用方法

要在您的项目中使用 DCSettings,您需要在 Swift 文件的顶部像这样导入它。

import DCSettings

配置设置

要配置设置,您可以使用 DCSettingsManager 实例(通常是共享单例实例)上的 configure 方法。 此方法接受一个闭包,该闭包返回一个 DCSettingGroup 实例数组。 每个 DCSettingGroup 可以包含多个 DCSetting 实例。

这是一个如何配置设置的示例

DCSettingsManager.shared.configure {
    DCSettingGroup("General") {
        DCSetting(key: "showNotifications", defaultValue: true)
        DCSetting(key: "soundEffects", defaultValue: true)
        DCSetting(key: "shemeColor") {
            DCSettingOption(value: "Blue")
            DCSettingOption(value: "Red")
            DCSettingOption(value: "Green")
        }
    }
    .store(.standard)
    DCSettingGroup("Appearance") {
        DCSetting(key: "fontSize", defaultValue: 14)
        DCSetting(key: "fontName", defaultValue: "Helvetica")
    }
}

在配置设置时,您有几个选项可用。 首先,您可以创建 DCSettingGroup 实例来将相关设置分组在一起。 每个 DCSettingGroup 可以具有一个键和一个标签。 该标签用于为组提供一个人类可读的名称。

建议避免为组设置特定的键。

在每个 DCSettingGroup 中,您可以创建 DCSetting 实例来表示单个设置。 每个 DCSetting 都有一个键、一个默认值和一个可选标签。 该键用于唯一标识该设置,而默认值用作该设置的初始值(如果之前未设置任何值)。 该标签用于为设置提供一个人类可读的名称。 如果未提供标签,则将使用键的句子大小写字符串版本作为标签。

注意:DCSetting 默认情况下支持以下类型:BoolIntDoubleStringDateColor (SwiftUI)。 您还可以使用符合 Codable 协议的自定义类型。

除了这些基本属性之外,DCSetting 实例还可以具有其他配置选项。 这些选项使用 DCSettingConfiguration 结构体指定。

DCSettingConfiguration 中可用的选项之一是 options 属性。 此属性允许您指定一个 DCSettingOption 实例数组,该数组表示设置的有效值列表。 每个 DCSettingOption 都有一个值,还可以有一个可选标签和图像。

DCSettingConfiguration 中提供的另一个配置选项是 bounds 属性。 此属性允许您使用 DCValueBounds 实例指定设置的有效值范围。 DCValueBounds 实例具有下限和上限,用于定义有效值的范围。

最后,DCSettingConfiguration 还有一个 step 属性,允许您指定设置的有效值之间的增量。

这是一个示例,展示了如何使用其中一些选项来配置设置。

DCSettingsManager.shared.configure {
    DCSettingGroup(key: "General") {
        DCSetting(key: "themeColor") {
            DCSettingOption(value: "Blue", default: true)
            DCSettingOption(value: "Red")
            DCSettingOption(value: "Green")
        }
        DCSetting(key: "fontSize", defaultValue: 14, lowerBound: 10, upperBound: 20, step: 2)
    }
}

在此示例中,我们为常规设置创建了一个设置组,并添加了两个设置:一个用于主题颜色,另一个用于字体大小。 主题颜色设置有三个选项:蓝色(默认)、红色和绿色。 字体大小设置的默认值为 14,有效值范围为 10 到 20,步长值为 2。

访问设置

配置设置后,您可以使用 DCStoredValue 属性包装器在其他地方访问它们。 这是一个如何从前面的示例中访问 ShowNotifications 设置的示例

@DCStoredValue("ShowNotifications") var showNotifications: Bool

您还可以使用 DCSettingsManagervalue(forKey:) 方法直接访问设置。 这是一个如何执行此操作的示例

let showNotifications = DCSettingsManager.shared.bool(forKey: "ShowNotifications")

后备存储

DCSettings 允许您为每个设置组和单个设置指定要使用的键值存储。 默认情况下,设置使用标准键值存储,该存储由 UserDefaults.standard 支持。 但是,您可以使用 DCSettingGroupDCSetting 的 *store* 属性指定不同的键值存储。

这是一个示例,展示了如何使用由 UserDefaults 实例支持的自定义键值存储,其套件名称为“com.example.myapp”。

DCSettingsManager.shared.configure {
    DCSettingGroup(key: "General") {
        DCSetting(key: "ShowNotifications", defaultValue: true)
    }
    .store(.userDefaults(suiteName: "com.example.myapp"))
}

注意:如果未为设置组指定键值存储,则将使用标准键值存储。

您还可以为单个设置指定自定义键值存储。 这是一个展示如何执行此操作的示例

DCSettingsManager.shared.configure {
    DCSettingGroup(key: "General") {
        DCSetting(key: "ShowNotifications", defaultValue: true, store: .userDefaults(suiteName: "com.example.myapp"))
    }
}

注意:如果您为设置组指定了自定义键值存储,则该组中的所有设置都将使用该键值存储,除非您为单个设置指定了不同的键值存储。

DCSettings 还支持使用 NSUbiquitousKeyValueStore 作为设置的键值存储,这是一个将数据存储在 iCloud 中的键值存储,允许在多个设备之间共享设置。 这是一个展示如何为设置组使用 NSUbiquitousKeyValueStore 的示例

DCSettingsManager.shared.configure {
    DCSettingGroup(key: "General") {
        DCSetting(key: "ShowNotifications", defaultValue: true)
        DCSetting(key: "SoundEffects", defaultValue: true)
    }
    .store(.ubiquitous)
}

DCSettingsView

设置好设置后,您可以使用 DCSettingsView 快速将设置视图添加到您的应用。 此视图显示使用给定的 DCSettingsManager 配置的所有设置组和设置的列表。 您可以创建此视图的一个实例,并像任何其他 SwiftUI 视图一样将其添加到应用的视图层次结构中。

这是一个示例,展示了如何创建和使用 DCSettingsView

struct ContentView: View {
    var body: some View {
        DCSettingsView(filter: .labelled)
    }
}

注意:默认情况下,DCSettingsView 将显示**所有**设置。 如果您只想显示具有标签的设置,则可以将过滤器参数设置为 .labelled

DCSettingsView 有几个自定义选项可用。 例如,您可以指定一个过滤器来包含或排除某些设置组或单个设置。 您还可以提供自定义内容提供程序来控制每个设置的显示方式。

这是一个示例,通过将过滤器传递给 DCSettingsView 初始化程序来指定应排除“General”设置组

struct ContentView: View {
    var body: some View {
        DCSettingsView(filter: .excludeKeys(["General"]))
    }
}

类型

当您使用 DCSettingsView 显示您的设置时,每个设置都将使用适合其值类型的控件呈现给用户。 以下是如何呈现每种值类型的说明

自定义

配置 DCSetting 时,您可以提供几个额外的选项,这些选项会影响设置在 DCSettingsView 中的显示方式。

DCSettingViewProviding

DCSettingViewProviding 是一种协议,允许您为 DCSettingsView 中的单个设置提供自定义视图。 要使用此协议,您需要创建一个符合它的类型并实现 content(for:) 方法。

content(for:) 方法将一个 DCSettable 实例作为其参数,并返回一个可选视图。 如果您从此方法返回一个视图,它将在向用户显示设置时使用。 如果您返回 nil,则将使用该设置的默认视图。

这是一个示例,展示了如何创建自定义 DCSettingViewProviding 类型

struct MySettingViewProvider: DCSettingViewProviding {
    @ViewBuilder func content(for setting: any DCSettable) -> some View {
        if setting.key == "ShowNotifications", let concreteSetting = setting as? DCSetting<Bool> {
            Toggle("Show Notifications", isOn: concreteSetting.valueBinding())
        }
    }
}

在此示例中,我们创建了一个符合 DCSettingViewProviding 协议的 MySettingViewProvider 类型。 在我们对 content(for:) 方法的实现中,我们检查设置的键是否为“ShowNotifications”并且是具有 Bool 值类型的设置。 如果是,我们将返回该设置的自定义切换视图。 对于所有其他设置,我们返回 nil,这意味着将使用这些设置的默认视图。

创建自定义 DCSettingViewProviding 类型后,您可以将它的一个实例传递给 DCSettingsView 初始化程序来使用它。 这是一个展示如何执行此操作的示例

struct ContentView: View {
    var body: some View {
        DCSettingsView(contentProvider: MySettingViewProvider())
    }
}

贡献

在使用 DCSettings 之前,建议您花几分钟时间熟悉其文档。 由于这是一个非常年轻的项目,因此可能有一些粗糙的边缘。 请发送您遇到的任何问题的反馈。

根据范围和方向,非常欢迎您的贡献。 如果您希望进行更改,请打开一个 Pull Request - 即使只是建议更改的草稿 - 我们可以进一步讨论它。