业界举例:
① 招行的后台运行时长选择列表
② 概念画板的Licenses展示
③ 搜狗输入法
④ outlook默认邮箱
⑤ 微博
Settings Bundle 实际上是Root.plist配置文件与NSUserDefault相关联的
使用之前需要先创建这样一个文件,target里找到settings bundle直接创建就行
然后需要在代码里添加注册代码
//MARK: - 注册setting bundle
- (void)registerDefaultsFromSettingsBundle{
NSString *settingsBundle = [[NSBundle mainBundle] pathForResource:@"Settings" ofType:@"bundle"];
if(!settingsBundle) {
NSLog(@"Could not find Settings.bundle");
return;
}
NSDictionary *settings = [NSDictionary dictionaryWithContentsOfFile:[settingsBundle stringByAppendingPathComponent:@"Root.plist"]];
NSArray *preferences = [settings objectForKey:@"PreferenceSpecifiers"];
NSMutableDictionary *defaultsToRegister = [[NSMutableDictionary alloc] initWithCapacity:[preferences count]];
for(NSDictionary *prefSpecification in preferences) {
NSString *key = [prefSpecification objectForKey:@"Key"];
if(key) {
[defaultsToRegister setObject:[prefSpecification objectForKey:@"DefaultValue"] forKey:key];
}
}
[[NSUserDefaults standardUserDefaults] registerDefaults:defaultsToRegister];
}
在-application:didFinishLaunchingWithOptions:
方法里调用即可实现配置的同步 (也可在进入前台时调用)
Group
Key | Value type | Value |
---|---|---|
Type (required) |
String | 类似, PSGroupSpecifier 这个值是固定写法 |
Title (localizable) |
String | 标题,类似tableview的组头 |
FooterText (localizable) |
String | 类似tableview的footer |
SupportedUserInterfaceIdioms |
Array | 标识平台,支持多个平台差异化,可以创建多个类似文件,该字段作为标识 |
示例:
<dict>
<key>Type</key>
<string>PSGroupSpecifier</string>
<key>Title</key>
<string>header标题文字</string>
<key>FooterText</key>
<string>footer文字</string>
</dict>
Title和FooterText可以不填内容可用于分隔空间
<dict>
<key>Type</key>
<string>PSGroupSpecifier</string>
<key>Title</key>
<string></string>
</dict>
Multi Value Element
列表选择,只有单选模式,分为两个层级,外层显示默认选项或者已选选项,内层显示列表页
Key | Value type | Description |
---|---|---|
Type (required) |
String | 类似 PSMultiValueSpecifier 固定写法. |
Title (required, localizable) |
String | 标题 |
Key (required) |
String | 关联userdefault偏好设置保存的值,这就是key |
DefaultValue (required) |
Any | 默认值(必填) |
Values (required) |
Array | 列表值数组,选取的标题对应的值 |
Titles (required, localizable) |
Array | 列表标题数组 |
ShortTitles (localizable) |
Array | 简短标题用于选中时同时显示标题和值(没有实际操作过) |
SupportedUserInterfaceIdioms |
Array | 平台标识 |
DisplaySortedByTitle |
Boolean | 标题排序显示 |
示例:
<dict>
<key>Type</key>
<string>PSMultiValueSpecifier</string>
<key>DisplaySortedByTitle</key>
<true/>
<key>Title</key>
<string>环境切换</string>
<key>Key</key>
<string>default-env</string>
<key>DefaultValue</key>
<string>stg1</string>
<key>Values</key>
<array>
<string>prd</string>
<string>stg1</string>
<string>stg2</string>
<string>stg3</string>
<string>stg4</string>
</array>
<key>Titles</key>
<array>
<string>prd</string>
<string>stg1</string>
<string>stg2</string>
<string>stg3</string>
<string>stg4</string>
</array>
</dict>
RadioGroup
相对于Multi Value Element
只是少了一层级的包装,扁平化的显示这个列表而已
Key | Value type | Value |
---|---|---|
Type (required) |
String | 类型PSRadioGroupSpecifier 固定写法 |
Title (localizable) |
String | 标题. |
FooterText (localizable) |
String | footer组尾 |
Key (required) |
String | 偏好设置关联的key. |
DefaultValue (required) |
Any | 默认值 |
Values (required) |
Array | 值数组 |
Titles (required, localizable) |
Array | 标题数组 |
SupportedUserInterfaceIdioms |
Array | 平台标识 |
DisplaySortedByTitle |
Boolean | 按标题排序显示 |
示例:
<dict>
<key>Type</key>
<string>PSRadioGroupSpecifier</string>
<key>DisplaySortedByTitle</key>
<true/>
<key>Title</key>
<string>RadioGroup列表展示</string>
<key>FooterText</key>
<string>这是底部说明文字</string>
<key>Key</key>
<string>show-radio-group</string>
<key>DefaultValue</key>
<string>stg1</string>
<key>Values</key>
<array>
<string>prd</string>
<string>stg1</string>
<string>stg2</string>
<string>stg3</string>
<string>stg4</string>
</array>
<key>Titles</key>
<array>
<string>prd</string>
<string>stg1</string>
<string>stg2</string>
<string>stg3</string>
<string>stg4</string>
</array>
</dict>
Toggle Switch Element
开关
Key | Value type | Value |
---|---|---|
Type (required) |
String | 开关类型PSToggleSwitchSpecifier 固定写法 |
Title (required, localizable) |
String | 标题 |
Key (required) |
String | 偏好设置关联的key. |
DefaultValue (required) |
Any | 默认值. |
TrueValue |
Any | True关联的值,可以是数字,日期,字符串,二进制, 如果不设置则默认为布尔值类型 |
FalseValue |
Any | False关联的值,可以是数字,日期,字符串,二进制, 如果不设置则默认为布尔值类型 |
SupportedUserInterfaceIdioms |
Array | 平台标识 |
示例:
<dict>
<key>Type</key>
<string>PSToggleSwitchSpecifier</string>
<key>Key</key>
<string>demo-click-effect</string>
<key>Title</key>
<string>点击效果</string>
<key>DefaultValue</key>
<string>NO</string>
</dict>
Slider Element
进度滑块
Key | Value type | Value |
---|---|---|
Type |
String | 类型PSSliderSpecifier 固定写法 |
Key (required) |
String | 关联的key |
DefaultValue (required) |
Real | 默认值 (浮点或者整数) |
MinimumValue (required) |
Real | 最小值 |
MaximumValue (required) |
Real | 最大值 |
MinimumValueImage |
String | 最小值图片, 21x 21 px |
MaximumValueImage |
String | 最小值图片, 21x21 px |
SupportedUserInterfaceIdioms |
Array | 平台标识 |
示例:
<dict>
<key>Type</key>
<string>PSSliderSpecifier</string>
<key>MinimumValueImage</key>
<!-- 最小值图片名 -->
<string>left</string>
<key>MaximumValueImage</key>
<!-- 最大值图片名 -->
<string>right</string>
<key>Key</key>
<string>progress-bar</string>
<key>DefaultValue</key>
<real>0.5</real>
<key>MinimumValue</key>
<integer>0</integer>
<key>MaximumValue</key>
<integer>1</integer>
</dict>
Text Field Element
Key | Value type | Value |
---|---|---|
Type (required) |
String | 类型PSTextFieldSpecifier`固定写法 |
Title (localizable) |
String | 标题 |
Key (required) |
String | 偏好设置关联的key. |
DefaultValue |
String | 默认值 |
IsSecure |
Boolean | 是否为安全输入 |
KeyboardType |
String | 键盘类型 |
AutocapitalizationType |
String | 自动首字母大小写模式 |
AutocorrectionType |
String | 自动纠正类型 |
SupportedUserInterfaceIdioms |
Array | 支持平台 |
不知道苹果故意为之还是bug,输入框缺少placeholder字段,官方文档也未提及
示例:
<dict>
<key>Type</key>
<string>PSTextFieldSpecifier</string>
<key>Title</key>
<string>密码</string>
<key>DefaultValue</key>
<string>123456</string>
<key>IsSecure</key>
<true/>
<key>KeyboardType</key>
<string>NumbersAndPunctuation</string>
<key>AutocapitalizationType</key>
<string>None</string>
<key>AutocorrectionType</key>
<string>No</string>
<key>Key</key>
<string>pwd-demo-xxx</string>
</dict>
Title Element
标题节点,无事件交互纯信息展示的一个cell
Key | Value type | Description |
---|---|---|
Type (required) |
String | 类型 PSTitleValueSpecifier 固定写法 |
Title (localizable) |
String | 标题 |
Key (required) |
String | 关联的key |
DefaultValue (required) |
String | 默认值 |
Values |
Array | 本地化展示的值 |
Titles (localizable) |
Array | 本地化展示的标题 |
SupportedUserInterfaceIdioms |
Array | 支持平台标识 |
示例:
<dict>
<key>Type</key>
<string>PSTitleValueSpecifier</string>
<key>Title</key>
<string>君不见</string>
<key>DefaultValue</key>
<string>黄河之水天上来</string>
<key>Key</key>
<string>cell-display</string>
</dict>
Child Pane Element
子面板节点
需基于父节点或者根节点来实现,写法与根节点没差别,只是需要在根节点配置入口,指定子节点plist文件的名称
Key | Type | Value |
---|---|---|
Type (required) |
String | 类型PSChildPaneSpecifier 固定写法 |
Title (required, localizable) |
String | 标题 |
File (required) |
String | 创建的文件,放到bundle里,填写字段时无需后缀名 |
SupportedUserInterfaceIdioms |
Array | 平台标识 |
示例:
创建了一个child.plist的文件:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>StringsTable</key>
<string>child</string>
<key>PreferenceSpecifiers</key>
<array>
<dict>
<key>Type</key>
<string>PSGroupSpecifier</string>
<key>Title</key>
<string>这是子面板组头标题</string>
<key>FooterText</key>
<string>子面板菜单尾部说明文字</string>
</dict>
<dict>
<key>Type</key>
<string>PSMultiValueSpecifier</string>
<key>DisplaySortedByTitle</key>
<true/>
<key>Title</key>
<string>列表展示</string>
<key>Key</key>
<string>sssss</string>
<key>DefaultValue</key>
<string>stg1</string>
<key>Values</key>
<array>
<string>prd</string>
<string>stg1</string>
<string>stg2</string>
<string>stg3</string>
<string>stg4</string>
</array>
<key>Titles</key>
<array>
<string>prd</string>
<string>stg1</string>
<string>stg2</string>
<string>stg3</string>
<string>stg4</string>
</array>
</dict>
<dict>
<key>Type</key>
<string>PSChildPaneSpecifier</string>
<key>Title</key>
<string>详情信息展示</string>
<key>File</key>
<string>detail</string>
</dict>
</array>
</dict>
</plist>
child.plist又关联了一个detail.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>StringsTable</key>
<string>detail</string>
<key>PreferenceSpecifiers</key>
<array>
<dict>
<key>Type</key>
<string>PSGroupSpecifier</string>
<key>Title</key>
<string></string>
<key>FooterText</key>
<string>The name of the schema file to load. (This file must be a property list file.) The string you specify for this key should not contain path information or the .plist filename extension of your schema file. The Settings app looks in the top-level of your settings bundle for a .plist file with the specified name. For example, if you had a MyPrefs.plist file, you would assign the value MyPrefs to this key. This key is required.</string>
</dict>
</array>
</dict>
</plist>
概念画板.app 就是这种实现,把开源的一些三方库的LICENSES全部展示在settings bundle里,就是用的子面板+group
Root.plist里关联只需如下即可:
<dict>
<key>Type</key>
<string>PSChildPaneSpecifier</string>
<key>Title</key>
<string>更多信息</string>
<key>File</key>
<string>child</string>
</dict>
把以上plist转成json来看就比较直观了(plist和JSON互转工具,关注公众号"飙码人生Coding" 回复关键字 20220321 领取)
Root.json
{
"StringsTable": "Root",
"PreferenceSpecifiers": [
{
"Type": "PSTitleValueSpecifier",
"Title": "君不见",
"Key": "cell-display",
"DefaultValue": "黄河之水天上来"
},
{
"DefaultValue": "123456",
"KeyboardType": "NumbersAndPunctuation",
"AutocorrectionType": "No",
"Key": "pwd-demo-xxx",
"Type": "PSTextFieldSpecifier",
"Title": "密码",
"IsSecure": true,
"AutocapitalizationType": "None"
},
{
"MaximumValue": 1,
"DefaultValue": 0.5,
"Key": "progress-bar",
"MaximumValueImage": "right",
"MinimumValue": 0,
"Type": "PSSliderSpecifier",
"MinimumValueImage": "left"
},
{
"Title": "iOS SDK Demo",
"Type": "PSGroupSpecifier",
"FooterText": "与demo里的配置一一对应且同步,这里仅是提供一个可操作的面板菜单而已"
},
{
"Titles": [
"prd",
"stg1",
"stg2",
"stg3",
"stg4"
],
"DefaultValue": "stg1",
"Values": [
"prd",
"stg1",
"stg2",
"stg3",
"stg4"
],
"Key": "default-env",
"Type": "PSMultiValueSpecifier",
"Title": "环境切换",
"DisplaySortedByTitle": true
},
{
"Type": "PSToggleSwitchSpecifier",
"Title": "埋点开关",
"Key": "track-enable",
"DefaultValue": "1.0.0"
},
{
"Type": "PSToggleSwitchSpecifier",
"Title": "点击效果",
"Key": "demo-click-effect",
"DefaultValue": "NO"
},
{
"Type": "PSToggleSwitchSpecifier",
"Title": "遮罩蒙层",
"Key": "shield-effect",
"DefaultValue": "NO"
},
{
"Type": "PSToggleSwitchSpecifier",
"Title": "异常捕获(保活一次)",
"Key": "sw-exception-catch",
"DefaultValue": "NO"
},
{
"Type": "PSToggleSwitchSpecifier",
"Title": "录屏结束展示性能图表",
"Key": "sw-echarts-display",
"DefaultValue": "NO"
},
{
"Title": "",
"Type": "PSGroupSpecifier"
},
{
"Type": "PSTitleValueSpecifier",
"Title": "SDK版本",
"Key": "SDKVersion",
"DefaultValue": "1.0.0"
},
{
"Title": "<!-- 这是一条分割线 -->",
"Type": "PSGroupSpecifier"
},
{
"Title": "以下是DC配置的环境json文本",
"Type": "PSGroupSpecifier",
"FooterText": "敏感信息已和谐"
},
{
"Title": "",
"Type": "PSGroupSpecifier"
},
{
"Title": "更多信息",
"Type": "PSChildPaneSpecifier",
"File": "child"
}
]
}
child.json
{
"StringsTable": "child",
"PreferenceSpecifiers": [
{
"Title": "这是子面板组头标题",
"Type": "PSGroupSpecifier",
"FooterText": "子面板菜单尾部说明文字"
},
{
"Titles": [
"prd",
"stg1",
"stg2",
"stg3",
"stg4"
],
"DefaultValue": "stg1",
"Values": [
"prd",
"stg1",
"stg2",
"stg3",
"stg4"
],
"Key": "sssss",
"Type": "PSMultiValueSpecifier",
"Title": "列表展示",
"DisplaySortedByTitle": true
},
{
"Title": "详情信息展示",
"Type": "PSChildPaneSpecifier",
"File": "detail"
},
{
"Values": [
"prd",
"stg1",
"stg2",
"stg3",
"stg4"
],
"DefaultValue": "stg1",
"Titles": [
"prd",
"stg1",
"stg2",
"stg3",
"stg4"
],
"Key": "show-radio-group",
"Type": "PSRadioGroupSpecifier",
"Title": "RadioGroup列表展示",
"FooterText": "这是底部说明文字",
"DisplaySortedByTitle": true
}
]
}
detail.json
{
"StringsTable": "detail",
"PreferenceSpecifiers": [
{
"Title": "",
"Type": "PSGroupSpecifier",
"FooterText": "The name of the schema file to load. (This file must be a property list file.) The string you specify for this key should not contain path information or the .plist filename extension of your schema file. The Settings app looks in the top-level of your settings bundle for a .plist file with the specified name. For example, if you had a MyPrefs.plist file, you would assign the value MyPrefs to this key. This key is required."
}
]
}