SwiftKeychain

一个 Keychain 包装器,允许使用强类型值安全地与 Keychain 交互,甚至可以以 Swift 并发方式进行。

安装

.package(url: "https://github.com/ShenghaiWang/SwiftKeychain.git", from: "1.0.0")

用法 API 文档

最简单的用法是将 Swift 宏与 SwiftKeychain 结合使用,如下所示。请先添加 SwiftMacros 包。

struct TestAccess {
    @Access<CodableStruct?>(.keychain)
    var value: CodableStruct?
}

或者不使用宏,像下面这样使用它

// Add keychain item
SwiftKeychain.add(data: data, for: key) // For data value
let result = try? SwiftKeychain.add(value: value, for: key) // For Codable value

// Search keychain item
let resultData = SwiftKeychain.search(key: key) // For data value
let resultValue: Struct = try? SwiftKeychain.search(key: key) // For Codable value

// Delete
let resultStatus = SwiftKeychain.delete(key: key)

功能完善的方法提供对 keychain 的完全访问权限,即使在 Swift 并发方式下也是如此。

便捷方法

添加

@discardableResult
public static func add(data: Data, for key: String) -> Bool
// And
public static func add(value: Encodable, for key: String) throws -> Bool

搜索

public static func search(key: String) -> Data?
// And
public static func search<T: Decodable>(key: String) throws -> T

删除

@discardableResult
public static func delete(key: String) -> Bool

功能完善的方法

有四组方法负责添加、搜索、更新和删除 keychain 项目。所有方法都有同步方法及其异步对应方法。

请参阅 结果解析 部分以了解如何处理结果。

添加

public static func add(item: Item,
                       results: [ResultKey] = []) -> OperationResult
public static func add(item: Item,
                       results: [ResultKey] = [],
                       completion: @escaping (OperationResult) -> Void)
public static func add(item: Item,
                       results: [ResultKey] = []) async throws -> OperationResult

搜索

public static func search(item: Item,
                          with searchAttributes: [SearchAttribute] = [],
                          results: [ResultKey] = []) -> OperationResult
public static func search(item: Item,
                          with searchAttributes: [SearchAttribute] = [],
                          results: [ResultKey] = [],
                          completion: @escaping (OperationResult) -> Void)
public static func search(item: Item,
                         with searchAttributes: [SearchAttribute] = [],
                         results: [ResultKey] = []) async throws -> OperationResult

更新

public static func update(item: Item,
                          with searchAttributes: [SearchAttribute] = [],
                          to newItem: Item) -> OperationResult
public static func update(item: Item,
                          with searchAttributes: [SearchAttribute] = [],
                          to newItem: Item,
                          completion: @escaping (OperationResult) -> Void)
public static func update(item: Item,
                          with searchAttributes: [SearchAttribute] = [],
                          to newItem: Item) async throws -> OperationResult

删除

public static func delete(item: Item,
                          with searchAttributes: [SearchAttribute] = []) -> OperationResult
public static func delete(item: Item,
                          with searchAttributes: [SearchAttribute] = [],
                          completion: @escaping (OperationResult) -> Void)
public static func delete(item: Item,
                          with searchAttributes: [SearchAttribute] = []) async throws -> OperationResult

结果解析

除了便捷方法之外,所有方法都返回包含状态代码和结果对象的 OperationResult

Keychain 以一种非常灵活的方式返回结果 - 返回的对象可以是数据对象、字典或数组等。为了简化结果处理过程,OperationResult 提供了以下方法来访问结果对象

  1. .data 变量:用于访问 keychain 项目的数据对象。无论返回的对象类型如何,它都会自动尝试从结果中获取数据。

  2. attribute 下标:用于从结果字典中访问属性值。如果结果是一个数组,它将尝试返回数组第一个元素的值。

  3. index, attribute 下标:用于访问结果数组中指定索引的属性值。