引言
在 iOS 之网络恳求 一文中已经了解到怎么进行网络恳求,当经过网络恳求获取到数据后需求将其耐久性地存储起来时,就需求了解在iOS 开发
中怎么进行耐久性地存储数据
在iOS 开发
中对数据进行耐久性地存储的方法首要有:本地存储
和数据库存储
本地存储
本地存储
是指将数据存储在设备的本地文件体系上,使运用程序能够在没有互联网衔接的情况下拜访和操作数据。本地存储一般用于存储非敏感
和小规模
的信息
UserDefaults
一种轻量级的本地存储方法,用于存储少量的键值对
数据。一般用于存储运用的偏好设置和用户装备
UserDefaults
是一个单例方法
的类,经过.standard
特点来拜访运用程序中的仅有UserDefaults 实例
。这使得在整个运用程序中方便地同享和拜访数据
// 存储数据到UserDefaults
let datas = UserDefaults.standard
datas.set("JohnDoe", forKey: "Username")
datas.set(25, forKey: "Age")
datas.set(true, forKey: "IsLoggedIn")
// 读取数据从UserDefaults
let username = datas.string(forKey: "Username")
let age = datas.integer(forKey: "Age")
let isLoggedIn = datas.bool(forKey: "IsLoggedIn")
当从UserDefaults
中读取数据时,需求依据数据类型
来正确读取数据。假如尝试运用不匹配的类型来读取数据,可能会导致运行时过错或回来默认值(假如设置了默认值)
经典单例方法结构
class MySingleton {
static let shared = MySingleton()
private init() {
// 私有的初始化办法,确保不能在外部创立多个实例
}
// 这儿能够添加其他特点和办法
}
单例方法的经典结构包含一个私有的构造办法
和一个公共的静态特点(或办法)
,用于拜访仅有实例
UserDefaults 单例方法
UserDefaults
的完成方法与经典单例方法类
的结构略有不同。UserDefaults
是Swift 规范库
供给的一个类,它是一个全局单例
,其完成方法不同于传统的单例方法,而是经过Swift 规范库
内部进行办理的,不需求手动完成单例方法
。只需求运用UserDefaults.standard
来拜访全局的单例实例
,而不需求自己创立单例。这是Swift规范库为了方便数据耐久化存储而供给的一种机制,它隐藏了单例方法
的杂乱性
open class UserDefaults : NSObject {
open class var standard: UserDefaults { get }
}
Plists
全称Property Lists
,一种用于存储和序列化数据的XML
或二进制
文件格局,一般以.plist
文件扩展名保存
Plists
文件一般是经过键-值(key-value)
的方法来存储各种类型的数据。每个数据项都有一个仅有的键(key)
,用于标识该数据项,然后依据键来获取对应的值。这种结构适用于存储字典、数组、字符串、整数、浮点数等多种数据类型
Plists
可用于存储结构化的数据,例如装备文件、运用设置、静态数据等
// 创立一个字典,包含要保存到 Plist 文件的数据
let dataToSave: [String: Any] = [
"Username": "JohnDoe",
"Age": 25,
"IsLoggedIn": true
]
// 获取 Plist 文件的 URL,一般是在运用的沙盒目录中
if let plistURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first?.appendingPathComponent("UserData.plist") {
do {
// 将数据写入 Plist 文件,运用 PropertyListSerialization
let plistData = try PropertyListSerialization.data(fromPropertyList: dataToSave, format: .xml, options: 0)
try plistData.write(to: plistURL)
print("Data saved to \(plistURL)")
// 从 Plist 文件读取数据
let plistDataRead = try Data(contentsOf: plistURL)
if let dictionary = try PropertyListSerialization.propertyList(from: plistDataRead, options: [], format: nil) as? [String: Any] {
if let username = dictionary["Username"] as? String {
print("Username: \(username)")
}
if let age = dictionary["Age"] as? Int {
print("Age: \(age)")
}
if let isLoggedIn = dictionary["IsLoggedIn"] as? Bool {
print("IsLoggedIn: \(isLoggedIn)")
}
}
} catch {
print("Error writing to Plist: \(error)")
}
}
拓展
Plist
文件的数据类型:
- 假如将文件扩展名设置为
.plist
,则数据将存储为XML 格局
的Plist
文件 - 假如将文件扩展名设置为
.bplist
,则数据将存储为二进制格局
的Plist
文件
PropertyListSerialization.data(fromPropertyList: dataToSave, format: .xml, options: 0)
处的format
用于指定输出的格局,有.xml
和.binary
两个值,这儿的数据格局不会影响数据写入文件时的实际格局,写入文件的数据类型是与扩展名相关
Archiver
Archiver
是将目标序列化为二进制数据,并将其保存在文件中的过程,以便后续能够复原成原始目标。在iOS 开发
中,能够运用NSKeyedArchiver
和NSKeyedUnarchiver
类来进行归档
和反归档
操作
归档的步骤
- 创立要归档的目标:首要,你需求创立一个自定义的类,该类需求遵循
NSCoding
协议,这个协议要求完成encode(with:)
和init(coder:)
办法,以便目标能够被归档
和反归档
- 归档目标:运用
NSKeyedArchiver
类的实例,能够将目标归档
为二进制数据
并将其保存到文件中 - 反归档目标:运用
NSKeyedUnarchiver
类的实例,能够从文件中读取归档数据,并将其解析
为原始目标
1. 创立要归档的目标
class Person: NSObject, NSCoding {
var name: String
var age: Int
init(name: String, age: Int) {
self.name = name
self.age = age
}
// 完成NSCoding协议的办法
required init?(coder aDecoder: NSCoder) {
self.name = aDecoder.decodeObject(forKey: "name") as! String
self.age = aDecoder.decodeInteger(forKey: "age")
}
func encode(with aCoder: NSCoder) {
aCoder.encode(name, forKey: "name")
aCoder.encode(age, forKey: "age")
}
}
2. 归档
let person = Person(name: "John", age: 30)
let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
let archiveURL = documentsDirectory.appendingPathComponent("person.archive")
do {
let data = try NSKeyedArchiver.archivedData(withRootObject: person, requiringSecureCoding: false)
try data.write(to: archiveURL)
print("Person object archived successfully.")
} catch {
print("Error archiving person object: \(error)")
}
3. 反归档
do {
let data = try Data(contentsOf: archiveURL)
if let loadedPerson = try NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(data) as? Person {
print("Loaded person: \(loadedPerson.name), Age: \(loadedPerson.age)")
} else {
print("Failed to unarchive person object.")
}
} catch {
print("Error loading person object: \(error)")
}
数据库存储
数据库存储
是指将数据存储在结构化数据库中,以便有效地查询、检索和办理数据。这种方法适用于需求大规模数据存储
和杂乱查询的情况
,例如运用程序中的用户数据、购物车数据等
CoreData
:苹果供给的一个高档耐久性结构,供给目标联系映射(ORM)
功用,适用于杂乱的数据模型
SQLite
:轻量级嵌入式联系型数据库
,适用于杂乱的数据结构和查询需求
第三方数据库:运用第三方数据库解决计划,如Realm
、Firebase Realtime Database
、Couchbase Lite
等
耐久化存储计划比照
UserDefaults 和 Plists 比照
相似之处
-
键-值存储:
Plist
和UserDefaults
都采用了键-值(key-value)
的存储方法,其中每个数据项都有一个仅有的键用于标识 - 支持多种数据类型: 两者都支持存储多种数据类型,包含字符串、整数、浮点数、数组、字典等
-
耐久性存储:
Plist
和UserDefaults
都支持将数据耐久性地存储在设备上,以便在运用程序从头启动后保存数据
关键差异
-
存储位置:
Plist
一般是存储在运用的沙盒目录
中的文件,能够轻松地创立、读取和修改;UserDefaults
则是一个键值对存储体系
,运用更高档的 API
进行拜访 -
数据规模:
Plist
一般用于存储较大或结构化的数据;UserDefaults
一般用于存储运用的用户设置和轻量级数据 -
拜访方法:
Plist
需求手动读取和写入,一般需求运用PropertyListSerialization API
进行操作;UserDefaults
则供给了更高档别的 API
,使数据的读取和写入愈加方便
Plists 和 Archiver 比照
-
Archiver
:适用于保存自定义目标
、杂乱数据模型
、运用状态信息
等需求保存目标类型信息的场景。归档
能够将整个目标图保存到文件中,以便康复目标的状态 -
Plists
:适用于保存简单的数据结构
,如键-值对、装备信息、用户偏好设置等。Plists
不适用于保存自定义目标
,由于它不会保存目标的类信息
总之,Plist
和Archiver
都能够保存二进制数据
,但是Plist
不具备主动解析并复原自定义目标的功用,而归档(Archiver)
会保存目标的类信息
,使康复愈加容易
拓展
open 和 public 关键字
open
和 public
是Swift中的拜访控制关键字,它们用于控制类、结构体、函数、特点等成员的可见性和拜访权限。它们之间的首要差异在于拜访等级和承继性:
-
open
: 运用open
关键字润饰的成员具有最高档别的拜访权限
,对于其他模块(结构或库)来说是可见的,并且能够被承继
。这意味着其他模块能够扩展和承继open
成员。一般,open
用于创立可扩展的公共接口
,以便其他开发者能够承继和扩展 -
public
: 运用public
关键字润饰的成员也对其他模块可见,但不具有承继性
。这意味着其他模块能够拜访public
成员,但不能承继或重写
沙盒目录
沙盒目录(Sandbox Directory)
是iOS 运用程序
的私有文件体系空间
,每个iOS 运用
都有自己的独立沙盒目录
,用于存储运用程序的数据和文件。沙盒目录
的概念是为了确保运用程序之间的阻隔性
和安全性
,防止一个运用程序拜访其他运用程序的数据或文件
iOS 的文件体系
会依据运用程序
的包标识符
为每个运用程序创立一个独立的沙盒目录
。这意味着不同运用程序的沙盒目录
是相互阻隔的,一个运用程序无法直接拜访另一个运用程序的沙盒目录
内的文件
沙盒目录包含的首要文件夹
-
Documents 目录: 用于存储
用户生成的文件
,例如文档、照片、视频等。这些文件会在运用程序备份时被包含在备份中,并能够经过iCloud
同享 -
Library 目录: 该目录包含两个子目录
-
Caches 目录: 用于存储能够从头生成的
临时数据
,例如缓存文件。这些文件不会在运用程序备份时被包含在备份中,由于它们能够随时从头生成 -
Preferences 目录: 用于存储运用程序的
偏好设置
,一般以plist 文件
的方法存在
-
Caches 目录: 用于存储能够从头生成的
-
tmp 目录: 用于存储
临时文件
,这些文件不会被运用程序备份,且在运用程序退出后可能会被删除 -
运用程序包目录: 包含了运用程序的
可执行文件
和资源文件
,一般不允许在运行时修改这个目录中的文件
// 获取路径
// for: .documentDirectory, .libraryDirectory, .cachesDirectory, .preferencePanesDirectory
FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first{}
小结
关于iOS 开发
中关于数据耐久化
部分,首要是以本地存储数据
为主,比照说明晰UserDefaults
、Plists
和Archiver
这三种本地存储的方法;对于数据库存储
仅是做了简要概述,感兴趣能够深化了解,后面假如有用到也会更新相关文章的~~