前言:在我们开发过程中,不管是你做啥子应用,都要遇到数据的保存问题。将数据保存本地,这样让程序的运行更加流畅,不在出现小菊❀这样的╮(╯﹏╰)╭东东了,使得用户体验更好! 以下将介绍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,可以通过这里互相学习一下,共同进步 ...