在传统的桌面应用程序中,偏好设置是一些专门面向应用程序的设置,用于配置应用程序的行为和外观。iPhone OS也支持应用程序偏好设置,但并不将它作为应用程序整体的一部分。在iPhone OS上,应用程序级别的偏好设置并不由各个程序本身的定制界面来显示,而是由系统提供的Settings程序统一显示。
为了将定制的应用程序偏好设置集成到Settings程序中,您必须在应用程序包的顶级目录中包含一个特殊格式的Settings程序包,由它负责将应用程序的偏好设置信息提供给Settings程序,而Settings程序则负责对其进行显示,并将用户提供的值写入偏好设置数据库。在运行时,您的应用程序可以通过标准的API取得这些偏好设置的值。本章的下面部分将描述Settings程序包的格式,以及用于取得偏好设置值的API。
偏好设置的指导原则
将偏好设置加入到Settings程序的做法最适合于效率工具类型的应用程序,以及偏好设置值配置完成后很少再改变的程序。Mail程序就是一个例子,它通过这种形式的偏好设置来存储用户账户信息及消息检查设置。由于Settings程序可以按层次进行显示,所以当您有大量的偏好设置时,通过Settings程序来进行操作也是比较合适的,在自己的应用程序中提供同样的偏好设置集合可能需要太多屏幕,而且可能造成用户的混淆。
当您的应用程序只需要少数的选项,或者用户需要经常改变这些选项时,应该认真考虑是否用Settings程序来管理。举例来说,工具程序更适合在主视图的背面提供定制的配置选项,即在视图上通过一个特殊的控件翻转视图,显示应用程序的选项,再通过另一个控件将视图翻转回来。对于简单的应用程序,这种方式使用户可以立即访问应用程序选项,比使用Settings程序方便得多。
对于游戏和其它全屏程序的预置,可以使用Settings程序或自行实现定制的屏幕。定制屏幕通常更适合游戏程序,因为偏好设置可以处理为游戏设置的一部分。当然,您也可以使用Settings程序,如果您认为那样对游戏的使用流程更好的话。
请注意:永远不要使偏好设置同时存在于Setting程序和自定义的应用程序屏幕上。举例来说,如果工具类应用程序在主视图的背面有偏好设置,则在Settings程序中就不应该再有可配置的设置。如果您的应用程序需要进行偏好设置,则请仅选择和使用一种方案。
偏好设置的接口
Settings程序实现了一组有层次的页面,用于访问应用程序的偏好设置。Settings程序的主视图显示了可以进行偏好设置的系统程序及第三方应用程序,用户选择一个第三方程序后会进入该程序的偏好设置页面。
每个应用程序都至少有一个偏好设置页面,我们称为主页面。如果您的应用程序只有少数几个偏好设置,则一个主页面可能就够了。然而,如果偏好设置太多,在主页面上放不下,也可以加入更多页面。这些额外的页面就成为主页面的子页面,用户通过轻触特定类型的偏好设置来访问这些页面。
您显示的每一个偏好设置都必须具有特定的类型。偏好设置的类型定义了Settings程序如何对其进行显示。大多数偏好设置类型都和某种类型的、用于进行设置的控件相关联,而另外一些类型则提供一种偏好设置的组织方式。表9-1列出了Settings程序支持的各种元素类型,以及如何用这些类型来实现自己的偏好设置页面。
元素类型 |
描述 |
---|---|
文本框 |
文本框类型显示一个可选的标题和一个可编辑的文本输入框,适用于需要用户输入自定义字符串的偏好设置。 这个类型的键是 |
标题 |
标题类型显示一个只读的字符串,适用于显示只读字符串的偏好设置(如果偏好设置包含隐含或非直接的值,这个类型可以将可能的值映射为字符串)。 这个类型的键是 |
拨动开关 |
拨动开关类型显示一个ON/OFF拨动按键,适用于配置值为二选一的偏好设置。这个类型通常用于表示包含布尔值的偏好设置,但也可以用于表示包含非布尔值的偏好设置。 这个类型的键是 |
滑块 |
滑块类型显示一个滑块控件,适用于值为一个范围的偏好设置。这个类型的值是一个实数,值的最小和最大值由您来指定。 这个类型的键是 |
值列表 |
值列表类型使用户可以从一个值的列表中选择其一,适用于支持多个互斥值的偏好设置,这些值的类型可以是任意的。 这个类型的键是 |
组 |
组类型使您可以将几组不同的偏好设置组织到一个页面上。组类型并不表示一个可配置的偏好设置,而只是包含一个标题字符串,显示在一或多个可配置的偏好设置之前。 这个类型的键是 |
子页面 |
子页面类型使用户可以访问新的偏好设置页面,适用于实现多层次的偏好设置。有关如何配置和使用这个类型的更多信息,请参见“多层次的偏好设置” 。这个类型的键是 |
各种偏好设置类型的详细格式信息请参见Settings程序的结构参考。如果要了解如何创建和编辑Setting程序的页面文件,则请参见“添加和修改Settings程序包”部分。
Settings程序包
在iPhone OS中,开发者通过一种特殊的Settings程序包来指定应用程序的偏好设置,这种程序包命名为
Settings.bundle
,驻留在应用程序程序包的顶级目录上。该程序包中包含一或多个Settings页面文件,用于定义应用程序偏好设置的详细信息;还可以包含显示偏好设置需要的其它支持文件,比如图像或本地化文件。表9-2列出了一个典型Settings程序包的内容。
项目名称 |
描述 |
---|---|
|
这个Settings页面文件包含根页面的偏好设置,它的内容在“Settings页面文件的格式” 部分有更详细的描述。 |
其它 |
如果您需要通过多个子面板来构建一组有层次结构的偏好设置,则每个子面板的内容都分别存储在不同的Settings页面文件中。您需要负责命名这些文件,并将它们关联到正确的子面板上。 |
一或多个 |
这些目录用于存储Settings页面文件的本地化字符串资源。每个目录都包含一个字符串文件,文件的标题在Settings页面中指定。这些字符串文件为偏好设置提供可以直接显示给用户的本地化内容。 |
其它图像 |
如果您使用滑块控件,则可以将滑块的图像存储在程序包的顶级目录下。 |
除了Settings程序包之外,应用程序的程序包中还可以包含应用程序设置的定制图标。如果应用程序包的顶级目录含有名为
Icon-Settings.png
的文件,则该文件包含的图标会被Settings程序用于标识应用程序的偏好设置。如果不存在这样的文件,Settings程序会转而采用应用程序的图标文件(缺省为
Icon.png
),并进行必要的缩放处理。您的
Icon-Settings.png
文件必须是29 x 29像素的图像。
在启动时,Settings程序会检查每一个定制的应用程序是否包含Settings程序包,并对其进行装载,然后将相应的应用程序名称和图标显示在Settings程序的主页面上。当用户轻触您的应用程序对应的行时,Settings程序会装载Settings程序包的
Root.plist
页面文件,并根据该文件的定义显示应用程序的主设置页面。
除了装载程序包的
Root.plist
页面文件之外,Settings程序还会在必要时装载与该文件相关联的语言资源。每个Settings页面文件都可以有一个关联的
.strings
文件,用于包含可见字符串的本地化值。在准备显示偏好设置信息时,Settings程序会根据用户偏好的语言来寻找相应的字符串资源,并在显示之前替换偏好设置页面中对应的内容。
Settings页面文件的格式
Settings程序包中的每个Settings页面文件都以iPhone设置属性列表的文件格式(它是一种结构化的文件格式)进行存储。编辑Settings页面文件的最简单方法,就是使用Xcode内置的编辑器组件,具体做法请参见“为Settings页面的编辑做准备”部分;您也可以用属性列表编辑器程序来进行编辑,它是Xcode的工具之一。
请注意:在连编时,Xcode会将工程中基于XML的属性文件自动转换为二进制格式,转换过程是连编时自动完成的,目的是节省磁盘空间。
每个Settings页面文件的根元素都包含表9-3列出的键。事实上,只有一个键是必须的,但我们推荐包含所有的两个键。
键 |
类型 |
值 |
---|---|---|
|
数组 |
这个键的值是一个字典数组,数组中的每个字典都包含一个偏好设置元素的信息。有关元素类型列表请参见表9-1,与元素类型相关联的键的描述,则请参见Settings程序的结构参考。 |
|
字符串 |
和这个页面文件相关联的字符串文件的名称。程序包中专用于语言的工程目录应该包含这个字符串文件的一个拷贝(带有相应的本地化字符串)。如果您没有包含这个键,则表示页面文件中的字符串没有被本地化。有关如何使用这些字符串的信息,请参见“本地化资源”部分。 |
多层次的偏好设置
如果您希望以一定的层次结构组织偏好设置,则您定义的每个页面都必须有它自己的
.plist
文件,每个
.plist
文件包含一组仅在该页面显示的偏好设置。应用程序偏好设置的主页面总是存储在
Root.plist
文件中,其它页面则可以根据自己的喜好进行命名。
为了建立父子页面之间的连接,您需要在父页面中包含一个子面板元素。子面板元素负责占据一行,在用户触击时显示一个新的设置Settings页面。子面板元素的
File
键标识一个
.plist
文件的名称,该文件负责定义子页面的内容;
Title
键则标识子页面的标题,该标题也作为子面板元素行的文本。Settings程序会自动提供子页面的漫游控制,使用户可以回到父页面。
图9-1展示了一组多层次的页面是如何工作的。图的左边显示了
.plist
文件,右边则显示各个页面之间的关系。
图9-1 用子面板组织偏好设置
![应用程序偏好设置 - hackbin - 一个人的天空 Organizing preferences using child panes](http://www.apple.com.cn/developer/iphone/library/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/Art/preferences.jpg)
有关子面板元素及其关联键的更多信息,请参见Settings程序的结构参考。
本地化资源
由于偏好设置中包含用户可见的字符串,所以您应该在Settings程序包中为那些字符串提供本地化版本。对于程序包支持的每种本地化语言,偏好设置页面都可以有一个
.strings
文件与之对应。当Settings程序碰到一个支持本地化的键时,就会在相应本地化版本的
.strings
文件中寻找匹配的键,如果找到了,就显示与之关联的值。
在寻找诸如
.strings
文件这样的本地化资源时,Settings程序遵循和Mac OS X程序一样的规则,即首先寻找与用户偏好语言相匹配的本地化资源,如果该版本的资源不存在,再选择缺省语言的版本。
有关字符串文件的格式、语言工程目录、以及如何从程序包中取得特定语言资源的相关信息,请参见国际化编程主题。
添加和修改Settings程序包
Xcode提供了一个为当前工程添加Settings程序包的模板。缺省的Settings程序包中包含一个
Root.plist
文件,以及一个用于存放本地化资源的缺省语言目录。您可以在这个基础上进行扩展,加入Settings程序包需要的其它属性列表文件和资源。
添加Settings程序包
通过如下步骤可以为您的Xcode工程添加一个Settings程序包:
选择File > New File.
选择iPhone OS > Settings > Settings Bundle template.
将文件命名为
Settings.bundle
.
除了在工程中添加一个新的Settings程序包之外,Xcode还自动将该程序包加入到应用程序目标的Copy Bundle Resources连编阶段中。这样,您需要做的就只是修改Settings程序包中的属性列表文件和添加其它资源了。
新添加的
Settings.bundle
程序包具有如下结构:
Settings.bundle/
|
Root.plist
|
en.lproj/
|
Root.strings
|
为Settings页面的编辑做准备
用Settings程序包模板创建Settings程序包之后,您可以将结构文件(schema file)的内容进行格式化,使它们更容易编辑。下面的步骤向您展示如何格式化Settings程序包的
Root.plist
文件,这些步骤同样适用于您创建的其它结构文件。
显示Settings程序包中
Root.plist
文件的内容。
在Groups & Files列表中,展开
Settings.bundle
,查看程序包的内容。
选择
Root.plist
文件,其内容就会显示在Detail视图中.
在Detail视图中,选择
Root.plist
文件的Root键。
选择View > Property List Type > iPhone Settings plist.
这个命令会将Detail视图中的属性列表内容进行格式化。Xcode不是直接显示属性列表的键和值,而是将它们显示为可读的字符串(如图9-2所示),使我们更加易于理解和编辑文件的内容。
图9-2 格式化过的
Root.plist
文件内容
![应用程序偏好设置 - hackbin - 一个人的天空 Formatted contents of the Root.plist file](http://www.apple.com.cn/developer/iphone/library/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/Art/settings_root_template.jpg)
配置一个Settings页面:一个教程
这个部分包含一个教程,目的是向您展示如果配置一个Settings页面,使它显示您需要的内容。教程的目标是创建一个像图9-2这样的页面,如果您之前还没有为自己的工程创建Settings程序包,则在执行下面这些步骤之前,应该按照“为Settings页面的编辑做好准备”部分的描述进行准备。
图9-3 一个根Settings页面
![应用程序偏好设置 - hackbin - 一个人的天空 A root Settings page](http://www.apple.com.cn/developer/iphone/library/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/Art/settings_myapp.jpg)
将Settings Page Title 键的值改为您的应用程序名称。
双击
YOUR_PROJECT_NAME
文本并将它改为
MyApp
。
展开Preference Items键,显示模板包含的缺省项目。
将
Item 1
的标题改为
Sound
:
展开
Preference Items
的
Item 1
。
将
Title
键的值由
Group
改为
Sound
。
保持
Type
键的值不变,仍然为
Group
。
为新命名的Sound组创建第一个拨动开关。
选中
Preference Items
的
Item 3
项,并选择Edit > Cut命令。
选中
Item 1
,并选择Edit > Paste命令(这会将拨动开关项移到文本框项的前面)。
展开拨动开关项,显示其配置键。
将
Title
键的值改为
Play Sounds
。
将
Identifier
键的值改为
play_sounds_preference
。现在,这个项目的配置应该如下图所示:
![应用程序偏好设置 - hackbin - 一个人的天空 Changing the value of the identifier property](http://www.apple.com.cn/developer/iphone/library/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/Art/settings_myapp_playsounds.jpg)
为Sound 组创建第二个拨动开关。
选中
Item 2
(即Play Sounds拨动开关)。
选择Edit > Copy命令。
选择Edit >Paste命令,将拨动开关的拷贝放到第一个的下面。
展开新的拨动开关项,显示其配置键。
将其
Title
键的值改为
3D Sound
。
将其
Identifier
键的值改为
3D_sound_preference
。
现在,您已经完成了第一组设置,可以开始创建User Info组了。
将
Item 4
改为Group类型的元素,并命名为
User Info
。
在
Preferences Items
中点击
Item 4
,显示一个项目类型列表的下拉菜单。
从下拉菜单中,选择
Group
元素类型。
![应用程序偏好设置 - hackbin - 一个人的天空 Configuring a group item](http://www.apple.com.cn/developer/iphone/library/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/Art/settings_myapp_userinfo.jpg)
展开
Item 4
的内容。
将
Title
键的值设置为
User Info
。
创建Name域。
选择Preferences Item中的
Item 5
。
使用下拉菜单,将其类型改为
Text Field
。
将
Title
键的值改为
User Info
。
将
Identifier
键的值改为
user_name
。
合上展开按键,隐藏这个项目的内容。
创建Experience Level设置。
选择
Item 5
并点击加号(+)键(或者按下回车键),创建一个新的项目。
点击这个新创建的项目,将其类型设置为
Multi Value
。
展开项目的内容,将其标题设置为
Experience Level
,标识设置为
experience_preference
,缺省值设置为
0
。
选中Default Value键,点击加号键加入一个
Titles
数组。
通过展开键打开
Titles
数组,点击表格右侧的项目按键。点击这个键可以为
Titles
添加一个新的子项目。
选中新添加的子项目,点击两次加号键,创建总共三个子项目。
将子项目的值设置为
Beginner
、
Expert
、和
Master
。
再次选择
Titles
键,点击其展开键,将子项目隐藏起来。
点击加号键,创建
Values
数组。
在
Values
数组中加入三个子项目,将它们的值分别设置为
0
、
1
、和
2
。
点击
Item 6
的展开按键,隐藏其内容。
添加设置页面的最好一组。
创建一个新项目,将其类型设置为
Group
,标题设置为
Gravity
。
再次创建一个新项目,将其类型设置为
Slider
,标识设置为
gravity_preference
,缺省值设置为
1
,最大值设置为
2
。
创建额外的Settings页面文件
Settings程序包模板包含一个
Root.plist
文件,用于定义应用程序的顶级Settings页面。您如果要定义额外的Settings页面,必须在Settings程序包中加入额外的属性列表文件,您可以在Finder或Xcode中进行添加。
在Xcode中为Settings程序包添加属性列表的步骤如下:
在Groups & Files面板中,打开Settings程序包,选中
Root.plist
文件。
选择File > New命令。
选择Other > Property List命令。
选中新生成的文件,并选择View > Property List Type > iPhone Settings plist命令,将它配置为一个设置文件。
往Settings程序包加入新的Settings页面之后,就可以按照“配置一个Settings页面:一个教程”部分描述的那样,在页面中显示设置。您必须通过一个子面板元素对其进行引用,详情请参见“多层次的偏好设置”部分的描述。
访问您的偏好设置
iPhone应用程序可以通过Foundation或者Core Foundation框架来读写偏好设置的值。在Foundation框架中,您可以通过
NSUserDefaults
类来读写偏好设置的值;而在Core Foundation框架中,您则可以使用几个与偏好设置相关的函数。
程序清单9-1展示一个如何在应用程序中读取偏好设置的简单实例,例子中通过
NSUserDefaults
类取得一个在“配置一个Settings页面:一个教程”部分中创建的偏好设置值,并将它赋值给应用程序的一个实例变量。
程序清单9-1 访问应用程序偏好设置的值
- (void)applicationDidFinishLaunching:(UIApplication *)application
|
{
|
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
|
[self setShouldPlaySounds:[defaults boolForKey:play_sounds_preference]];
|
|
// Finish app initialization...
|
}
|
有关
NSUserDefaults
类中用于读写偏好设置值的方法的更多信息,请参见NSUserDefaults类参考;有关读写偏好设置的Core Foundation函数,请参见偏好设置工具参考。
在仿真器中调试应用程序的偏好设置
在运行您的应用程序时,iPhone Simulator会将所有偏好设置的值保存在
~/Library/Application Support/iPhone Simulator/User/Applications/
<APP_ID>
/Library/Preferences
目录下,这里的<APP_ID>是一个由程序生成的目录名,iPhone OS用它来标识您的应用程序。
每次重新安装应用程序时,iPhone OS都会执行一次干净的安装,将之前所有的偏好设置删除。换句话说,在Xcode中连编或运行应用程序会导致老版本的所有内容被新版本所代替。如果您要测试应用程序在两次运行之间偏好设置发生的变化,则必须直接从仿真器界面上运行,而不应该通过Xcode运行。