1.plist文件 即屬性列表文件,全名是Property List,這種文件的擴展名為.plist,因此,通常被叫做plist文件。它是一種用來存儲串列化後的對象的文件,用於存儲程式中經常用到且數據量小而不經常改動的數據。 可以存儲的類型:NSNumber,NSString,NSDate,NSDa ...
1.plist文件
即屬性列表文件,全名是Property List,這種文件的擴展名為.plist,因此,通常被叫做plist文件。它是一種用來存儲串列化後的對象的文件,用於存儲程式中經常用到且數據量小而不經常改動的數據。
可以存儲的類型:NSNumber,NSString,NSDate,NSData ,NSArray,NSDictionary,BOOL.
不支持自定義對象的存儲。
plist的創建方式有兩種:command + n 創建和純代碼創建,不同的創建方式使用方法也自然不同。
command + n 創建:
// read bundle's plist if let plistPath = Bundle.main.path(forResource: "test", ofType: "plist") { var dataDict = NSDictionary(contentsOfFile: plistPath) as! Dictionary<String, Any> // var dataArray = NSArray(contentsOfFile: plistPath) as! NSArray // modify dataDict["Int"] = 1 dataDict["String"] = "hi" }
純代碼創建:
// create let documentsPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] as NSString let plistPath = documentsPath.appendingPathComponent("test.plist") print(plistPath) // write var dict = [String: Any]() dict["Int"] = 1 dict["Bool"] = true (dict as NSDictionary).write(toFile: plistPath, atomically: true) // read if let dataDict = NSDictionary(contentsOfFile: plistPath) { print(dataDict) }
需要註意的問題:如果需要存儲自定義類型的數據需要先進行序列化。
2.NSUserDefaults
用於存儲用戶的偏好設置、用戶信息(如用戶名、是否自動登錄、字體大小等)。
數據自動保存在沙盒的Libarary/Preferences 目錄下。
NSUserDefaults將輸入的數據儲存在.plist格式的文件下,這種存儲方式就決定了它的安全性幾乎為0,所以不建議存儲一些敏感信息如:用戶密碼、token、加密私鑰等。
它能存儲的數據類型為:NSNumber(NSInteger、float、double、BOOL),NSString,NSDate,NSArray,NSDictionary,NSData。
不支持自定義對象的存儲。
需要註意的問題: 1.NSUserDefaults存儲的數據都是不可變的,想將可變數據存入需要先轉為不可變才可以存儲。
2.NSUserDefaults是定時把緩存中的數據寫入磁碟的,而不是即時寫入,為了防止在寫完NSUserDefaults後程式退出導致的數據丟失,可以在寫入數據後使用synchronize強制立即將數據寫入磁碟。
/// code block: func testUserDefaults() -> Void { let standard = UserDefaults.standard standard.set(1, forKey: "Int") standard.set(true, forKey: "Bool") standard.set(1.0, forKey: "Float") standard.synchronize()// 立即存儲 if let v_int = standard.object(forKey: "Int") { print("\(v_int)") // update standard.set(2, forKey: "Int") // remove standard.removeObject(forKey: "Int") } else { print("not exist") } }
3.鑰匙串(keychain)
Keychain在Mac上主要進行一些敏感信息存儲使用 如用戶名,密碼,網路密碼,認證令牌, Wi-Fi網路密碼,VPN憑證等。 iOS 中 Keychain, 也有相同的功能實現 , 保存的信息存儲在設備中, 獨立於每個App沙盒之外。
當你刪除APP後Keychain存儲的數據不會刪除,所以在重裝App後,Keychain里的數據還能使用。從ios 3.0開始,跨程式分享keychain變得可行而NSUserDefaults存儲的數據會隨著APP而刪掉。
相同的 Team ID 開發, 可實現多個App 共用數據。
使用keychain時蘋果官方已經為我們封裝好了文件KeychainItemWrapper,引入即可使用。
第三方庫SAMKeychain。。。
/// SAMKeychain 簡單使用 func testKeychain() -> Void { let account = "479377608" let service = "com.qq" // 檢測數據是否已存 if SAMKeychain.password(forService: service, account: account) != nil { print("keychain exist..") } else { // 存儲 if SAMKeychain.setPassword("123456", forService: service, account: account) { print("keychain set success") } else { print("keychain set failed...") } } }
4.歸檔(NSKeyedArchiver)
歸檔是iOS開發中數據存儲常用的技巧,歸檔可以直接將對象儲存成文件,把文件讀取成對象。
相對於plist或者NSUserDefault形式,歸檔可以存儲的數據類型更加多樣,並且可以存取自定義對象。對象歸檔的文件是保密的,在磁碟上無法查看文件中的內容,更加安全。
遵守NSCoding協議,並實現該協議中的兩個方法。如果是繼承,則子類一定要重寫那兩個方法。因為子類在存取的時候,會去子類中去找調用的方法,沒找到那麼它就去父類中找,所以最後保存和讀取的時候新增加的屬性會被忽略。需要先調用父類的方法,先初始化父類的,再初始化子類的。
保存數據的文件的尾碼名可以隨意命名。
最大的優點是:可以將複雜的對象寫入文件 可以歸檔集合類,所以無論添加多少對象,將對象寫入磁碟的方式都是一樣的,不會增加工作量。
5.沙盒(sandbox)
持久化在Document目錄下,一般存儲非機密數據。當App中涉及到電子書閱讀、聽音樂、看視頻、刷圖片列表等時,推薦使用沙盒存儲,可以極大的節約用戶流量,且增強了app的體驗效果。
Application:存放程式源文件,上架前經過數字簽名,上架後不可修改。
Documents: 保存應運行時生成的需要持久化的數據,iTunes同步設備時會備份該目錄。例如,游戲應用可將游戲存檔保存在該目錄。
tmp: 保存應運行時所需的臨時數據,使完畢後再將相應的文件從該目錄刪除。應用 沒有運行時,系統也可能會清除該目錄下的文件。iTunes同步設備時不會備份該目錄。
Library/Caches: 保存應用運行時成的需要持久化的數據,iTunes同步設備時不會備份 該目錄。一般存儲體積大、不需要備份的非重要數據,比如網路數據緩存存儲到Caches下
Library/Preference: 保存應用的所有偏好設置,如iOS的Settings(設置) 應會在該目錄中查找應的設置信息。iTunes同步設備時會備份該目錄。
func testSandbox() -> Void { // app's home path let path = NSHomeDirectory() // document path let documentsPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first // cache path let cachePath = NSSearchPathForDirectoriesInDomains(.cachesDirectory, .userDomainMask, true).first // library path let libraryPath = NSSearchPathForDirectoriesInDomains(.libraryDirectory, .userDomainMask, true).first // tmp path let tmpPath = NSTemporaryDirectory() // write file let filePath = (cachePath! as NSString).appendingPathComponent("test.txt") let numbers = [1,2,3] as NSArray if numbers.write(toFile: filePath, atomically: true) { print("write success.") } else { print("write failed..") } // read file guard let readNumbers = NSArray(contentsOfFile: filePath) else { print("read failed...") return } print(readNumbers) }
6.資料庫(sqllite)
適合儲存數據量較大的數據,一般使用FMDB等第三方庫。
FMDB是iOS平臺的SQLite資料庫框架,FMDB以OC的方式封裝了SQLite的C語言API,使用起來更加面向對象,省去了很多麻煩、冗餘的C語言代碼,對比蘋果自帶的Core Data框架,更加輕量級和靈活,提供了多線程安全的資料庫操作方法,有效地防止數據混亂。
易用性不強, 但可以存儲大量數據,存儲、檢索大量數據非常高效;能對數據進行複雜的聚合,比使用對象執行這些操作要高效得多。
7.CoreData
Core Data是iOS5之後才出現的一個框架,它提供了對象-關係映射(ORM)的功能,即能夠將OC對象轉化成數據,保存在SQLite資料庫文件中,也能夠將保存在資料庫中的數據還原成OC對象。在此數據操作期間,我們不需要編寫任何SQL語句。
CoreData本質還是講數據存在了SQLite資料庫文件,使用不是很方便。