ios的存储

沙河主要子目录:

/AppName.app:存放应用程序自身

/Documents/:这是文档目录。有关应用的所有数据文件应该写入到这个目录下,这个目录用于存储用户数据或者其他应该定期备份的信息。

/Library/:默认设置,下面有一些规范定义的的子目录,当然也可以自定义子目录,用于存放应用的文件,但是不宜存放用户数据文件,和document一样会被itunes同步,但不包括caches子目录

/Library/Preferences,这里存放程序规范要求的首选项文件,通过NSUserDefaults来获取和设置首选项。

/Library/Caches,保存应用的持久化数据,用于应用升级或者应用关闭后的数据保存,不会被itunes同步,所以为了减少同步的时间,可以考虑将一些比较大的文件而又不需要备份的文件放到这个目录下

/tmp/,保存应用数据,但不需要持久化的,在应用关闭后,该目录下的数据将删除,也可能系统在程序不运行的时候做清除

//打开是模拟器的路径

模拟器的app是systemData。

1、这是沙盒的入口文件(可直接打印)

NSString *homeDirectory = NSHomeDirectory();  

NSLog(@"path:%@", homeDirectory);  

2、获取document目录

    //第一种拼接办法

    NSString *documentPath = [NSHomeDirectory() stringByAppendingString:@"document"];

    //第二种函数办法(因为此函数返回的是数组)

    NSString *documentPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)firstObject];

3、获取Cache目录

//第一种拼接办法

    NSString *NSCachesDirectory = [NSHomeDirectory() stringByAppendingString:@"Cache"];

    //第二种函数办法(因为此函数返回的是数组)

    NSString *NSCachesDirectorys = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES)firstObject];

4、获取Library目录

    //第一种拼接办法

    NSString *libraryPath = [NSHomeDirectory() stringByAppendingString:@"library"];

    //第二种函数办法(因为此函数返回的是数组)

    NSString *libraryPath = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES)firstObject];

5、获取Tmp目录(也可以直接访问的存储空间)

NSString *tmpDir = NSTemporaryDirectory();  

 NSLog(@"%@", tmpDir);  

//平时经常用document。

//其实info.plist和storyboard的文件都是可以解析成xml的,可以查看

一,解析info.plist文件(plist存储)

NSString *plistPath = [[NSBundle mainBundle]pathForResource:@"Info" ofType:@"plist"];

    //拿到对应的plist字典

    NSDictionary *plistDictionary = [NSDictionary dictionaryWithContentsOfFile:plistPath];

    //可以对字典做相应的操作(读数据)

    NSArray *allKey = [plistDictionary allKeys];

    //也可以写数据(写到对应的沙盒里)

    NSString *docStr =  [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask,YES).firstObject stringByAppendingPathExtension:@"newFile"];

    [plistPath writeToFile:docStr atomically:YES];

//其实为沙盒存储,其中为判断文件是否已存在方法,

//尽量不用数字路经中,

[NSFileManager defaultManager] fileExistsAtPath:fullPath]

二,NSUserdefault存储

开发的两个方法

存数据

[[NSUserDefaults standardUserDefaults] setObject:@"111" forKey:@"nameFiled"];

读数据

[[NSUserDefaults standardUserDefaults] objectForKey:@"nameFiled"];

还有一种是当新版本时,显示某界面的操作,是拿到本次的版本号,存到偏好设置里面,当下次启动的时候,查看版本号是否和之前一致,判断是否显示

//需要在application里设置拿到plist的CFBundleShortVersionString查看当前版本。在从NSUserDefaults里拿到本地版本,这样来判断是否为第一次打开该版本。

//需要在程序结束后把本地版本存起来。

NSUserDefaults *userDefaults = NSUserDefaults.standardUserDefaults;

    NSString *currentVersion = [NSBundle mainBundle].infoDictionary[@"CFBundleShortVersionString"];

    NSString *localVersion = [userDefaults valueForKey:@"localVersion"];

!以上为沙盒存储,但是只能存储简单的数据,但是不能存储自定义模型数据。

三,NSKeyedArchiver,NSKeyedUnarchiver归档

//归档是序列化的过程,反归档是反序列化的过程,

1,苹果自带数据归档和反归档

    self.data = [NSKeyedArchiver archivedDataWithRootObject:@[@"11",@"22"] requiringSecureCoding:YES error:nil];

    //反归档

    NSArray *dataArray = [NSKeyedUnarchiver unarchivedObjectOfClass:NSArray.class fromData:self.data error:nil];

2,自定义对象数据

//自定义对象的归档和反归档只要对象换一下就可以。但是对于自己写的model需要操作写数据。

要支持<NSSecureCoding>的协议

同时实现三个方法

- (void)encodeWithCoder:(nonnull NSCoder *)aCoder {

    [aCoder encodeObject:self.nameField forKey:@"name"];

    [aCoder encodeInteger:self.age forKey:@"age"];

    }

- (nullable instancetype)initWithCoder:(nonnull NSCoder *)aDecoder {

    if(self = [super init])

    {

        self.nameField = [aDecoder decodeObjectForKey:@"name"];

        self.age = [aDecoder decodeIntegerForKey:@"age"];

    }

    return self;

}

+ (BOOL)supportsSecureCoding

{

    return YES;

}

https://www.jianshu.com/p/3463b905d3dc 是归档详解

四,SQLite存储

//头文件引入#import "sqlite3.h"

//内嵌式(嵌入到一些小系统里面)占用资源也很低,支持window/linux/unix等等主流pc端操作,

支持的五种类型

1,NULL:表示该值为NULL值。

2,INTEGER:整型值。

3,REAL:浮点值。

4,TEXT:文本字符串,存储使用的编码方式为UTF-8,UTF-16等。

5,BLOB:二进制大对象是人意类型的数据。

SQLite常见函数

splite3_open

sqlite3_close

sqlite3_exec

sqlite3_prepare_v2

sqlite3_step

sqlite3_column_text

想要在工程中使用,必须要先导入该工程

在general下有一个Linked Frameworks and Libraries,点击+,引入libsqlite3.tbd。之后项目就会出现Frameworks的文件夹。

//以下为声明的一些方法。(用于实现增删改查)

- (void)createDB:(NSString *)dbName;

- (void)createTab:(NSString *)tabName;

- (void)insertMessage:(LHBMessage *)message;

- (void)deleteMessage:(NSString *)name;

- (void)updateMessage:(LHBMessage *)message;

- (NSArray<LHBMessage *>*)queryMessage;

- (NSArray<LHBMessage *>*)queryMessageByName:(NSString *)name;

- (void)dropTable:(NSString *)table;

//一下为各方法的实现

//数据库打开之后就要随时关闭,否则会浪费资源

- (void)createDB:(NSString *)dbName

{

//    1,查找沙盒

    NSString *str = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask,YES).firstObject;

    NSLog(@"%@",str);

//    2,拼接数据库

    NSString *strDocument = [str stringByAppendingPathComponent:dbName];

//    3,常用数据库(UTF8String是oc转c语言)

    int result = sqlite3_open([strDocument UTF8String],&_sqlite);

    if(result == SQLITE_OK){

        NSLog(@"数据库创建成功");

    }else{

        NSLog(@"数据库创建失败");

    }

}

- (void)createTab:(NSString *)tabName

{


    //创建table。

    NSString *sql = [NSString stringWithFormat:@"create table %@(id integer primary key autoincrement, name text,phone text,address text)",tabName];

    NSLog(@"%@",sql);

    char *error;

    //c语言,数据库执行函数,两个null代表不需要回调,最后一个参数代表错误。

    int result = sqlite3_exec(_sqlite, [sql UTF8String], NULL, NULL, &error);

    if(result == SQLITE_OK){

        NSLog(@"table创建成功");

    }

    else{

        NSLog(@"table创建失败%s",error);

    }

    //sqlite3_close(_sqlite);

}

- (void)insertMessage:(LHBMessage *)message

{

    NSString *sql = [NSString stringWithFormat:@"insert into test(name,phone,address) values ('%@','%@','%@')",message.name,message.phone,message.address];

    int result = sqlite3_exec(_sqlite, [sql UTF8String], NULL, NULL, NULL);

    if(result == SQLITE_OK){

        NSLog(@"插入成功!");

    }

    else{

        NSLog(@"插入失败!");

    }

}

//一般很少进行数据库删除操作,要使用一定要进行一个弹窗提示,或者执行删除操作把该属性设为值,这样就可以达到查询时找不到该数据的效果

- (void)deleteMessage:(NSString *)name

{

    NSString *sql = [NSString stringWithFormat:@"delete from test where name = '%@'",name];

    int result = sqlite3_exec(_sqlite, [sql UTF8String], NULL, NULL, NULL);

    if(result == SQLITE_OK){

        NSLog(@"删除成功!");

    }

    else{

        NSLog(@"删除失败!");

    }

}

- (void)updateMessage:(LHBMessage *)message

{

    NSString *sql = [NSString stringWithFormat:@"update test set phone = '%@' where name = '%@'",message.phone,message.name];

    int result = sqlite3_exec(_sqlite, [sql UTF8String], NULL, NULL, NULL);

    if(result == SQLITE_OK){

        NSLog(@"更新成功!");

    }

    else{

        NSLog(@"更新失败!");

    }

}

- (NSArray<LHBMessage *> *)queryMessage

{

    NSString *sql = [NSString stringWithFormat:@"select * from test"];

    //sql语句的内部结构

    sqlite3_stmt *stmt;

    NSMutableArray *message = [[NSMutableArray alloc]init];

    int result = sqlite3_prepare_v2(_sqlite, [sql UTF8String], -1, &stmt, NULL);

    if(result == SQLITE_OK){

        while (sqlite3_step(stmt) == SQLITE_ROW) {

        const char *nameStr =(const char *)sqlite3_column_text(stmt, 1);

        const char *phoneStr =(const char *)sqlite3_column_text(stmt, 2);

        const char *addressStr =(const char *)sqlite3_column_text(stmt, 3);

            LHBMessage *lMessage = [[LHBMessage alloc]initWithObject:[NSString stringWithUTF8String:nameStr] withPhone:[NSString stringWithUTF8String:phoneStr] withAddress:[NSString stringWithUTF8String:addressStr]];

            [message addObject:lMessage];

        }

        return message;

    }

    else{

      NSLog(@"查询失败");

    }

    return nil;

}

- (void)dropTable:(NSString *)table

{

    NSString *sql = [NSString stringWithFormat:@"drop table %@",table];


    char *error;

    int result = sqlite3_exec(_sqlite, [sql UTF8String], NULL, NULL, &error);

    if(result == SQLITE_OK){

        NSLog(@"删除表成功!");

    }

    else{

        NSLog(@"删除表失败!%s",error);

    }

  }

//为判断是否table表已存在。

-(BOOL)checkName:(NSString *)name{

    char *err;

    NSString *sql = [NSString stringWithFormat:@"SELECT COUNT(*) FROM sqlite_master where type='table' and name='%@';",name];

    const char *sql_stmt = [sql UTF8String];

    if(sqlite3_exec(db, sql_stmt, NULL, NULL, &err) == 1){

        return YES;

    }else{

        return NO;

    }

}

!其中model想要输出对象,要实现其descripe函数,相当于java的tostring。

四,FMDB存储

sqlite3的封装,是一个第三方框架,因为sqlite3是对语言的封装,不太方便,所以FMDB就是完全对语言进行了oc的封装。

pod FMDB 此为第三方库

//头文件引入#import "fmdb/FMDB.h"

//声明fmdb的变量

@property (nonatomic,retain) FMDatabase *db;

//在tools工具类中相应完成打开数据库,创建table等操作。

//数据库打开之后就要随时关闭,否则会浪费资源

- (void)createDB

{

//    1,查找沙盒

    NSString *str = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask,YES).firstObject;

//    2,拼接数据库

    NSString *strDocument = [str stringByAppendingPathComponent:@"Message.db"];

//    3,常用数据库

    self.db = [FMDatabase databaseWithPath:strDocument];

    BOOL isSuccess = [self.db open];

    if(isSuccess){

        NSLog(@"打开成功!");

    }else{

        NSLog(@"打开失败!");

    }

}

//跟sqlite3不同的是,这里面要要把变量改成?。在executeUpdate的后面做相应的改变。

- (void)createTab

{

    [self createDB];

    //创建table。

    NSString *sql = [NSString stringWithFormat:@"create table message(id integer primary key autoincrement, name text,phone text,address text)"];


    BOOL isSuccess = [self.db executeUpdate:sql];

    if(isSuccess){

        NSLog(@"table创建成功");

    }

    else{

        NSLog(@"table创建失败");

    }

    [self.db close];

}

//如果有基础数据就直接用@{}转变为对象。

- (void)insertMessage:(LHBMessage *)message

{

    [self createDB];

    NSString *sql = [NSString stringWithFormat:@"insert into message(name,phone,address) values (?,?,?)"];

    BOOL isSuccess = [self.db executeUpdate:sql,message.name,message.phone,message.address];


    if(isSuccess){

        NSLog(@"table插入成功");

    }

    else{

        NSLog(@"table插入失败");

    }

    [self.db close];

}

//做相应的数据库查询操作,用到函数excuteQuery

- (NSArray<LHBMessage *> *)queryMessageByName:(NSString *)name

{

    [self createDB];

    NSString *sql = [NSString stringWithFormat:@"select * from message where name = ?"];

    //sql语句的内部结构

    NSMutableArray *message = [[NSMutableArray alloc]init];

  //先拿到结果集

    FMResultSet *set = [self.db executeQuery:sql,name];

        while ([set next]) {

        NSString *nameStr = [set stringForColumnIndex:1];

        NSString *phoneStr = [set stringForColumnIndex:2];

        NSString *addressStr = [set stringForColumnIndex:3];

            LHBMessage *lMessage = [[LHBMessage alloc]initWithObject:nameStr withPhone:phoneStr withAddress:addressStr];

            [message addObject:lMessage];

        }

    [self.db close];

        return message;

}

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 200,738评论 5 472
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,377评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 147,774评论 0 333
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,032评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,015评论 5 361
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,239评论 1 278
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,724评论 3 393
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,374评论 0 255
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,508评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,410评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,457评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,132评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,733评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,804评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,022评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,515评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,116评论 2 341

推荐阅读更多精彩内容