经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 移动开发 » iOS » 查看文章
数据持久化
来源:cnblogs  作者:mustard22  时间:2019/6/27 9:26:30  对本文有异议

1.plist文件

即属性列表文件,全名是Property List,这种文件的扩展名为.plist,因此,通常被叫做plist文件。它是一种用来存储串行化后的对象的文件,用于存储程序中经常用到且数据量小而不经常改动的数据。

可以存储的类型:NSNumber,NSString,NSDate,NSData ,NSArray,NSDictionary,BOOL.

不支持自定义对象的存储。

plist的创建方式有两种:command + n 创建和纯代码创建,不同的创建方式使用方法也自然不同。

command + n 创建:

  1.    
  1.   // read bundle's plist
  2. if let plistPath = Bundle.main.path(forResource: "test", ofType: "plist") {
  3. var dataDict = NSDictionary(contentsOfFile: plistPath) as! Dictionary<String, Any>
  4. // var dataArray = NSArray(contentsOfFile: plistPath) as! NSArray
  5. ?
  6. // modify
  7. dataDict["Int"] = 1
  8. dataDict["String"] = "hi"
  9. }

  

纯代码创建:

  1.   // create
  2. let documentsPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] as NSString
  3. let plistPath = documentsPath.appendingPathComponent("test.plist")
  4. print(plistPath)
  5. ?
  6. // write
  7. var dict = [String: Any]()
  8. dict["Int"] = 1
  9. dict["Bool"] = true
  10. (dict as NSDictionary).write(toFile: plistPath, atomically: true)
  11. ?
  12. // read
  13. if let dataDict = NSDictionary(contentsOfFile: plistPath) {
  14. print(dataDict)
  15. }

  

需要注意的问题:如果需要存储自定义类型的数据需要先进行序列化。

 

 

2.NSUserDefaults

用于存储用户的偏好设置、用户信息(如用户名、是否自动登录、字体大小等)。

数据自动保存在沙盒的Libarary/Preferences 目录下。

NSUserDefaults将输入的数据储存在.plist格式的文件下,这种存储方式就决定了它的安全性几乎为0,所以不建议存储一些敏感信息如:用户密码、token、加密私钥等。

它能存储的数据类型为:NSNumber(NSInteger、float、double、BOOL),NSString,NSDate,NSArray,NSDictionary,NSData。

不支持自定义对象的存储。

需要注意的问题: 1.NSUserDefaults存储的数据都是不可变的,想将可变数据存入需要先转为不可变才可以存储。

2.NSUserDefaults是定时把缓存中的数据写入磁盘的,而不是即时写入,为了防止在写完NSUserDefaults后程序退出导致的数据丢失,可以在写入数据后使用synchronize强制立即将数据写入磁盘。

  1. /// code block:
  2. func testUserDefaults() -> Void {
  3. let standard = UserDefaults.standard
  4. standard.set(1, forKey: "Int")
  5. standard.set(true, forKey: "Bool")
  6. standard.set(1.0, forKey: "Float")
  7. standard.synchronize()// 立即存储
  8. ?
  9. if let v_int = standard.object(forKey: "Int") {
  10. print("\(v_int)")
  11. // update
  12. standard.set(2, forKey: "Int")
  13. // remove
  14. standard.removeObject(forKey: "Int")
  15. } else {
  16. print("not exist")
  17. }
  18. }

  

 

 

3.钥匙串(keychain)

Keychain在Mac上主要进行一些敏感信息存储使用 如用户名,密码,网络密码,认证令牌, Wi-Fi网络密码,VPN凭证等。 iOS 中 Keychain, 也有相同的功能实现 , 保存的信息存储在设备中, 独立于每个App沙盒之外。

当你删除APP后Keychain存储的数据不会删除,所以在重装App后,Keychain里的数据还能使用。从ios 3.0开始,跨程序分享keychain变得可行而NSUserDefaults存储的数据会随着APP而删掉。

相同的 Team ID 开发, 可实现多个App 共享数据。

使用keychain时苹果官方已经为我们封装好了文件KeychainItemWrapper,引入即可使用。

第三方库SAMKeychain。。。

  1. /// SAMKeychain 简单使用
  2. func testKeychain() -> Void {
  3. let account = "479377608"
  4. let service = "com.qq"
  5. // 检测数据是否已存
  6. if SAMKeychain.password(forService: service, account: account) != nil {
  7. print("keychain exist..")
  8. } else {
  9. // 存储
  10. if SAMKeychain.setPassword("123456", forService: service, account: account) {
  11. print("keychain set success")
  12. } else {
  13. print("keychain set failed...")
  14. }
  15. }
  16. }

  

 

4.归档(NSKeyedArchiver)

归档是iOS开发中数据存储常用的技巧,归档可以直接将对象储存成文件,把文件读取成对象。

相对于plist或者NSUserDefault形式,归档可以存储的数据类型更加多样,并且可以存取自定义对象。对象归档的文件是保密的,在磁盘上无法查看文件中的内容,更加安全。

遵守NSCoding协议,并实现该协议中的两个方法。如果是继承,则子类一定要重写那两个方法。因为子类在存取的时候,会去子类中去找调用的方法,没找到那么它就去父类中找,所以最后保存和读取的时候新增加的属性会被忽略。需要先调用父类的方法,先初始化父类的,再初始化子类的。

保存数据的文件的后缀名可以随意命名。

最大的优点是:可以将复杂的对象写入文件 可以归档集合类,所以无论添加多少对象,将对象写入磁盘的方式都是一样的,不会增加工作量。

 

 

5.沙盒(sandbox)

持久化在Document目录下,一般存储非机密数据。当App中涉及到电子书阅读、听音乐、看视频、刷图片列表等时,推荐使用沙盒存储,可以极大的节约用户流量,且增强了app的体验效果。

Application:存放程序源文件,上架前经过数字签名,上架后不可修改。

Documents: 保存应运行时生成的需要持久化的数据,iTunes同步设备时会备份该目录。例如,游戏应用可将游戏存档保存在该目录。

tmp: 保存应运行时所需的临时数据,使完毕后再将相应的文件从该目录删除。应用 没有运行时,系统也可能会清除该目录下的文件。iTunes同步设备时不会备份该目录。

Library/Caches: 保存应用运行时成的需要持久化的数据,iTunes同步设备时不会备份 该目录。一般存储体积大、不需要备份的非重要数据,比如网络数据缓存存储到Caches下

Library/Preference: 保存应用的所有偏好设置,如iOS的Settings(设置) 应会在该目录中查找应的设置信息。iTunes同步设备时会备份该目录。

  1. func testSandbox() -> Void {
  2. // app's home path
  3. let path = NSHomeDirectory()
  4. // document path
  5. let documentsPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first
  6. // cache path
  7. let cachePath = NSSearchPathForDirectoriesInDomains(.cachesDirectory, .userDomainMask, true).first
  8. // library path
  9. let libraryPath = NSSearchPathForDirectoriesInDomains(.libraryDirectory, .userDomainMask, true).first
  10. // tmp path
  11. let tmpPath = NSTemporaryDirectory()
  12. ?
  13. // write file
  14. let filePath = (cachePath! as NSString).appendingPathComponent("test.txt")
  15. let numbers = [1,2,3] as NSArray
  16. if numbers.write(toFile: filePath, atomically: true) {
  17. print("write success.")
  18. } else {
  19. print("write failed..")
  20. }
  21. ?
  22. // read file
  23. guard let readNumbers = NSArray(contentsOfFile: filePath) else {
  24. print("read failed...")
  25. return
  26. }
  27. print(readNumbers)
  28. }

  

 

6.数据库(sqllite)

适合储存数据量较大的数据,一般使用FMDB等第三方库。

FMDB是iOS平台的SQLite数据库框架,FMDB以OC的方式封装了SQLite的C语言API,使用起来更加面向对象,省去了很多麻烦、冗余的C语言代码,对比苹果自带的Core Data框架,更加轻量级和灵活,提供了多线程安全的数据库操作方法,有效地防止数据混乱。

易用性不强, 但可以存储大量数据,存储、检索大量数据非常高效;能对数据进行复杂的聚合,比使用对象执行这些操作要高效得多。

 

7.CoreData

Core Data是iOS5之后才出现的一个框架,它提供了对象-关系映射(ORM)的功能,即能够将OC对象转化成数据,保存在SQLite数据库文件中,也能够将保存在数据库中的数据还原成OC对象。在此数据操作期间,我们不需要编写任何SQL语句。

CoreData本质还是讲数据存在了SQLite数据库文件,使用不是很方便。

MagicalRecord是对CoreData的二次封装,使用起来简

原文链接:http://www.cnblogs.com/mustard22/p/11090905.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号