iOS Programming NSUserDefaults
iOS Programming NSUserDefaults
When you start an app for the first time, it uses its factory settings. As you use it, a good app learns your preferences. Where are your preferences stored? Inside each app bundle there is a plist that holds the user's preferences. As a developer, you will access this plist using the NSUserDefaults class. The preferences plist for your app can also be edited by the Settings app. To allow this, you create a settings bundle inside your app.
当你第一次开始你的app时,你使用它的工厂设置。当你使用它时,一个好的app 会学习你的preferences.你的preferences 存在哪了呢?在每个app bundle中都有一个plist 保持了user的preference.作为一个developer,你可以通过使用NSUserDefaults类。preferences plist 你的app能够通过setting app 编辑。为了允许这个,你需要创建一个setting bundle 在你的app内。
1 NSUserDefaults
The set of defaults for a user is a collection of key-value pairs. The key is the name of the default, and the value is some data that represents what the user prefers for that key.You ask the shared user defaults object for the value of that key – not unlike getting an object from a dictionary:
对一个用户的defaults 的设置是一个key-value pairs 容器。key 是default的名字,而value是代表饿了用户喜欢什么的数据。你询问shared user defaults 对象为了那个key 的value,很像从一个字典中获取对象。
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSString *greeting = [defaults objectForKey:@"FavoriteGreeting"];
If the user expresses a preference, you can set the value for that key:
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:@"Hello" forKey:@"FavoriteGreeting"];
This value will automatically be stored to the app's preferences plist. Thus, the value must be a plist type: NSArray, NSDictionary, NSString, NSData, NSDate, or NSNumber. If you want to store a non-plist type to the user defaults, you will need to convert it to a plist. Often this is accomplished by archiving the object (or objects) into an NSData, which is a plist.
这些值自动的存入app的preference plist.因此这个value必须是plist type:NSArray,NSDictionary,NSString,NSData,NSDate,or NSNumber.如果你是存的一个non-plist,你需要把它转换为plist。通常这会存档一个对象为NSData。
What if you ask for the value of a preference that has not been set by the user? NSUserDefaults will return the factory settings, the "default default," if you will. These are not stored on the file system, so you need to tell the shared instance of NSUserDefaults what the factory settings are every time your app launches. And you need to do it early in the launch process – before any of your classes try to read the defaults. Typically you will override +initialize on your app delegate:
如果你询问一个preference的值还没有被设置?NSUserDefaults将会返回factory settings ,the "default default",如果你乐意。这些没有存储到文件系统中,所以你需要告诉NSUserDefaults 的shared instance 在你的app 每次启动时要设置什么factory settings .你需要做这些在启动程序的早期:在你的类视图读取defaults之前。一般你回重+initialize 在你的app delegate上。
+ (void)initialize
{
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSDictionary *factorySettings = @{@"FavoriteGreeting": @"Hey!",
@"HoursBetweenMothershipConnection : @2};
[defaults registerDefaults:factorySettings];
}
The class method initialize is called automatically by the Objective-C runtime before the first
instance of that class is created.
这个类方法initialize 在那个类被创建的Objective -C 运行时间自动的被调用。
1.1 Register the factory settings
注册factory Settings
At launch time, the first thing that will happen is the registering of the factory settings. It is considered good style to declare your preference keys as global constants.
启动时,将发生的第一件事就是factory settings 的注册。声明你的preference keys 为一个global constants 是一种好的方式。Open BNRAppDelegate.h and declare two constant global variables:
extern NSString * const BNRNextItemValuePrefsKey;
extern NSString * const BNRNextItemNamePrefsKey;
In BNRAppDelegate.m, define those global variables and use them to register the factory defaults in
+initialize:
NSString * const BNRNextItemValuePrefsKey = @"NextItemValue";
NSString * const BNRNextItemNamePrefsKey = @"NextItemName";
@implementation BNRAppDelegate
+ (void)initialize
{
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSDictionary *factorySettings = @{BNRNextItemValuePrefsKey: @75,
BNRNextItemNamePrefsKey: @"Coffee Cup"};
[defaults registerDefaults:factorySettings];
}
1.2 Read a preference 读取一个preference
When you create a new item in BNRItemStore.m, use the default values. Be sure to import BNRAppDelegate.h at the top of BNRItemStore.m so that the compiler knows about BNRNextItemValuePrefsKey.
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
item.valueInDollars = [defaults integerForKey:BNRNextItemValuePrefsKey];
item.itemName = [defaults objectForKey:BNRNextItemNamePrefsKey];
// Just for fun, list out all the defaults
NSLog(@"defaults = %@", [defaults dictionaryRepresentation]);
Notice the method integerForKey:. It is there as a convenience. It is equivalent to:
item.valueInDollars = [[defaults objectForKey:BNRNextItemValuePrefsKey] intValue];
There are also convenience methods for setting and getting float, double, BOOL, and NSURL values.
1.3 Change a preference
You could create a view controller for editing these preferences. Or, you could create a settings bundle for setting these preferences. Or, you can just try to guess the user's preferences from their actions. For example, if the user sets the value of an item to $100, that may be a good indication that the next item might also be $100. For this exercise, you will do that.
你可以创建一个view controller 来编辑这些preferences.或者,你能创建settings bundle 来设置这些preferences.或者你仅仅视图猜测用户的preferences 从他们的actions。例如,一个用户设置一个item的value是100,那么这是一个很好的indication ,next item 可能也是100。
Open BNRDetailViewController.m and edit the viewWillDisappear: method.
int newValue = [self.valueField.text intValue];
// Is it changed?
if (newValue != item.valueInDollars) {
// Put it in the item item.valueInDollars = newValue;
// Store it as the default value for the next item
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setInteger:newValue forKey:BNRNextItemValuePrefsKey];
item.valueInDollars = [self.valueField.text intValue];
}
Import BNRAppDelegate.h so that the compiler knows about the BNRNextItemValuePrefsKey constant.
Sometimes you will give the user a button that says "Restore factory default", which will remove some defaults from the app's preferences plist.
To remove key-value pairs from your app's preferences plist, NSUserDefaults has a removeObjectForKey: method.
有时候你提供给用户一个button 说重新设置factory default,这将移除所有的default在你的app的preferences plist.移除所有的key-value pairs 从你的app's preferences plist,NSUserDefaults 有一个removeObjectForKey方法。
2 Settings Bundle
Now you are going to create a settings bundle so that the NextItemName preference can be changed from "Coffee Cup" to whatever string the user desires.
现在你将创建一个settings bundle 这样NextItemName preference 能从"Cofffee Cup"到任何用户需要的数据。

These days many designers consider settings bundles to be distasteful and most apps do not include a settings bundle. That said, many apps do have settings bundles, so it is a good idea to know how to make them.
这些天,许多designers 认为setting bundles 为不好的,许多apps 不包括setting bundles .也就是许多apps 有settings bundles ,所以知道怎么用她是有用的。
The bundle is just a directory that holds a plist that describes what controls should appear in this view and what default each control is manipulating.
bundle 仅仅是拥有了一个plist表示了什么控制应该出现在这个view和每个控制默认的操作是什么的一个目录而已。
You will pull the user visible strings (like the label "Default Item Name" in
Figure 26.1) into a strings file that is localized for the user. Those strings files will also be in the settings bundle.
你将把user visible strings 放进一个Strings file用来用户本地化。这些Strings files 也将在settings bundle.
To create a settings bundle inside your app, open Xcode's File menu and choose New → File.... Under the iOS Resources pane, choose Settings Bundle
Accept the default name. Notice that a directory called Settings.bundle has been created in your project directory. It has a Root.plist file and an en.lprog subdirectory.

1.1 Editing the Root.plist
The Root.plist describes what controls will appear in your app's settings pane. It contains an array of dictionaries; each dictionary represents one view (typically a control) that will appear on the pane. Every dictionary must have Type key. Here are the acceptable values for Type:
Root.plist表述了什么控制将显示到你的app's setting pane。它包含了一列dictionaries;每个dictionary 代表了一个view将显示在pane上的。每个dictionary 必须有一个Type key。这里是一些能接受的值:
PSTextFieldSpecifier
a labeled text field 标签文字
PSToggleSwitchSpecifier
a labeled toggle switch 开关标签
PSSliderSpecifier
a slider (not labeled) 滑动
PSRadioGroupSpecifier
a list of radio buttons; only one can be selected 一列radio buttons,只有一个可选
PSMultiValueSpecifier
a table view of possibilities; only one can be selected 一个table view 的可能
PSTitleValueSpecifier
a title for formatting
PSGroupSpecifier
a group for formatting
PSChildPaneSpecifier
lets you move some preferences onto a child pane
让你移动一些preferences 到child pane.

Notice that you have been laying out a user interface using a plist file. When you create a settings bundle, you are not writing any executable code, and you are not creating any view controllers or other objects that you control. The Settings application will read your application's Root.plist and will construct its own view controllers based on the contents of the plist file.
注意到你已经laying out 一个user interface用一个plist file.当你创建一个setting bundle时,你没有写任何可执行的代码,你也没有创建然任何view controller 或者是你控制的其他对象。setting application 会读取你应用的root.plist并构建自己的view controller 基于plist file的内容。
2.2 Localized Root.strings
Inside your settings bundle is an en.lproj which will hold your English strings. You can delete all the key-value pairs and give the title for your text field:
在你的setting bundle是一个en.lproj,它将保持你的English strings.你可以删除所有的key-value pairs 并给定你的text field 的title。
"NextItemName" = "Default Item Name";
One final point: when your defaults are changed (by your own app or the Settings app) an NSUserDefaultsDidChangeNotification will get posted to your application. If you want to respond to changes in the Settings app immediately, register as an observer of this notification.
最后一点是:当你的defaults 发生改变时,NSUserDefaultsDidChangeNotification 将推送给application。如果你想及时的响应setting app 立刻的,注册成为这个notification 的一个观察者。
iOS Programming NSUserDefaults的更多相关文章
- Head First iOS Programming
内部分享: Head First iOS Programming http://www.slideshare.net/tedzhaoxa/head-first-ios-programming-4606 ...
- iOS Programming Recipe 6: Creating a custom UIView using a Nib
iOS Programming Recipe 6: Creating a custom UIView using a Nib JANUARY 7, 2013 BY MIKETT 12 COMMENTS ...
- iOS Programming Autorotation, Popover Controllers, and Modal View Controllers
iOS Programming Autorotation, Popover Controllers, and Modal View Controllers 自动旋转,Popover 控制器,Moda ...
- iOS Programming Controlling Animations 动画
iOS Programming Controlling Animations 动画 The word "animation" is derived from a Latin wor ...
- iOS Programming UIStoryboard 故事板
iOS Programming UIStoryboard In this chapter, you will use a storyboard instead. Storyboards are a f ...
- iOS Programming Localization 本地化
iOS Programming Localization 本地化 Internationalization is making sure your native cultural informatio ...
- iOS Programming State Restoration 状态存储
iOS Programming State Restoration 状态存储 If iOS ever needs more memory and your application is in the ...
- iOS Programming UISplitViewController
iOS Programming UISplitViewController The iPad, on the other hand, has plenty of screen space to pr ...
- iOS Programming UIWebView 2
iOS Programming UIWebView 1 Instances of UIWebView render web content. UIWebView可以显示web content. In ...
随机推荐
- oracle连接串的一种写法
我在.NET项目里访问oracle,向来是规规矩矩地这样写: DATA SOURCE=PDBGZFBC;PASSWORD=test;PERSIST SECURITY INFO=True;USER ID ...
- oracle 10g 实例用localhost无法访问的处理
我在笔记本上安装了一个Oracle10g,安装好了之后,查看E:\oracle\product\10.2.0\db_1\network\ADMIN\tnsnames.ora文件,发现SID对应的IP地 ...
- noteexpress使用指南
软件功能:在写论文时直接调用参考数据并输出正规的格式. (以下简称NE) A.下载安装 下载地址:Note-express - Bibliography Software 选择相应的学校进行下载,相 ...
- caioj1275&&hdu4035: 概率期望值6:迷宫
期望的大难题,%%ZZZ大佬的解释,不得不说这是一道好题(然而膜题解都没完全看懂,然后就去烦ZZZ大佬) 简单补充几句吧,tmp的理解是个难点,除以tmp的原因是,当我们化简时,子节点也有一个B*f[ ...
- Python基础第九天
一.内容
- Asp.net Mvc 数据库上下文初始化器
在Asp.net Mvc 和Entity FrameWork程序中,如果数据库不存在,EF默认的行为是新建一个数据库.如果模型类与已有的数据库不匹配的时候,会抛出一个异常. 通过指定数据库上下文对象初 ...
- arcgis for silverlight 鼠标点击地图获取当前经纬度
silverlight代码: 地图的name值是myMap.后台在页面初始化的时候,添加地图的点击事件 myMap.MouseClick+=new EventHandler<Map.MouseE ...
- sql server 日期模糊查询
转换成varchar类型 ) like '%2010-10-09%' 两个字段拼接成一个字段 SELECT C0252_ID, C0252_name,C0252_Addr, ((select top ...
- E201700525-hm
skeleton n. 骨骼; (建筑物等的) 骨架; 梗概; 骨瘦如柴的人(或动物);adj. 骨骼的; 骨瘦如柴的; 概略的; 基本的; cloud n. 云; 云状物; invoke ...
- idea打印gc日志
1.在idea里添加配置 -XX:+PrintGCDetails 2.打印GC的详细信息: -XX:+PrintGCDetails 解释:打印GC详细信息. -XX:+PrintGCTimeStamp ...