Swift数据存储(一)

96
叫我干苦力的码农
2016.06.13 13:38* 字数 725

前言:在我们开发过程中,不管是你做啥子应用,都要遇到数据的保存问题。将数据保存本地,这样让程序的运行更加流畅,不在出现小菊❀这样的╮(╯﹏╰)╭东东了,使得用户体验更好! 以下将介绍NSUserDefaults/ NSKeyedArchiver/ write写入方式.

文件操作知识临时充饥看我上篇文章:Swift文件管理必知的一些操作

1.使用NSUserDefaults存储数据

NSUserDefaults:一般我们拿它用来保存应用程序设置和属性、用户保存的数据,用户的手机不管是关机or开机时候都会保存在本地(除非你把他删除了),它一般可以存储类型包括:字符,数组,字典,NSData,NSNumber以及基本数据类型都可.那就来看看咋的实现它吧!
这里我简单的对其简单封装了一下方法,我就直接贴代码了,重要位置我都加了注释(ps:想看比较全面的可以参考这篇文章Swift之一步一步带你封装一个本地缓存库):

    /*  使用NSUserDefaults对普通数据对象储存   */
    
    /**
     储存
     
     - parameter key:   key
     - parameter value: value
     */
    class func setNormalDefault(key:String, value:AnyObject?){
        if value == nil {
            NSUserDefaults.standardUserDefaults().removeObjectForKey(key)
        }
        else{
            NSUserDefaults.standardUserDefaults().setObject(value, forKey: key)
            // 同步
            NSUserDefaults.standardUserDefaults().synchronize()
        }
    }
    
    /**
     通过对应的key移除储存
     
     - parameter key: 对应key
     */
    class func removeNormalUserDefault(key:String?){
        if key != nil {
            NSUserDefaults.standardUserDefaults().removeObjectForKey(key!)
            NSUserDefaults.standardUserDefaults().synchronize()
        }
    }
    
    /**
     通过key找到储存的value
     
     - parameter key: key
     
     - returns: AnyObject
     */
    class func getNormalDefult(key:String)->AnyObject?{
        return NSUserDefaults.standardUserDefaults().valueForKey(key)
    }
  

下面举个简单 looklook

private func userDefaultStoreData(){
        Tool.setNormalDefault("name", value: "Rookie")
        let value = Tool.getNormalDefult("name")
        print("测试NSUserDefaults 简单对象储存\\(value)")
    }

//   控制台输出: **测试****NSUserDefaults ****简单对象储存****Optional(Rookie)**

2.通过write写入方式存储为plist属性列表
write写入方式也是一种把数据永久保存在磁盘中储存方式,一般步骤:1)获取路径(一般有两种方式:使用NSSearchPathForDirectoriesInDomains或URLsForDirectory;使用NSHomeDirectory➕相应的路径);2)向文件中写入数据;3)从文件中读取数据. 具体代码如下:

    /**
     创建文件
     
     - parameter name:        文件名
     - parameter fileBaseUrl: url
     
     - returns: 文件路径
     */
   class func creatNewFiles(name:String, fileBaseUrl:NSURL) -> String{
        let manager = NSFileManager.defaultManager()
        let file = fileBaseUrl.URLByAppendingPathComponent(name)
        
        let exist = manager.fileExistsAtPath(file.path!)
        if !exist {
            let createFilesSuccess = manager.createFileAtPath(file.path!, contents: nil, attributes: nil)
            print("文件创建结果: \\(createFilesSuccess)")
        }
        return String(file)
    }
    
    /**
     读取文件
     
     - parameter name:        文件名
     - parameter fileBaseUrl: url
     
     - returns: 读取数据
     */
    class func readTheFlies(name:String , fileBaseUrl:NSURL) ->NSString{
        let file = fileBaseUrl.URLByAppendingPathComponent(name)
       //  print(file)
        let readHandler = try! NSFileHandle(forReadingFromURL:file)
        let data = readHandler.readDataToEndOfFile()
        let readString = NSString(data: data, encoding: NSUTF8StringEncoding)
        return readString!
    }

实现 如下:

// MARK:-  存储plist属性列表
    private func savePlistFiles(){
        // 储存的沙盒路径
        let manager = NSFileManager.defaultManager()
        let urlForCatch = manager.URLsForDirectory(NSSearchPathDirectory.CachesDirectory, inDomains: NSSearchPathDomainMask.UserDomainMask)
        let url = urlForCatch.first! as NSURL
        let fileName = "RookieSon.plist"
        // 创建文件
        let filesPath = Tool.creatNewFiles(fileName, fileBaseUrl: url)
        // 储存数据
        let saveDataInfo = NSMutableArray()
        saveDataInfo.addObject("我的剑,就是你的剑")
        saveDataInfo.addObject("我用双手成就你的梦想")
        saveDataInfo.addObject("纵然前路迷茫,纵然天隔一方,纵然我手中的刀刃已然破碎,也无法阻挡我寻找你的道路")
        //        print(saveDataInfo)
        // 写入文件
        saveDataInfo.writeToURL(NSURL(string: filesPath)!, atomically: true)
        
        // 读取文件
        let readDataInfo = Tool.readTheFlies(fileName, fileBaseUrl: url)
        print(readDataInfo)
    }

/* 打印结果: 
**<plist version="1.0">**
**<array>**
** <string>****我的剑****,****就是你的剑****</string>**
** <string>****我用双手成就你的梦想****</string>**
** <string>****纵然前路迷茫,纵然天隔一方,纵然我手中的刀刃已然破碎,也无法阻挡我寻找你的道路****</string>**
**</array>**
**</plist>**
*/

3.NSKeyedArchiver采用归档的形式来保存数据
NSKeyedArchiver保存数据对象需要遵守NSCoding协议,并且该对象对应的类必须提供encodeWithCoder:和initWithCoder:方法,简单的说就是告诉系统怎么对对象进行编码,怎么对对象进行解码. 下面就对Person这个对象进行归档保存:
Person.m文件:

class Person: NSObject {
    
    var name:String?
    var phone:String?
    
    // 构造方法
    init(name:String!,phone:String!) {
        self.name = name
        self.phone = phone
        
        super.init()
    }
    
    // 从NSObject解析回来
    
    init(coder aDecoder:NSCoder!){
        self.name=aDecoder.decodeObjectForKey("name") as? String
        self.phone=aDecoder.decodeObjectForKey("phone") as? String
    }
    
    //编码成object,哪些属性需要归档,怎么归档
    func encodeWithCoder(aCoder:NSCoder!){
        aCoder.encodeObject(name,forKey:"name")
        aCoder.encodeObject(phone,forKey:"phone")
    }
    
}

实现部分代码如下:

 private func  archiveSaveDataInfo(){
    // 储存自定义对象
    let userDefault = NSUserDefaults.standardUserDefaults()
    let mo = Person(name: "RookieYX", phone: "123456")
    // 实例对象转化成NSData
    let moData:NSData = NSKeyedArchiver.archivedDataWithRootObject(mo)
    // 储存NSData对象
    userDefault.setObject(moData, forKey: "myMo")
    // 自定义对象读取
    let myMoData = userDefault.objectForKey("myMo") as! NSData
    // 解档
    let myM= NSKeyedUnarchiver.unarchiveObjectWithData(myMoData) as! Person
    print(myM)

    }

/*
打印结果:
**<SwiftUserDefault.Person: 0x7fd958518450>**
**person ****名字****: Optional("Rookie")**
**person ****电话****: Optional("123456")**
*/

看了以上写的东西,我相信你已经对这三种简单的存储有了初步理解,那么我们就来检查一下自己的学习的知识吧,我们现在做一个简单的网络图片的本地缓存处理. 你可以先想一下,在继续看下去吧(⊙o⊙)…!(具体我直接贴代码)
函数实现部分:

    /**
     传递一个uiimageView,和图片路径,设置图片,异步操作
     
     - parameter newsImageView: UIImageView
     - parameter imageString:   网络图片地址
     */
   class func setImagesViewData(newsImageView:UIImageView,imageString:String){
        // 获取文件路径
        var catePath = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.CachesDirectory,NSSearchPathDomainMask.AllDomainsMask, true)
        print(catePath)
        let cateImagesUrl:NSURL = NSURL(fileURLWithPath: "\\(catePath.first)/\\(imageString.Rookie_MD5())")//获取缓存加密后的路径
        
        //缓存存在直接加载
        if let cateReadData:NSData  = NSData(contentsOfURL: cateImagesUrl){
            newsImageView.image = UIImage(data: cateReadData);
        }
        else{
            newsImageView.image = UIImage(named: "load.jpg");//默认图片
            //这里我们做个异步处理,用来加载图片
            let session = NSURLSession.sharedSession();
            let task = session.dataTaskWithURL(NSURL(string: imageString)!, completionHandler: { (imageData:NSData?, resp:NSURLResponse?, error:NSError?) in
                if let error = error {
                    print("连接网络失败1:\\(error)");
                }else{
                    // 当我们加载完数据了回主线程修改图片
                    if let endImageData = imageData{
                        dispatch_sync(dispatch_get_main_queue(), {
                            newsImageView.image = UIImage(data: endImageData)
                        })
                        // 写入本地
                        endImageData.writeToURL(cateImagesUrl, atomically: true)
                    }
                }
            })
            
            // 启动任务
            task.resume()
        }
    }
    

实现部分代码:

 private func cacheIntenetImage(){
        Tool.setImagesViewData(ImgView, imageString: URL)
    }

希望通过这篇文章可以对你有所帮助,因为我们在Swift学习之路上,如有错误之处,还请各位大 指出! ! 之后将会学习其他的数据存储方式,总结好之后也会更新在博客上, 有要学习的同学,可以关注一下me,可以通过这里互相学习一下,共同进步 ...

Swift学习笔记
Web note ad 1