QQ学习群:262779381QQ学习群:2627793811.Documents目录该目录用于存放本APP所有资源文件和数 据文件,当打开文件夹后,可以看到应用所有的文件和图片资源都存放在内。获取目录位置的代码如下所示。NSArraydocume ntPath=NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask,YES)其中documentPath是只有一个元素的数组,然后我们可以使用如下代码将路径取出。 NSStringmyDocumentPath=[documentPathlastObject]或者NSString myDocumentPath=[documentPathobjectAtIndex:0]2.Library目录在Lib rary目录下存放了Preferences和Caches目录,前者存放了应用的偏好设置数据,比如本地化,国际化偏好设置数据,后者存 放缓存数据。3.tmp目录临时文件目录,用户可以访问,但是不能进行iTunes和iCloud的备份。可以使用以下代码获取临时目 录的路径。NSStringtemDir=NSTemporaryDirectory()归档的含义就是指 将对象写入文件并保存在硬盘中,当再次打开应用程序时,可以还原这些对象,以达到数据存储的功能。归档也可以称之为对象序列化和对象持久化 。和属性列表不同的是,归档后的数据是加密的,我们看不到数据具体的内容,我们通过一个实例来了解如何进行数据归档。QQ学习 群:2627793819.2.2归档归档前,我们定义一个数组对象,并初始化一些数据,然后定义一个文件路径,用于保存归档后的文 件。1.#import2.intmain(intargc,const charargv[]){3.@autoreleasepool{4.NSArraydat aArray=[NSArrayarrayWithObjects:@"Jack",@"Rose",@"Mike",nil]; 5.NSStringfilePath=[NSHomeDirectory()stringByAppend ingPathComponent:@"array.archive"];6.BOOLsuccess=[NSA rchiverarchiveRootObject:dataArraytoFile:filePath];7.i f(success){8.NSLog(@"归档成功!");9.}10.} 11.return0;12.}QQ学习群:262779381注意我们文件的格式是随便定义的,在这里只是表 示一个形式,没有规定的格式。最后使用archiveRootObject方法进行对象归档,它的返回值是布尔类型,因此我们定义一个BO OL类型的变量。运行项目后,我们可以找到文件目录,看到我们归档的文件如图所示。QQ学习群:262779381 前面我们提到过,因为归档后的文件是加密保存的,我们看到的都是经过加密处理的数据,所以让我们要读取文件内容时,需要进行解归档操作。 重写main方法,因为我们归档的是数组对象,所以我们解归档时也要使用数组对象接受解归档的数据。13.#import< Foundation/Foundation.h>14.intmain(intargc,constcharargv[ ]){15.@autoreleasepool{16.NSStringfilePath=[N SHomeDirectory()stringByAppendingPathComponent:@"array.archive"] ;17.NSArrayarray=[NSUnarchiverunarchiveObjectWithFi le:filePath];18.NSLog(@"array:%@",array);19.}20. return0;21.} 运行模拟器,可以看到控制台输出结果为:array:(Jack,Rose, Mike)QQ学习群:262779381这种解归档的方式有很多缺点,比如一个对象只能归档一个文件,而且 必须知道归档的类型。下面的方法可以多个对象进行归档,重写main方法。22.#importtion.h>23.intmain(intargc,constcharargv[]){24.@auto releasepool{25.NSArraynameArray=[NSArrayarrayWithO bjects:@"Jack",@"Rose",@"Mike",nil];26.NSArrayteamArr ay=[NSArrayarrayWithObjects:@"Arsenal",@"ACMilan",nil];27. NSStringfilePath=[NSHomeDirectory()stringByAppendingP athComponent:@"array.text"];28.NSMutableDatadata=[NS MutableDatadata];29.NSKeyedArchiverarchiver=[[NSKey edArchiveralloc]initForWritingWithMutableData:data];30. [archiverencodeObject:nameArrayforKey:@"name"];31.[arc hiverencodeObject:teamArrayforKey:@"team"];32.[archive rfinishEncoding];33.BOOLsuccess=[datawriteToFile:fi lePathatomically:YES];34.if(success){35. NSLog(@"归档成功");36.}37.}38.return0;39.}QQ学习群 :262779381这里我们定义了两个数组对象,你也可以定义多个,然后创建了NSMutableData实例,然后创建 了NSKeyedArchiver实例,用于保存data实例中的内容,接下来将数组写入归档对象,最后结束归档。运行项目,可 以看到在目录下创建好了归档文件,如图所示。QQ学习群:262779381当我们要读取数据时,需要进行解归档操作,这 里和第一种方式也有一定的区别,也需要创建一个NSMutableData实例,来存储归档后的数据,重写main方法。40.#imp ort41.intmain(intargc,constchar argv[]){42.@autoreleasepool{43.NSStringfilePath =[NSHomeDirectory()stringByAppendingPathComponent:@"array.text "];44.NSMutableDatadata=[[NSMutableDataalloc]initWi thContentsOfFile:filePath];45.NSKeyedUnarchiverunarchi ver=[[NSKeyedUnarchiveralloc]initForReadingWithData:data];46. NSArrayarray1=[unarchiverdecodeObjectForKey:@"name"] ;47.NSArrayarray2=[unarchiverdecodeObjectForKey:@"t eam"];48.NSLog(@"array1:%@",array1);49.NSLog(@" array2:%@",array2);50.}51.return0;52.}QQ学习群:26277938 1运行项目,可以看到控制台输出结果如下:array1:(Jack,Rose,Mike)arr ay2:(Arsenal,"ACMilan")QQ学习群:262779381SQLite数 据库是一个开源的嵌入式关系数据库,也就是为手持移动终端开发的关系数据库,它管理的数据较小。SQLite相比其他数据库来说,拥有可移 植性好,容易使用,占用空间小,高效可靠等优点。它还有一个更大的优点就是在嵌入到程序内部时不需要进行网络配置,也不需要进 行管理,这是因为客户端和服务器在同一个进程空间里运行。所以访问的速度非常快。其他的关系型数据库,例如DB2,Oracle等都需要与 网络进行通信,已达到数据管理功能。在使用SQLite数据库前,需要添加libsqlite3.0.dylib框架,添加的 方式如图所示。QQ学习群:2627793819.3SQLite数据库QQ学习群:262779381在项目的Bu ildPhases选项中的LinkBinaryWithLibraries添加框架。我们的讲解主要讲述如何在XCode中使用 SQLite对数据库表进行创建、添加数据、查询数据等操作。在XCode中新建工程,使用SingleViewAppli cation模板。并在工程中导入libsqlite3.0.dylib框架,在.h文件中导入sqlite3.h头文件。------ -----------viewController.h-------------------1.#importIKit.h>2.#import3.@interfaceViewController:UIVie wController4.@end准备工作完成后,现在我们开始实现对SQLite数据库进行操作。QQ学习群:26277938 1创建数据库表的操作步骤主要有以下3个步骤:(1)使用sqlite3_open函数打开数据库。(2)使用sqlite3_ex ec函数执行createtable语句,创建数据库表。(3)使用sqlite3_close函数关闭数据库表,释放资源。在.m 文件中新建CreateTable方法,实现创建数据库表功能。5.-(void)createTable{6.NSSt ringfilePath=[NSHomeDirectory()stringByAppendingFormat:@"/st udent.sqlite"];7.NSLog(@"%@",filePath);8.sqlite3sqlit e=nil;9.intresult=sqlite3_open([filePathUTF8String], &sqlite);10.if(result!=SQLITE_OK){11.NSLog(@"数据 库打开失败");12.sqlite3_close(sqlite);13.return;14. }QQ学习群:2627793819.3.1创建数据库表15.charerror=nil;16. //创建数据库表17.NSStringsql=@"CREATETABLEIFNOTEXISTSst udent(usernameTEXTprimarykey,password18.TEXT,ageTEXT)" ;19.result=sqlite3_exec(sqlite,[sqlUTF8String],NULL,N ULL,&error);20.if(result!=SQLITE_OK){21.NSLog( @"创建表失败:%s",error);22.return;23.}24.//关闭数据库25 .sqlite3_close(sqlite);26.NSLog(@"创建表成功!");27.}QQ学习群: 262779381首先我们获取文件的路径,并初始化sqlite实例,它是一个指向数据库文件的指针。接下来使用sqli te3_open([filePathUTF8String],&sqlite)方法打开数据库,它返回的是一个BOOL类型的值,当 结果为true说明数据库打开成功,若为false则失败。这里使用SQLite提供的SQLITE_OK判断结果。接下来 我们使用sqlite3_exec方法创建数据库表student,最后关闭数据库释放资源。我们在沙盒目录中去查看我们的数据库文件是否 创建成功。控制台输出路径如下。Users/pc/Library/Developer/CoreSimulator/Devices/ 99B39655-17EB-4F78-98BF-B43FB01D1A29/data/Containers/Data/Applica tion/40C85614-5F4E-4BED-AEEE-A5CF744DCF0A/student.sqlite找到路径下的文件, 如图所示。QQ学习群:262779381QQ学习群:262779381在创建数据库表时,我们定义了3个字段,us ername(主键),password和age,我们使用SQLite管理工具SQLiteManager,打开我们创建的数据库,结果 如图所示。SQLiteManager工具可以在官网下载,读者可以访问SQLiteManager官网。在工具中,我们可以清楚的看到 我们的数据库表student已经创建完成,说明代码执行成功。QQ学习群:262779381QQ学习群:262779381 向数据库表中插入数据记录主要有以下6个步骤:(1)使用sqlite3_open函数打开数据库。(2)使用sqlite3_p repare函数对sql语句进行编译。(3)使用sqlite3_bind_text函数对数据进行插入。(4)使用sqlite3 _step函数执行sql插入语句。(5)使用sqlite3_finalize函数关闭数据库句柄。(6)使用sqlite3_cl ose函数关闭数据库释放资源。9.3.2插入数据在.m文件中,新建一个insertTable方法,用于实现添加数据功能。28 .-(void)insertTable29.{30.sqlite3sqlite=nil;31.sq lite3_stmtstmt=nil;32.NSStringfilePath=[NSHomeDirect ory()stringByAppendingString:@"/student.sqlite"];33.//打开数据库 34.intresult=sqlite3_open([filePathUTF8String],&sqlite );35.if(result!=SQLITE_OK){36.NSLog(@"数据库打开失败") ;37.return;38.}QQ学习群:26277938139.//创建SQL语句40. NSStringsql=@"INSERTINTOstudent(username,password,age)VAL UES(?,?,?)";41.//编译SQL语句42.sqlite3_prepare(sqlite,[sq lUTF8String],-1,&stmt,NULL);43.NSStringusername=@"ja ck";44.NSStringpassword=@"123321";45.NSStringage =@"23";46.//往数据库中添加数据47.sqlite3_bind_text(stmt,1,[us ernameUTF8String],-1,NULL);48.sqlite3_bind_text(stmt,2, [passwordUTF8String],-1,NULL);49.sqlite3_bind_text(stmt, 3,[ageUTF8String],-1,NULL);50.//执行SQL语句51.result= sqlite3_step(stmt);52.if(result==SQLITE_ERROR||result= =SQLITE_MISUSE){53.NSLog(@"执行SQL语句失败");54.ret urn;55.}56.//关闭数据库句柄57.sqlite3_finalize(stmt);58. //关闭数据库59.sqlite3_close(sqlite);60.NSLog(@"数据插入成功") ;61.}QQ学习群:262779381在viewDidLoad方法中调用insertTable方法,实现插入操 作。可以看到我们在方法中首先创建了一个sqlite3_stmt实例,这是数据库用于操作的句柄实例,只用通过使用该实例 ,才可以对数据库表里的数据进行相应的操作。接下来我们打开数据库成功,使用INSERTINTOstudent(username, password,age)VALUES(?,?,?)语句向数据库中插入数据,这里需要注意的是,数据库名称和对应的字段要正确,v alue的值用“?”代替,在下面的内容中进行实现。接下来定义3个NSString类型的变量,并使用sqlite3_b ind_text(stmt,1,[usernameUTF8String],-1,NULL)方法插入数据,因为我们数据库表 结构定义的是text类型的数据,所以这里我们使用sqlite3_bind_text方法,若是其他数据类型,需要使用其他的绑定方法, 读者可以自己查看SDK。然后执行插入语句,最后关闭数据库句柄和数据库文件,释放资源。QQ学习群:262779381我们打开SQ LiteManager管理工具查看我们插入的数据,如图所示。QQ学习群:262779381在数据库中查询数据主要有以下5个步 骤:(1)使用sqlite3_open函数打开数据库。(2)使用sqlite3_prepare函数对sql语句进行编译。(3 )使用循环语句执行sqlite3_step函数进行查询。(4)使用sqlite3_finalize函数关闭数据库句柄。(5)使 用sqlite3_close函数关闭数据库释放资源。我们将最后的查询结果显示在viewController视图控制器中。 我们在视图控制器中进行布局,创建3个UITextField和一个按钮,用于实现查询方法。QQ学习群:2627793819.3. 3查询数据在viewController.h文件中创建两个UITextField实例,用于显示查询数据后的结果。------- ----------viewController.h------------------62.#importKit.h>63.#import64.@interfaceViewController:UIVi ewController65.@property(nonatomic,retain)UITextFieldusernam e;66.@property(nonatomic,retain)UITextFieldage;67.@end然后在. m文件中对实例进行初始化布局,并对相关属性进行设置。-----------------viewController.m----- -------------68.-(void)viewDidLoad{69.[superviewDidLoad];70 .//用户名文本输入框71._username=[[UITextFieldalloc]initWithFrame: CGRectMake(120,40,80,40)];72._username.borderStyle=UITe xtBorderStyleRoundedRect;73.[self.viewaddSubview:_username];QQ 学习群:26277938174.//年龄文本输入框75._age=[[UITextFieldalloc]init WithFrame:CGRectMake(120,100,80,40)];76._age.borderStyle =UITextBorderStyleRoundedRect;77.[self.viewaddSubview:_age ];78.//查询按钮79.UIButtonsearchButton=[UIButtonbutton WithType:UIButtonTypeRoundedRect];80.searchButton.frame=CG RectMake(120,200,80,20);81.[searchButtonsetTitle:@"查询"f orState:UIControlStateNormal];82.[searchButtonsetTintColor: [UIColorblueColor]];83.[searchButtonaddTarget:selfaction: @selector(search)forControlEvents:UIControlEventTouchUpInside]; 84.[self.viewaddSubview:searchButton];85.}QQ学习群:262779381 注意我们在对按钮进行初始化时,设置了一个search方法,该方法就是实现数据库数据查询的方法,下面实现该方法。86.-(vo id)search87.{88.sqlite3sqlite=nil;89.sqlite3_stmt stmt=nil;90.NSStringfilePath=[NSHomeDirectory()strin gByAppendingString:@"/student.sqlite"];91.//打开数据库92.int result=sqlite3_open([filePathUTF8String],&sqlite);93.i f(result!=SQLITE_OK){94.NSLog(@"数据库打开失败");95. return;96.}QQ学习群:26277938197.NSStringsql=@"SELECTu sername,password,ageFROMstudent";98.//编译SQL语句99.sqlit e3_prepare_v2(sqlite,[sqlUTF8String],-1,&stmt,NULL);100. //执行查询SQL语句101.result=sqlite3_step(stmt);102.while( result==SQLITE_ROW){103.charusername=(char)sqli te3_column_text(stmt,0);104.charpassword=(char)sq lite3_column_text(stmt,1);105.charage=(char)sqlit e3_column_text(stmt,2);106.NSStringuserName=[NSStri ngstringWithCString:usernameencoding:NSUTF8StringEncoding];107 .NSStringpassWord=[NSStringstringWithCString:passwor dencoding:NSUTF8StringEncoding];108.NSStringAge=[NS StringstringWithCString:ageencoding:NSUTF8StringEncoding];109. //移动游标指向一下条数据110.result=sqlite3_step(stmt);11 1._username.text=userName;112._age.text=Age; 113.}114.sqlite3_finalize(stmt);115.sqlite3_close( sqlite);116.}QQ学习群:262779381《IOS应用开发教程》QQ学习群 :262779381http://www.xs360.cn第九章iOS中的数据存储QQ学习群:262779381教学目标 :1.了解IOS中数据存储的基本方法。2.了解IOS中SandBox沙盒机制。3.掌握SQLite数据库的使用方法,包括增、 删、改、查。4.了解网络资源获取的方法QQ学习群:2627793819.1数据存储的基本方式IOS提供本地存 储和云端存储(iCloud),苹果公司提供的iCloud云端存储共享技术已经非常成熟,有兴趣的读者可以去研究如何使用iCloud去 存储数据,并进行文件分享,在本教材中,我们讲述本地存储。本地存储主要涉及以下这5种机制。·属性列表。可以将集合 对象读写到属性列表(Plist)中,以键值对的形式。·NSUserDefaults。比较轻量级的存储机制。·对 象归档。可以将对象的状态保存到归档文件中。·SQLite数据库。轻量级开源嵌入式数据库保存数据。·CoreD ata。它是一种对象关系映射技术(ORM),也是基于SQLite存储。QQ学习群:2627793819.1.1数据存储基本方式 介绍QQ学习群:262779381属性列表就是通过plist文件对数据进行存储,plist其实是一种XML文件,在Founda tion框架中的数组和字典等都可以与属性列表文件相互转换。我们看到area.plist文件中有3个字段,分别是key、type和 value,分别代表存储数据的名称(key),存储数据的类型(type)和与名称对应的值(value),这里我们使用的类型是Dic tionary字典,可以使用NSArray数组。当我们需要读取相应数据时,只需要读取相应字段(key)的值(value)即可。 9.1.2属性列表QQ学习群:262779381在XCode中创建一个新工程,使用SingleViewApplicatio n模板,并创建一个plist文件,名称为student.plist。QQ学习群:2627793811.-(IBAction) saveData:(id)sender{2.NSLog(@"保存成功");3.//设置文件保存的路径4. NSArraypaths=NSSearchPathForDirectoriesInDomains(NSDocumen tDirectory,NSUserDomainMask,YES);5.//获取documents的路径6. NSStringdocumentPath=[pathslastObject];7.//定义路径8.N SStringsavePath=[documentPathstringByAppendingString:@"stude nt.plist"];9.//获取用户输入内容,通过字典存储10.NSMutableDictionarys tudentData=[[NSMutableDictionaryalloc]init];11.//添加学生数据1 2.[studentDatasetObject:_nameforKey:@"name"];13.[stude ntDatasetObject:_sexforKey:@"sex"];14.[studentDatasetObje ct:_ageforKey:@"age"];15.//保存到文件16.[studentDatawriteT oFile:savePathatomically:YES];17.}QQ学习群:262779381NSSearchPath ForDirectoriesInDomains方法搜索沙盒文件目录,然后通过stringByAppendingString方法找到 student.plist文件,然后通过可变字典添加数据,最后将字典写入到文件中。18.-(IBAction)loadData :(id)sender{19.//设置文件保存的路径20.NSArraypaths=NSSearch PathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask ,YES);21.//获取documents的路径22.NSStringdocumentPath=[ pathslastObject];23.//定义路径24.NSStringsavePath=[doc umentPathstringByAppendingPathComponent:@"student.plist"];25.//获取用户输入内容,通过字典存储26.NSMutableDictionaryreadData=[NSMutableDictionarydictionaryWithContentsOfFile:savePath];27.NSLog(@"readData:%@",readData);28._name=[readDataobjectForKey:@"name"];29._sex=[readDataobjectForKey:@"sex"];30._age=[readDataobjectForKey:@"age"];31.}QQ学习群:262779381我们在保存文件时,注意到我们在控制台输出了文件位置,控制台输出结果如下:/Users/pc/Library/Developer/CoreSimulator/Devices/99B39655-17EB-4F78-98BF-B43FB01D1A29/data/Containers/Data/Application/3AA2455E-6861-4390-944E-A85B5073A400/Documents/student.plistQQ学习群:262779381和Windows操作系统不同,Mac操作提供了一种沙盒(SandBox)机制,它在安全方面的等级更高。沙盒存放了IOS的各个App,切每个App之前的都是独立存储的,且App之间的数据也是不能共享的,如果要使用其他App的数据,那么需要一些特殊的API进行方法。在Mac中的沙盒目录如下所示。~Library/ApplicationSupport/iPhoneSimulator/6.0/Applications,我们在Finder文件管理器中找到该目录,可以使用command+shift+G快速进入文件。任意进入到一个App中,我们看到沙盒目录下有三个子文件夹。QQ学习群:2627793819.2沙盒(SandBox)和归档(Archive)9.2.1沙盒机制 |
|