iOS 数据存储(一) 沙盒、Settings Bundle

时间:2022-01-27 02:49:03

链接:http://blog.csdn.net/vnanyesheshou/article/details/52325852

iOS存储

iOS 数据存储的几种方式:

NSUserDefaults                 适用于保存程序参数,设置,选项相关的少量数据。

XML属性列表(plist)归档     少量数据

NSKeyedArchiver归档(NSCoding)

SQLite3                            大量数据

iOS程序只能在系统为该应用分配的文件区域下读/写文件,这个文件区域就被称为该应用程序的沙盒

iOS 数据存储(一) 沙盒、Settings Bundle

沙盒下的结构:

  • Documents:除了NSUserDefaults的首选项设置外,应用程序的数据、文件大都保存在该目录下。
  • Library:基于NSUserDefaults的首选项参数保存在Library/Preferences目录下。
  • tmp: 存储临时文件,当应用程序不再需要某个临时文件时,应负责删除。


沙盒各目录获取方式

1 获取Documents目录

两种方式:

  • 利用NSSearchPathForDirectoriesInDomains()函数
//NSDocumentDirectory表示查找Documents文件夹,NSUserDomainMask参数代表仅搜索应用程序沙盒。
NSArray *pathAry = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
//沙盒下只有一个Documets文件夹,所以获取第一个元素。
NSString *documentsPath = pathAry[0];
  • 利用根目录拼接字符串
//沙盒根目录
NSString *home = NSHomeDirectory();
NSString *documents = [home stringByAppendingPathComponent:@"Documents"];

2 获取tmp目录
NSString *tmpPath = NSTemporaryDirectory();

3 获取Library目录
Library目录
NSArray *pathAry = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES);
NSString *libraryPath = pathAry[0];

Library/Caches目录
与Documents方法相似
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
NSString *cachesPath = paths[0];

Library/Preferences目录
NSArray *pathAry = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES);
//通过Library目录拼接字符串
NSString *preferencesPath = [pathAry[0] stringByAppendingPathComponent:@"Preferences"];

Settings Bundle 默认设置

在说这几种数据存储之前我们先说一下Settings Bundle,程序默认设置。比如:是否适用震动,是否开启音效等。
通过在工程中新建Settings.bundle文件,你会看见工程中多了一个文件Settings.bundle,如下图所示:
iOS 数据存储(一) 沙盒、Settings Bundle

不做任何修改,运行程序,点击系统设置应用,点击自己的应用会发现多了四项内容:
iOS 数据存储(一) 沙盒、Settings Bundle
这些内容如果不修改,在程序中通过NSUserDefaults是获取不到的。需要启动程序的时候进行设置。
AppDelegate.m文件中设置
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Override point for customization after application launch.
    //设置之前
    NSLog(@"enabled before is %@",[[NSUserDefaults standardUserDefaults]
                                   stringForKey:@"enabled_preference"]);
    NSLog(@"name_preference is %@",[[NSUserDefaults standardUserDefaults] stringForKey:@"name_preference"]);
    NSLog(@"slider preference is %@",[[NSUserDefaults standardUserDefaults] stringForKey:@"slider_preference"]);
    // 加载默认配置
    [self registerDefaultsFromSettingsBundle];
    //设置之后
    NSLog(@"enabled after is %@",[[NSUserDefaults standardUserDefaults] stringForKey:@"enabled_preference"]);
    NSLog(@"name_preference is %@",[[NSUserDefaults standardUserDefaults] stringForKey:@"name_preference"]);
    NSLog(@"slider p is %@",[[NSUserDefaults standardUserDefaults] stringForKey:@"slider_preference"]);
    return YES;
}
- (void)registerDefaultsFromSettingsBundle {
    NSString *settingsBundle = [[NSBundle mainBundle] pathForResource:@"Settings" ofType:@"bundle"];
    if(!settingsBundle) {
        NSLog(@"Could not find Settings.bundle");
        return;
    }
    NSLog(@"setDefaultValue from settingsbundle");
    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 && [[prefSpecification allKeys] containsObject:@"DefaultValue"]) {
            NSLog(@"setDefault key:%@",key);
            [defaultsToRegister setObject:[prefSpecification objectForKey:@"DefaultValue"] forKey:key];
        }
    }
    //并不是真正设置到Library/Preferences中
    [[NSUserDefaults standardUserDefaults] registerDefaults:defaultsToRegister];
}

打印:
2016-08-26 11:44:52.303 GlassAssist[434:221569] enabled before is (null)
2016-08-26 11:44:52.303 GlassAssist[434:221569] name_preference is (null)
2016-08-26 11:44:52.303 GlassAssist[434:221569] slider preference is (null)
2016-08-26 11:44:52.303 GlassAssist[434:221569] setDefaultValue from settingsbundle
2016-08-26 11:44:52.305 GlassAssist[434:221569] setDefault key:name_preference
2016-08-26 11:44:52.306 GlassAssist[434:221569] setDefault key:enabled_preference
2016-08-26 11:44:52.306 GlassAssist[434:221569] setDefault key:slider_preference
2016-08-26 11:44:52.307 GlassAssist[434:221569] enabled after is 1
2016-08-26 11:44:52.307 GlassAssist[434:221569] name_preference is 
2016-08-26 11:44:52.307 GlassAssist[434:221569] slider p is 0.5
注意:设置之后就可以通过NSUserDefaults获取了,我们知道NSUserDefaults存储的是在Library/Preferences/下中的文件中,但此时打开此文件看并没有发现这几个key。
这是说明registerDefaults并不会将值存到沙盒中,(具体存哪就不知道了),此方法的好处在于如果沙盒中已经存在该值了,它就不会在保存这个值,只要当沙盒中没有的时候才会保存。所以每次开启应用都调一次这个方法没有关系。

当我们在设置中修改应用的这几个默认值时,会将某个修改的key value会通过NSUserDefaults存储到Library/Preferences/下中的文件中。

当我们第一次打开应用后关闭开关,enable_preference的值变为0存储到文件中,此时重新打开应用(先把应用杀掉再打开),打印如下:
2016-08-26 11:56:42.192 GlassAssist[247:30102] enabled before is 0
2016-08-26 11:56:42.192 GlassAssist[247:30102] name_preference is 
2016-08-26 11:56:42.192 GlassAssist[247:30102] slider preference is (null)
2016-08-26 11:56:42.192 GlassAssist[247:30102] setDefaultValue from settingsbundle
2016-08-26 11:56:42.195 GlassAssist[247:30102] setDefault key:name_preference
2016-08-26 11:56:42.195 GlassAssist[247:30102] setDefault key:enabled_preference
2016-08-26 11:56:42.196 GlassAssist[247:30102] setDefault key:slider_preference
2016-08-26 11:56:42.196 GlassAssist[247:30102] enabled after is 0
2016-08-26 11:56:42.197 GlassAssist[247:30102] name_preference is 
2016-08-26 11:56:42.198 GlassAssist[247:30102] slider p is 0.5

通过此可以发现enable_preference并没有重新设置默认值。。。。。