Apple Keychain 是一個非常流行且功能強大的 Swift 工具,每個 iOS 和 MacOS 用戶都在使用。 它可用於保存密碼、安全筆記、證書等。總的來說,Keychain 是一個加密數據庫,具有相當複雜和強大的 API,當您需要保存敏感的用戶數據(例如密碼)時,請使用Keychain。
範例 :
struct KeychainItemStorable {
let service: String
let account: String
}
extension KeychainItemStorable {
enum Error: Swift.Error {
case passwordNotFound
case unknownError(String)
case invalidData
}
func readPassword() throws -> String {
var query: [String : Any] = [:]
query[kSecClass as String] = kSecClassGenericPassword
query[kSecAttrService as String] = service
query[kSecAttrAccount as String] = account as AnyObject?
query[kSecMatchLimit as String] = kSecMatchLimitOne
query[kSecReturnAttributes as String] = kCFBooleanTrue
query[kSecReturnData as String] = kCFBooleanTrue
// Try to fetch the existing keychain item that matches the query.
var queryResult: AnyObject?
let status = withUnsafeMutablePointer(to: &queryResult) {
SecItemCopyMatching(query as CFDictionary, UnsafeMutablePointer($0))
}
switch status {
case noErr:
guard let items = queryResult as? [String: Any],
let valueData = items[kSecValueData as String] as? Data,
let valueString = String(data: valueData, encoding: .utf8) else
{ throw Error.invalidData }
return valueString
case errSecItemNotFound:
throw Error.passwordNotFound
default:
throw Error.unknownError(status.description)
}
}
}
優點 :
Plist 文件允許使用鍵/值約定存儲序列化對象。 在 macOS 和 iOS 應用程序中,plist 最常見的用法示例是存儲應用程序設置值的 Info.plist 文件。 在 Info.plist 中,我們可以找到應用程序名稱、版本號、所需權限信息、Facebook 應用程序信息等。 在我們所有使用 Firebase 的 iOS 應用程序模板中實現的 .plist 文件的另一個示例是 GoogleService -Info.plist 文件,其中包含用戶身份驗證和數據庫訪問所需的所有 Firebase API 密鑰
在 plist 文件中,您可以存儲基本型態資料,例如:
可以使用 Bundle.main.infoDictionary
讀取存儲在應用程序的 Info.plist 文件中的信息。
如下所示:
let bundleIdentifire = Bundle.main.infoDictionary[kCFBundleIdentifierKey] as? String
範例:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>FirstName</key>
<string>John</string>
<key>SecondName</key>
<string>Doe</string>
<key>Age</key>
<string>24</string>
</dict>
</plist>
class PlistReader {
func read(fileNamed: String) throws -> [String: Any] {
guard let path = bundle.path(forResource: fileNamed, ofType: "plist"),
let plistData = FileManager.default.contents(atPath: path) else {
throw Error.fileMissing
}
var format = PropertyListSerialization.PropertyListFormat.xml
return try PropertyListSerialization.propertyList(from: plistData,
options: .mutableContainersAndLeaves,
format: &format) as! [String: Any]
}
}