Swift 数据存储

作者: 天空中的球 | 来源:发表于2015-12-24 14:52 被阅读2164次

    说到数据的保存,我们先来了解下数据存储的地址,沙箱模型的有四个文件夹,分别是:Document,AppName.app, Library,tmp

    1. Documents 目录:您应该将所有的应用程序数据文件写入到这个目录下。这个目录用于存储用户数据或其它应该定期备份的信息。

    2. AppName.app 目录:这是应用程序的程序包目录,包含应用程序的本身。由于应用程序必须经过签名,所以您在运行时不能对这个目录中的内容进行修改,否则可能会使应用程序无法启动。

    3. Library 目录:包括CachesPreferencesPreferences
      PreferencesPreferences:包含应用程序的偏好设置文件。您不应该直接创建偏好设置文件,而是应该使用NSUserDefaults类来取得和设置应用程序的偏好。
      Caches:用于存放应用程序专用的支持文件,保存应用程序再次启动过程中需要的信息。

    4. tmp 目录:这个目录用于存放临时文件,保存应用程序再次启动过程中不需要的信息。

       // Document 路径
      let documentPaths = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory,NSSearchPathDomainMask.UserDomainMask, true)
      let documnetPath = documentPaths[0] as! String
       // Library 路径
      let libraryPaths = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.LibraryDirectory,NSSearchPathDomainMask.UserDomainMask, true)
      let libraryPath = libraryPaths[0] as! String
       // Cache 路径
      let cachePaths = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.CachesDirectory,NSSearchPathDomainMask.UserDomainMask, true)
      let cachePath = cachePaths[0] as! String
       // tmp 路径
      let tmpDir = NSTemporaryDirectory()  
      

    一、 NSUserDefaults

    一般来说,我们用来保存的偏好设置都是用 NSUserDefaults中,快速简单。

    //1、 保存
     NSUserDefaults .standardUserDefaults().setObject("weNeedSaveValue", forKey: "My_Key")
     NSUserDefaults .standardUserDefaults().setBool(false, forKey: "My_IsOK")
    //2、同步 
     NSUserDefaults .standardUserDefaults() .synchronize()
     //3、取值
     NSUserDefaults.standardUserDefaults() .objectForKey("My_Key")
    

    二、NSKeyedArchiver 归档

    归档(又名序列化),把对象转为字节码,以文件的形式存储到磁盘上;程序运行过程中或者当再次重写打开程序的时候,可以通过解归档(反序列化)还原这些对象。

    首先了解下它所存在的位置上:

    var path = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomainMask.UserDomainMask, true)[0] as NSString 
    var filePath = path.stringByAppendingPathComponent("data.archive")
    

    先自定义一个数据模型

    class MyArchiveModel: NSObject,NSCoding {
        
        var name: String!
        var phone: String!
        var age: NSInteger!
        
        
        func encodeWithCoder(aCoder: NSCoder){
            aCoder.encodeObject(self.name, forKey: "name")
            aCoder.encodeObject(self.phone, forKey: "phone")
            aCoder.encodeObject(self.age, forKey: "age")
        }
        
        required init(coder aDecoder: NSCoder) {
            super.init()
            self.name = aDecoder.decodeObjectForKey("name") as! String
            self.phone = aDecoder.decodeObjectForKey("phone") as! String
            self.age = aDecoder.decodeObjectForKey("age") as! NSInteger
        }
        
        override init() {
            
        }
    }
    

    序列化

     //创建一个全局路径,即要保存的位置:
     let path = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomainMask.UserDomainMask, true)[0] as NSString
     let filePath = path.stringByAppendingPathComponent("my_Archiver")
        
     let myArchive : MyArchiveModel = MyArchiveModel()
     myArchive.name = "Yang"
     myArchive.phone = "888888"
     myArchive.age = 24
        //归档
     print("\("save")")
     NSKeyedArchiver .archiveRootObject(myArchive, toFile: filePath)
    

    反序列化

    // 之前保存的位置
    let path = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomainMask.UserDomainMask, true)[0] as NSString
    let filePath = path.stringByAppendingPathComponent("my_Archiver")
    
    let unArchive =  NSKeyedUnarchiver .unarchiveObjectWithFile(filePath) as! MyArchiveModel
    print("unArchiver===\(unArchive.name,unArchive.phone,unArchive.age)")
    // print :unArchiver===("Yang", "888888", 24)
    

    相对 NSUserDefaults 来说,速度慢些,但是可以保存自定义类型的

    三、CoreData

    Core Date是ios3.0后引入的数据持久化解决方案,它是是苹果官方推荐使用的,不需要借助第三方框架。Core Date实际上是对SQLite的封装,提供了更高级的持久化方式。在对数据库操作时,不需要使用sql语句,也就意味着即使不懂sql语句,也可以操作数据库中的数据。

    简单点说,Core Data实际上是将数据库的创建、表的创建、对象和表的转换等操作封装起来,极大的简化了我们的操作。

    下面简单的运用下:

    3-1、建立项目,勾选上coreData

    项目创建成功后,会在AppDelegate类中自动添加相关代码,此外,还会自动生成一个数据模型文件JRCoreData.xcdatamodeld

    建立项目,勾选上coreData

    3-2、添加实体

    建立实体

    3-3、生成同名的类

    添加类 勾选1 勾选2 效果

    3-4、代码中的实现
    先导入

      import CoreData
    

    然后分别从 保存、获取、删除、修改

    override func viewDidLoad() {
        super.viewDidLoad()
        
        self .insertTheData()
        
        // 3秒之后获取
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW,
            Int64(0.5 * Double(NSEC_PER_SEC))), dispatch_get_main_queue()) {
                
                self .findTheData()
                
        }
        
        // Do any additional setup after loading the view, typically from a nib.
    }
    
    func insertTheData()
    {
        // 获取管理数据的上下文  对象
        let app = UIApplication.sharedApplication().delegate as! AppDelegate
        let context = app.managedObjectContext
        
        let user = NSEntityDescription.insertNewObjectForEntityForName("User", inManagedObjectContext: context) as! User
    
        user.name = "Yang"
        user.password = "123456"
        user.id = "01"
    
        do {
            try context .save()
    
        }
        catch{
            print("\("save failed")")
        }
        
        
        
    }
    
    func findTheData()
    {
        //获取管理的数据上下文 对象
        let app = UIApplication.sharedApplication().delegate as! AppDelegate
        let context = app.managedObjectContext
    
        //声明数据的请求
        let fetchRequest:NSFetchRequest = NSFetchRequest()
        fetchRequest.fetchLimit = 10 //限定查询结果的数量
        fetchRequest.fetchOffset = 0 //查询的偏移量
        
        //声明一个实体结构
        let entity:NSEntityDescription? = NSEntityDescription.entityForName("User",
           inManagedObjectContext: context)
       //设置数据请求的实体结构
        fetchRequest.entity = entity
      
        //设置查询条件
        let predicate = NSPredicate(format: "id= '01'", "")
        fetchRequest.predicate = predicate
       
        //查询操作
    
        var fetchedObjects :[AnyObject]?
        
        do{
           fetchedObjects =  try context .executeFetchRequest(fetchRequest)
        }
        catch{
            print("\("have problem")")
        }
        
      
        
        //遍历查询的结果
        
         for info:User in fetchedObjects as! [User]
         {
            print("id=\(info.id)")
            print("username=\(info.name)")
            print("password=\(info.password)")
         }
        
    
        //遍历查询的结果
         for info:User in fetchedObjects as! [User]{
            //修改密码
                info.password = "002221"
            //重新保存
            do{
               try context.save()
            }
            catch{
                print("save Failed")
            }
         
          }
        
        
          for info:User in fetchedObjects as! [User]{
                //删除对象
                context.deleteObject(info)
           }
    }
    

    当然,要熟练掌握和更加理解CoreData,多使用几次才行。
    陆续添加中····

    备注:
    https://developer.apple.com/library/ios/documentation/Cocoa/Reference/CoreData_ObjC/index.html#//apple_ref/doc/uid/TP40001181
    http://www.cnblogs.com/iCocos/p/4672168.html

    相关文章

      网友评论

      • 我本善良:swift有类似的运行时吗?能让遵循NSCoding的协议都自动code和decode,类似OC下MJ写了个类别通过运行时支持NSCoding,这样每个类自动完成了NSCoding。有好的方法没?
        天空中的球:@我本善良 Swift 这块我个人用的少,你可以参考下这篇文章:http://www.infoq.com/cn/articles/dynamic-analysis-of-runtime-swift?utm_source=infoq&utm_campaign=user_page&utm_medium=link

      本文标题:Swift 数据存储

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