这个库旨在简化会话管理。它有几个主要目标:
UserSession
,以简化处理用户登录/注销所需的工作。SessionContainer
中存储、检索和删除项目的基本类。可以通过提供符合NotificationPosting
的东西来发布通知 (NotificationCenter
默认符合此协议)。Session<T>
。RefreshHandler
闭包。SessionContainer
来创建自己的容器。KeychainStorageContainer
以供使用的类。SessionTools/Base
子规范来集成 SessionTools,而无需钥匙串依赖项。接下来,我们假设您在 iOS 上使用它,并且想要使用钥匙串。您可能已经在代码库中创建了它的某种变体。
struct Model: Codable {
let firstName: String
let lastName: String
let email: String
let token: String
}
默认的容器配置使用非托管的钥匙串容器。 这意味着该框架不会尝试为您删除会话的数据,并且您将负责在需要时通过调用Session.deleteItem()
来删除此会话的数据。 由于操作系统版本之间的差异,我们无法保证数据在当前安装之外在钥匙串中持续存在的时间。 有关更多讨论,请参阅下面。
let config = KeychainContainerConfig(keychainName: "your.keychain.name")
如果您只希望会话的数据在当前安装中持续存在,请使用生命周期KeychainLifecycle.currentInstall()
实例化您的KeychainContainerConfig
,并传入安装标识符。 该标识符应在当前安装中保持稳定,但在安装之间发生变化。
此安装标识符在运行钥匙串操作之前会附加到钥匙串名称中。 因为标识符在安装之间发生变化,所以先前的密钥将不再匹配。 理论上,如果您重复使用先前的安装标识符,您仍然可以取回该密钥,但由于操作系统版本之间的差异,我们无法保证数据在当前安装之外在钥匙串中持续存在的时间。 有关更多讨论,请参阅下面。
let managedConfig = KeychainContainerConfig(keychainName: "com.app.name", lifecycle: .currentInstall(identifier: installationIdentifier))
let container = KeychainStorageContainer<Model>(config: config)
如果您不想使用默认的钥匙串存储机制,您还可以创建自己的符合SessionContainer
的对象并实例化它。
struct MyStorageContainer: SessionContainer {
func hasItem(forIdentifier identifier: String) -> Bool {
// ...
}
func item(forIdentifier identifier: String, jsonDecoder: JSONDecoder) throws -> Item? {
// ...
}
func removeItem(forIdentifier identifier: String) throws {
// ...
}
func storeItem(_ item: Item, forIdentifier identifier: String, jsonEncoder: JSONEncoder) throws {
// ...
}
}
let anyContainer = AnySessionContainer(container)
您只需要提供模型对象的类型、存储它的容器以及将在存储容器中与您的对象关联的密钥。
let session = Session<Model>(container: anyContainer, storageIdentifier: "identifier.for.your.model.object")
可选地,如果您想在模型过期时自动处理刷新(例如,API 令牌),请遵守Refreshable
协议。
class ModelSession: Session<Model>, Refreshable {
// your class code here
// MARK: - Refreshable
func refresh(completion: @escaping RefreshCompletion) {
// your refresh code here
completion(nil)
}
}
let userSession = UserSession<Model>(container: anyContainer, storageIdentifier: "identifier.for.your.model.object", notificationPoster: NotificationCenter.default)
如果您想在模型过期时自动处理刷新(例如,API 令牌),您还可以将refreshHandler
提供给 UserSession 初始化器。
private static func userRefreshHandler(_ completion: @escaping RefreshCompletion) -> Void {
// your refresh code
completion(nil)
}
let userSession = UserSession<Model>(container: container, storageIdentifier: "identifier.for.your.model.object", notificationPoster: NotificationCenter.default, refreshHandler: userRefreshHandler)
现在,您可以轻松获取对应用程序当前用户的引用。
let currentUser = userSession.currentUser
您还可以检查当前是否有用户登录。
let isUserLoggedIn = userSession.isLoggedIn
UserSession<T>
还包含可以调用以在您认为合适时登录、注销或更新信息的方法。
do {
try userSession.didLogIn(model)
try userSession.didLogOut(nil) // Optionally provide the error that triggered the logout
try userSession.didUpdate(model)
} catch {
// Handle container read/write errors here
}
您的代码部分可以选择通过订阅Notification.Name.userSessionStateDidChange
通知来观察这些登录/注销/更新事件。
NotificationCenter.default.addObserver(self, selector: #selector(didUpdateUser:), name: .userSessionStateDidChange, object: nil)
访问通知上的userSessionState
属性以轻松获取发生的状态更改。
@objc private func didUpdateUser(_ notification: Notification) {
guard let sessionState = notification.userSessionState else { return }
// Do something with the state
switch sessionState {
case .loggedIn:
// ...
case .loggedOut(let error): // Optionally get a reference to the error that triggered the logout
// ...
case .updated:
// ...
}
}
要运行示例项目,您首先需要使用 Carthage 来安装 SessionTool 的依赖项 (KeychainAccess。
在 安装 Carthage 后,克隆存储库
git clone https://github.com/BottleRocketStudios/iOS-SessionTools.git
接下来,使用 Carthage 安装依赖项
carthage update
从这里开始,您可以打开SessionTools.xcworkspace
并运行示例
dependencies: [
.package(url: "https://github.com/BottleRocketStudios/iOS-SessionTools.git", from: "1.2.0")
]
SessionTools 可通过 CocoaPods 获得。 要安装它,只需将以下行添加到您的 Podfile 中
pod 'SessionTools'
或者,如果您不在可以访问钥匙串的环境中工作,请使用基本子规范
pod 'SessionTools/Base'
将以下内容添加到您的 Cartfile 中
github "BottleRocketStudios/iOS-SessionTools"
运行 carthage update
并按照 Carthage 的 README 中描述的步骤操作。
注意:如果您的环境可以访问钥匙串,请不要忘记将SessionTools.framework
和KeychainAccess.framework
依赖项都添加到您的项目中。
过去,您从应用程序添加的钥匙串数据会在安装之间持续存在。 虽然现在仍然如此,但我们无法保证这种情况在未来的版本中仍然如此。 这篇文章 总结了这一事实。 在 iOS 10.3 Beta 2 中,Apple 添加了一项功能,可以在卸载时删除所有应用程序钥匙串数据,但在导致现有应用程序出现问题时又恢复了。 如果 Apple 规范化了这种行为,我们也会在这里规范化。
请参阅 CONTRIBUTING 文档。 谢谢 贡献者!