Swift 文件存储
一、UserDefaults存储配置信息
主要存储APP相关的配置信息、用户信息等。
示例如下:
// 存储
let user: String = "123456789"
UserDefaults.standard.set(user, forKey: "user")
// 读取
let userName: String = UserDefaults.standard.object(forKey: "user") as! String
print(userName)
UserDefaults是一个全局的单例,一般在需要存储账户信息,配置信息,这些比较简单的信息的时候,可以用它来存储。最基本的存储就是利用String的Key值去存储数据。
它实际上是一个存储在沙盒的.plist文件,只不过iOS6.0之后就没有存在常用的目录下,所以,不对系统进行破解是看不到这个文件的。
Userdefaults可以存储诸如:Data, String, NSNumber, Array, Dictionary等(这些数据类型是鄙人自己根据代码推测的,如有不对,请斧正)。
Swift是一个强类型的语言,在存储和读取的时候,切记对于类型的把握,否则容易导致代码出问题。
二、文件存储
主要存储非机密数据,比较大的数据等,如图片
示例:(存储Data数据,注意Data数据的路径的获取)
// 此代码位于do catch代码块里
let userAccountPath = NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.documentDirectory, FileManager.SearchPathDomainMask.userDomainMask, true).first!
let encoder = JSONEncoder()
if let BeerData = try? encoder.encode(myStruct) {
print(BeerData)
let url = URL.init(fileURLWithPath: userAccountPath).appendingPathComponent("userData.data")
try BeerData.write(to: url)
}
Swift4.0提供了一个类似于NSCoding的协议: Codable协议,该协议可以让开发者很方便的对Struct、class、enum进行归档、解档。
根据个人对于相关资料的查阅,Codable协议没有NSCoding协议类似的NSKeyedArchive类来进行持久化的存储。该协议的decode\encode方式,仅仅将我们的对象方便的处理为Json数据(.plist文件我没有尝试)。所以在进行持久化存储的时候,对于对象或者说是我们归档好的Json数据,我们可以根据个人需求进行存储。可以利用UserDefaults, 也可以利用上面的例子里的Data.write(to: )方法去存储。
String的存储:
let stringPath: String = NSHomeDirectory() + "/Documents/TookieString.txt"
let string: String = "存储进去的String"
// 路径遵循 StringProtocol协议
try? string.write(toFile: stringPath, atomically: true, encoding: .utf8)
print("存储的路径",stringPath)
Image的存储(类似于Data的存储)
Array的存储:
let arr: Array = ["123", "321","234"]
let arrPath = NSHomeDirectory() + "/Documents/arr.plist"
let array = NSArray.init(array: arr)
array.write(toFile: arrPath, atomically: true)
Dictnory存储类似于array的存储。
三、Codable序列化
关于这部分内容,我仅仅查阅的一些比较浅显的资料,并未去官方文档进行深入的研究,有相关升入研究的同志,还请不吝赐教
示例:
struct Swifter: Codable {
let fullName: String
let id: Int
let twitter: URL
}
// 二进制化的json数据
let json = """
{"fullName": "Federico Zanetello","id": 123456,"twitter": "http://twitter.com/zntfdr"}
""".data(using: .utf8)!
// 解档 json -> 对象
let myStruct = try JSONDecoder().decode(Swifter.self, from: json) // Decoding our data
print(myStruct) // 解档的结果
// 归档 对象 -> json数据
let userAccountPath = NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.documentDirectory, FileManager.SearchPathDomainMask.userDomainMask, true).first!
let encoder = JSONEncoder()
if let BeerData = try? encoder.encode(myStruct) {
print(BeerData) // 完成了对数据的二进制化归档
let url = URL.init(fileURLWithPath: userAccountPath).appendingPathComponent("userData.data")
try BeerData.write(to: url)
}
上述代码完成了从data到对象,对象到data的相互转化,对于Codable协议的解档和归档,均以data数据(主要在于将data持久化存储,转化为其他的数据,加密等)为核心处理。
补充:
在某些情况下,我们会将josn数据以Data的类型存储在沙盒路径下,示例代码如下:
let url = URL.init(fileURLWithPath: userAccountPath).appendingPathComponent("userData.data")
let data = try FileHandle.init(forReadingFrom: url)
let myStruct2 = try JSONDecoder().decode(Swifter.self, from: data.readDataToEndOfFile())
print(myStruct2)
这里读取文件数据用到了FileHandle这个类,该类和FileManager一起,作为iOS开发中对于文件操作的管理类。