iOS开发记录——Plist使用

作者: BBH_Life | 来源:发表于2016-03-29 12:40 被阅读7958次

    前言

    在iOS开发过程中,我们会经常用到数据持久化问题,作为数据持久化解决方案之一,plist的使用是一个很方便快捷的方案。

    plist保存的地方

    1,工程沙盒里(就是程序user Document文件夹下,以读取文件,写入文件方式)
    2,工程自身里(就是在工程里手动创建一个如.plist文件,把固定的内容写入,这个需要人工手动写入)
    3,工程沙盒里(保存到user Document下,不过不需要读写文件,用系统的 NSUserDefaults 可以快速保存添加读取删除基本数据类型,类似于android里的Sharedpreferences )

    plist是什么?

    它全名是:Property List,属性列表文件,它是一种用来存储串行化后的对象的文件。属性列表文件的扩展名为.plist ,因此通常被称为 plist文件。文件是xml格式的。Plist文件通常用于储存用户设置,也可以用于存储捆绑的信息。

    如何使用plist——plist的读取,修改和删除

    plist的读取(使用在工程自身里的方式)
    1. 创建一项测试project 1.png
    2. 创建一个plist文件


      2.png
      3.png

      在plist中添加一些信息


      4.png plist可以支持很多类型数据包括字典和数组
      5.png
    3. 读取代码
    - (void)viewDidLoad {
        [super viewDidLoad];
        
        //读取plist
        [self getDataFromPlist];
    }
    
    - (void)getDataFromPlist{
        NSString *plistPath = [[NSBundle mainBundle]pathForResource:@"PropertyListTest" ofType:@"plist"];
        NSMutableDictionary *dataDic = [[NSMutableDictionary alloc]initWithContentsOfFile:plistPath];
        NSLog(@"%@",dataDic);//直接打印数据
    }
    

    打印结果

    6.png
    plist的修改写入

    (之前有说,保存在工程自身的plist并不能修改写入,所以这里需要通过沙盒路径创建plist并修改保存,还有一个坑,模拟器与真机权限可能不一致,在模拟机上能够通过nsbundle路径修改成功,但是真机上并不能,所以建议需要修改的plist都使用沙盒路径来新建和修改并且两者所获取的plist并不是同一个文件,代码解释如下)

    - (void)viewDidLoad {
        [super viewDidLoad];
        
        //读取plist
        [self getDataFromPlist];
        // 写入plist
        [self writeDataToPlist];
    }
    
    - (void)getDataFromPlist{
        //沙盒获取路径
        NSArray *pathArray = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
        NSString *path = [pathArray objectAtIndex:0];
        //获取文件的完整路径
        NSString *filePatch = [path stringByAppendingPathComponent:@"PropertyListTest.plist"];//没有会自动创建
        NSLog(@"file patch%@",filePatch);
        NSMutableDictionary *sandBoxDataDic = [[NSMutableDictionary alloc]initWithContentsOfFile:filePatch];
        if (sandBoxDataDic==nil) {
            sandBoxDataDic = [NSMutableDictionary new];
            sandBoxDataDic[@"test"] = @"test";
            [sandBoxDataDic writeToFile:filePatch atomically:YES];
        }
        NSLog(@"sandBox %@",sandBoxDataDic);//直接打印数据
        
        
        //工程自身的plist  
        NSString *plistPath = [[NSBundle mainBundle]pathForResource:@"PropertyListTest" ofType:@"plist"];
        NSMutableDictionary *dataDic = [[NSMutableDictionary alloc]initWithContentsOfFile:plistPath];
        NSLog(@"nsbundle %@",dataDic);//直接打印数据
        
    }
    
    - (void)writeDataToPlist{
        //这里使用位于沙盒的plist(程序会自动新建的那一个)
        NSArray *pathArray = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
        NSString *path = [pathArray objectAtIndex:0];
        //获取文件的完整路径
        NSString *filePatch = [path stringByAppendingPathComponent:@"PropertyListTest.plist"];
        NSMutableDictionary *sandBoxDataDic = [[NSMutableDictionary alloc]initWithContentsOfFile:filePatch];
        NSLog(@"old sandBox is %@",sandBoxDataDic);
        sandBoxDataDic[@"test"] = @"hello world";
        [sandBoxDataDic writeToFile:filePatch atomically:YES];
        sandBoxDataDic = [[NSMutableDictionary alloc]initWithContentsOfFile:filePatch];
        NSLog(@"new sandBox is %@",sandBoxDataDic);
    
    
        //这里使用的是位于工程自身的plist(手动新建的那一个)
        NSString *plistPath = [[NSBundle mainBundle]pathForResource:@"PropertyListTest" ofType:@"plist"];
        NSMutableDictionary *dataDic = [[NSMutableDictionary alloc]initWithContentsOfFile:plistPath];
        
        //开始修改及写入
        NSNumber *number = @10;
        dataDic[@"1"] = number;//修改
        NSNumber *boolNumber = [NSNumber numberWithBool:YES];//bool值只能通过nsnumber修改
        dataDic[@"3"] = boolNumber;
        [dataDic writeToFile:plistPath atomically:YES];
        
        //重新获取数据 看是否有变动(虚拟机上会有变动,但是真机上不会)
        NSMutableDictionary *newDataDic = [[NSMutableDictionary alloc]initWithContentsOfFile:plistPath];
        NSLog(@"new %@",newDataDic);//打印新数据
    }
    

    虚拟机上的打印结果(bundle和sandbox都修改成功)


    虚拟机测试结果

    真机上的打印结果(bundle修改失败,sandbox修改成功)

    真机测试结果
    注意bool值的修改与一般值修改不一样,是需要nsnumber作为中间转换
    

    Way NO.3 UserDefaults

    plist文件读取的三种方式还有一种就是使用UserDefaults来访问一个特殊的plist文件,使用方法简单,不需要文件读取,使用系统方法,这里就不再介绍UserDefaults了,读者可自行Google。

    相关文章

      网友评论

      • Clemo:楼主! i直接拖入工程的plist文件,用字典读取出来之后,修改在写入,直接就是失败啊. 有什么办法可以解决吗?
        ripperhe:Bundle 内部的文件都是只读的
        Clemo:@BBH_Life 是的刚确认了,直接新建跟拖进去都是只读的
        BBH_Life:@Clemo 好久没详细看过了,不知道我的理解对不对:直接拖进去的按道理就是只读的吧?
      • lzp_John:请问下 有个问题 我在项目中的plist文件用这个方法
        NSString *path = [[NSBundle mainBundle] pathForResource:@"emotion" ofType:@"plist"];
        NSDictionary *dic = [NSDictionary dictionaryWithContentsOfFile:path];
        在真机中获取到的数据和模拟器的数据不一致 请问是怎么回事呢
        BBH_Life:@lzp_John 这个我也不是太清楚,我可能也要研究下
        lzp_John:plist文件放的是表情数据
        模拟器的数据时这样
        "[\U5496\U5561]" = 60;
        "[\U54c8\U6b20]" = 47;
        "[\U5564\U9152]" = 57;

        真机中的数据时这样
        emotion0 = "section0_emotion0";
        emotion1 = "section0_emotion1";
        emotion10 = "section0_emotion10";
      • Pusswzy:权限这里讲的不错. 手动创建的plist文件只能在模拟器上使用NSBundle修改, 但是在真机上却不可以.
        Pusswzy:@YYSheng 使用代码在沙盒中创建plist文件, 这个plist文件可以进行增删改查
        YYSheng:然而解决办法呢
        BBH_Life:@Pusswzy 谢谢鼓励:smile:

      本文标题:iOS开发记录——Plist使用

      本文链接:https://www.haomeiwen.com/subject/riqslttx.html