iOS中的數(shù)據(jù)持久化的方式有哪些?
在iOS開發(fā)中,數(shù)據(jù)持久化是指將應(yīng)用中的數(shù)據(jù)存儲到本地,使得數(shù)據(jù)在應(yīng)用關(guān)閉后仍然可以保留。數(shù)據(jù)持久化是移動應(yīng)用開發(fā)中非常重要的一部分,它可以幫助我們保存用戶的設(shè)置、緩存數(shù)據(jù)、本地化存儲等。本文將介紹iOS中常用的數(shù)據(jù)持久化方式,并通過實際案例來演示它們的用法。

1. 數(shù)據(jù)持久化方式概覽
iOS中常用的數(shù)據(jù)持久化方式有以下幾種:
屬性列表(Property List,plist)
歸檔(Archiving)
SQLite數(shù)據(jù)庫
Core Data
User Defaults
文件存儲(File Storage)
Keychain
每種方式都適用于不同的場景和數(shù)據(jù)類型,接下來我們將詳細介紹每種方式的使用方法和特點。
2. 屬性列表(Property List,plist)
屬性列表是一種輕量級的數(shù)據(jù)持久化方式,適用于保存簡單的數(shù)據(jù)結(jié)構(gòu),例如NSDictionary、NSArray等。屬性列表以plist文件的形式存儲,可以存儲的數(shù)據(jù)類型包括字符串、數(shù)字、日期、字典和數(shù)組等。
使用步驟:
將數(shù)據(jù)存儲為NSDictionary或NSArray類型。
let?data:?[String:?Any]?=?["name":?"John",?"age":?30,?"isVIP":?true]
獲取應(yīng)用的沙盒路徑,并拼接plist文件名。
guard?let?documentsDirectory?=?FileManager.default.urls(for:?.documentDirectory,?in:?.userDomainMask).first?else?{
?return
}
let?fileURL?=?documentsDirectory.appendingPathComponent("data.plist")
將數(shù)據(jù)寫入plist文件。
(data?as?NSDictionary).write(to:?fileURL,?atomically:?true)
從plist文件讀取數(shù)據(jù)。
if?let?loadedData?=?NSDictionary(contentsOf:?fileURL)?as??[String:?Any]?{
?// 處理讀取到的數(shù)據(jù)
}
代碼示例:
// 存儲數(shù)據(jù)
let?data:?[String:?Any]?=?["name":?"John",?"age":?30,?"isVIP":?true]
guard?let?documentsDirectory?=?FileManager.default.urls(for:?.documentDirectory,?in:?.userDomainMask).first?else?{
?return
}
let?fileURL?=?documentsDirectory.appendingPathComponent("data.plist")
(data?as?NSDictionary).write(to:?fileURL,?atomically:?true)
// 讀取數(shù)據(jù)
if?let?loadedData?=?NSDictionary(contentsOf:?fileURL)?as??[String:?Any]?{
?print(loadedData)?// ["name": "John", "age": 30, "isVIP": 1]
}
3. 歸檔(Archiving)
歸檔是一種將對象轉(zhuǎn)換為二進制數(shù)據(jù),并將其存儲到文件中的方式。它適用于保存自定義的對象或復(fù)雜的數(shù)據(jù)結(jié)構(gòu),例如自定義的數(shù)據(jù)模型。歸檔的優(yōu)勢在于可以保存多個對象及其層次結(jié)構(gòu),以及相關(guān)的屬性和關(guān)聯(lián)關(guān)系。
使用步驟:
讓自定義的對象遵循
Codable
協(xié)議,實現(xiàn)編碼和解碼方法。
class?Person:?Codable?{
?var?name:?String
?var?age:?Int
?
?init(name:?String,?age:?Int)?{
??? ?self.name?=?name
??? ?self.age?=?age
?}
?
?// 實現(xiàn)編碼和解碼方法
}
將對象轉(zhuǎn)換為二進制數(shù)據(jù)并存儲到文件中。
let?person?=?Person(name:?"John",?age:?30)
let?fileURL?=?// 獲取文件URL
let?data?=?try??JSONEncoder().encode(person)
try??data?.write(to:?fileURL)
從文件中讀取二進制數(shù)據(jù)并解碼為對象。
let?fileURL?=?// 獲取文件URL
let?data?=?try??Data(contentsOf:?fileURL)
let?person?=?try??JSONDecoder().decode(Person.self,?from:?data)
代碼示例:
// 存儲數(shù)據(jù)
class?Person:?Codable?{
?var?name:?String
?var?age:?Int
?
?init(name:?String,?age:?Int)?{
??? ?self.name?=?name
??? ?self.age?=?age
?}
}
let?person?=?Person(name:?"John",?age:?30)
let?fileURL?=?// 獲取文件URL
let?data?=?try??JSONEncoder().encode(person)
try??data?.write(to:?fileURL)
// 讀取數(shù)據(jù)
let?fileURL?=?// 獲取文件URL
let?data?=?try??Data(contentsOf:?fileURL)
let?person?=?try??JSONDecoder().decode(Person.self,?from:?data)
4. SQLite數(shù)據(jù)庫
SQLite是一種輕量級的嵌入式數(shù)據(jù)庫,適用于存儲結(jié)構(gòu)化的數(shù)據(jù)。iOS中可以通過FMDB
等第三方庫來方便地使用SQLite數(shù)據(jù)庫。
使用步驟:
導(dǎo)入
FMDB
庫。
import?FMDB
打開數(shù)據(jù)庫并創(chuàng)建表。
let?fileURL?=?// 獲取數(shù)據(jù)庫文件URL
let?database?=?FMDatabase(url:?fileURL)
if?database.open()?{
?let?createTableSQL?=?"CREATE TABLE IF NOT EXISTS person (id INTEGER PRIMARY KEY, name TEXT, age INTEGER)"
?try??database.executeUpdate(createTableSQL,?values:?nil)
?database.close()
}
插入數(shù)據(jù)。
let?fileURL?=?// 獲取數(shù)據(jù)庫文件URL
let?database?=?FMDatabase(url:?fileURL)
if?database.open()?{
?let?insertSQL?=?"INSERT INTO person (name, age) VALUES (?, ?)"
?try??database.executeUpdate(insertSQL,?values:?["John",?30])
?database.close()
}
查詢數(shù)據(jù)。
let?fileURL?=?// 獲取數(shù)據(jù)庫文件URL
let?database?=?FMDatabase(url:?fileURL)
if?database.open()?{
?let?querySQL?=?```swift
let?querySQL?=?"SELECT * FROM person"
let?resultSet?=?try??database.executeQuery(querySQL,?values:?nil)
while?resultSet?.next()?==?true?{
?let?name?=?resultSet?.string(forColumn:?"name")????""
?let?age?=?resultSet?.int(forColumn:?"age")????0
?print("Name: \(name), Age: \(age)")
}
database.close()
代碼示例:
// 導(dǎo)入FMDB庫
import?FMDB
// 打開數(shù)據(jù)庫并創(chuàng)建表
let?fileURL?=?// 獲取數(shù)據(jù)庫文件URL
let?database?=?FMDatabase(url:?fileURL)
if?database.open()?{
?let?createTableSQL?=?"CREATE TABLE IF NOT EXISTS person (id INTEGER PRIMARY KEY, name TEXT, age INTEGER)"
?try??database.executeUpdate(createTableSQL,?values:?nil)
?database.close()
}
// 插入數(shù)據(jù)
let?fileURL?=?// 獲取數(shù)據(jù)庫文件URL
let?database?=?FMDatabase(url:?fileURL)
if?database.open()?{
?let?insertSQL?=?"INSERT INTO person (name, age) VALUES (?, ?)"
?try??database.executeUpdate(insertSQL,?values:?["John",?30])
?database.close()
}
// 查詢數(shù)據(jù)
let?fileURL?=?// 獲取數(shù)據(jù)庫文件URL
let?database?=?FMDatabase(url:?fileURL)
if?database.open()?{
?let?querySQL?=?"SELECT * FROM person"
?let?resultSet?=?try??database.executeQuery(querySQL,?values:?nil)
?while?resultSet?.next()?==?true?{
??? ?let?name?=?resultSet?.string(forColumn:?"name")????""
??? ?let?age?=?resultSet?.int(forColumn:?"age")????0
??? ?print("Name: \(name), Age: \(age)")
?}
?database.close()
}
5. Core Data
Core Data是蘋果提供的一種對象圖管理框架,它提供了一種將對象模型與持久化存儲進行映射的方式。使用Core Data可以輕松地管理應(yīng)用中的數(shù)據(jù)模型,實現(xiàn)數(shù)據(jù)的增刪改查。
使用步驟:
在Xcode中創(chuàng)建Core Data模型文件,并定義數(shù)據(jù)模型。
生成NSManagedObject子類。
插入數(shù)據(jù)。
let?appDelegate?=?UIApplication.shared.delegate?as!?AppDelegate
let?context?=?appDelegate.persistentContainer.viewContext
let?person?=?NSEntityDescription.insertNewObject(forEntityName:?"Person",?into:?context)?as!?Person
person.name?=?"John"
person.age?=?30
try??context.save()
查詢數(shù)據(jù)。
let?appDelegate?=?UIApplication.shared.delegate?as!?AppDelegate
let?context?=?appDelegate.persistentContainer.viewContext
let?fetchRequest?=?NSFetchRequest<Person>(entityName:?"Person")
let?persons?=?try??context.fetch(fetchRequest)
for?person?in?persons????[]?{
?print("Name: \(person.name????""), Age: \(person.age)")
}
代碼示例:
// 插入數(shù)據(jù)
let?appDelegate?=?UIApplication.shared.delegate?as!?AppDelegate
let?context?=?appDelegate.persistentContainer.viewContext
let?person?=?NSEntityDescription.insertNewObject(forEntityName:?"Person",?into:?context)?as!?Person
person.name?=?"John"
person.age?=?30
try??context.save()
// 查詢數(shù)據(jù)
let?appDelegate?=?UIApplication.shared.delegate?as!?AppDelegate
let?context?=?appDelegate.persistentContainer.viewContext
let?fetchRequest?=?NSFetchRequest<Person>(entityName:?"Person")
let?persons?=?try??context.fetch(fetchRequest)
for?person?in?persons????[]?{
?print("Name: \(person.name????""), Age: \(person.age)")
}
6. User Defaults
User Defaults是iOS提供的一種簡單的數(shù)據(jù)持久化方式,適用于保存應(yīng)用的配置信息和用戶偏好設(shè)置。
使用步驟:
使用UserDefaults對象來存儲和讀取數(shù)據(jù)。
let?userDefaults?=?UserDefaults.standard
userDefaults.set("John",?forKey:?"name")
userDefaults.set(30,?forKey:?"age")
userDefaults.synchronize()
讀取數(shù)據(jù)。
let?userDefaults?=?UserDefaults.standard
let?name?=?userDefaults.string(forKey:?"name")????""
let?age?=?userDefaults.integer(forKey:?"age")
print("Name: \(name), Age: \(age)")
代碼示例:
// 存儲數(shù)據(jù)
let?userDefaults?=?UserDefaults.standard
userDefaults.set("John",?forKey:?"name")
userDefaults.set(30,?forKey:?"age")
userDefaults.synchronize()
// 讀取數(shù)據(jù)
let?userDefaults?=?UserDefaults.standard
let?name?=?userDefaults.string(forKey:?"name")????""
let?age?=?userDefaults.integer(forKey:?"age")
print("Name: \(name), Age: \(age)")
7. 文件存儲(File Storage)
文件存儲是一種將數(shù)據(jù)以文件的形式保存在沙盒目錄下的方式,適用于存儲大量的非結(jié)構(gòu)化數(shù)據(jù),例如圖片、音頻和視頻等。
使用步驟:
獲取文件在沙盒中的路徑。
guard?let?documentsDirectory?=?FileManager.default.urls(for:?.documentDirectory,?in:?.userDomainMask).first?else?{
?return
}
let?fileURL?=?documentsDirectory.appendingPathComponent("data.txt")
將數(shù)據(jù)寫入文件。
let?data?=?"Hello, World!".data(using:?.utf8)
try??data?.write(to:?fileURL)
從文件中讀取數(shù)據(jù)。
let?data?=?try??Data(contentsOf:?fileURL)
let?content?=?String(data:?data????Data(),?encoding:?.utf8)????""
print(content)?// "Hello, World!"
代碼示例:
// 存儲數(shù)據(jù)
guard?let?documentsDirectory?=?FileManager.default.urls(for:?.documentDirectory,?in:?.userDomainMask).first?else?{
?return
}
let?fileURL?=?documentsDirectory.appendingPathComponent("data.txt")
let?data?=?"Hello, World!".data(using:?.utf8)
try??data?.write(to:?fileURL)
// 讀取數(shù)據(jù)
let?data?=?try??Data(contentsOf:?fileURL)
let?content?=?String(data:?data????Data(),?encoding:?.utf8)????""
print(content)?// "Hello, World!"
8. Keychain
Keychain是iOS提供的一種安全的數(shù)據(jù)存儲方式,適用于保存敏感信息,例如密碼、令牌和證書等。
使用步驟:
導(dǎo)入Security.framework庫。
使用KeychainWrapper類存儲和讀取數(shù)據(jù)。
let?keychain?=?KeychainWrapper.standard
keychain.set("password123",?forKey:?"password")
let?password?=?keychain.string(forKey:?"password")????""
print("Password: \(password)")
代碼示例:
// 導(dǎo)入Security.framework庫```swift
import?Security
// 使用KeychainWrapper類存儲和讀取數(shù)據(jù)
let?keychain?=?KeychainWrapper.standard
keychain.set("password123",?forKey:?"password")
let?password?=?keychain.string(forKey:?"password")????""
print("Password: \(password)")
總結(jié)
本文介紹了iOS中常用的數(shù)據(jù)持久化方式,包括屬性列表、歸檔、SQLite數(shù)據(jù)庫、Core Data、User Defaults、文件存儲和Keychain。不同的數(shù)據(jù)持久化方式適用于不同的場景和數(shù)據(jù)類型,開發(fā)者可以根據(jù)具體的需求選擇合適的方式來實現(xiàn)數(shù)據(jù)持久化功能。同時,數(shù)據(jù)持久化過程中要注意數(shù)據(jù)的安全性和完整性,避免出現(xiàn)數(shù)據(jù)丟失或泄露的情況。
通過本文的介紹和示例代碼,相信讀者對iOS中的數(shù)據(jù)持久化有了更深入的理解,能夠更加靈活地運用不同的數(shù)據(jù)持久化方式來滿足應(yīng)用的需求,提升應(yīng)用的性能和用戶體驗。在日常開發(fā)中,合理選擇和使用數(shù)據(jù)持久化方式將有助于開發(fā)出高質(zhì)量的iOS應(yīng)用。祝愿讀者在iOS開發(fā)的路上越走越遠,不斷精進,成為一名優(yōu)秀的iOS程序員!
參考文獻:
Apple Developer Documentation:?https://developer.apple.com/documentation/
FMDB GitHub Repository:?https://github.com/ccgus/fmdb
KeychainSwift GitHub Repository:?https://github.com/evgenyneu/keychain-swift
iOS Data Storage Guidelines:?https://developer.apple.com/icloud/documentation/data-storage/
注:本文所涉及的代碼示例中可能存在簡化或省略,讀者在實際使用時需根據(jù)實際情況進行完善和調(diào)試。