阅读主题
iOS 会话与生命周期
StarlightSDK 标注 @MainActor。实例、回调和会话由主 actor 管理,网络通过 async/await 执行。宿主仍应明确 UI 所属、登录任务生命周期和游戏自身会话;SDK 不管理 UIViewController 或游戏引擎场景。
内存与 Keychain
构造时不传 storage 即使用内存会话,退出进程后不会自动恢复。显式传入 KeychainSessionStorage() 才保存候选凭据。存储键结合平台 API origin 与 App ID,避免不同应用配置直接复用候选。
Keychain 使用本设备、解锁后可访问、不同步 iCloud 的记录。自定义 service 可区分宿主环境;不要假设共享 App Group、跨 App 或跨设备登录已经配置。设备锁定、权限和 Keychain 故障需要在 Apple 设备验证。
restoreSession() 对候选凭据执行以下流程:
- 读取并解析本地候选,检查有效期与基本字段。
- 请求平台
/api/me验证,并使用返回的用户与角色更新候选。 - 验证成功后才写入
session、触发onSessionChanged。 - 会话撤销或过期时清理;403
ACCOUNT_RESTRICTED/APP_UNAVAILABLE同样终止候选恢复并清理身份。网络失败保留候选、抛出错误,不能显示已登录。
同一个 SDK 实例中的并发恢复复用正在进行的恢复任务。如果内存中已有未到期的会话,restoreSession() 直接返回它,不会每次都远程验证;需新鲜业务状态时调用 center() 等受鉴权接口。当前没有自动续签或独立心跳续期。
前台 login() 进行时调用 restoreSession() 会直接返回 nil,不从 Keychain 加载旧身份;新登录也会使已经发出的旧恢复结果失效。这个 nil 表示本次没有发布恢复结果,不能用来覆盖正在显示的登录进度。宿主应先完成启动恢复再开放登录,或在玩家发起登录后以该次登录结果为准。
监听与取消
swift
// 位于宿主 @MainActor 控制器/模型中;self 需能弱引用。
sdk.onSessionChanged = { [weak self] current in
self?.renderAccount(current) // 宿主实现,清理旧角色与页面缓存
}
sdk.onError = { [weak self] error in
self?.showAccountError(error.message) // 宿主实现
}SDK 保留闭包;宿主闭包引用控制器时使用适当的弱引用以避免循环持有。onError 当前报告受鉴权请求处理中的 StarlightError 和写入/删除存储错误;配置、登录、读取候选、恢复及自定义交换错误仍需通过调用处的 do/catch 处理,不能把它当全局异常总线。
回调可能同步触发宿主清理或更换身份。SDK 会重新检查会话,避免存储错误回调清空后又发布旧“登录成功”;宿主也应只根据当前会话更新界面,不在回调内无限重复同一失败操作。
关闭登录面板时调用 cancelLogin(),并取消宿主持有的登录 Task。cancelLogin() 令当前登录/恢复事务失效,迟到的成功响应不会发布为新身份;它不会清除既有会话,也不保证已经发出的 HTTP 请求立即停止。
swift
loginTask?.cancel() // 宿主持有的 Task,不是 SDK 属性
sdk.cancelLogin()宿主销毁账号模块时解除回调、取消自己的任务,再释放 SDK。Swift 端没有 Android 的 destroy() 或 detachActivity() 接口,也不依赖 Activity。
退出与切号
| 方法 | 行为 |
|---|---|
logout() | 先清本地会话和候选,再尝试撤销平台 token;网络失败会抛错,但不会恢复本地旧身份 |
switchAccount() | 当前等同退出;随后由宿主显示登录界面并调用新的 login |
clearSession() | 清内存身份并尝试删除候选,使当前实例不再恢复旧候选;不请求服务端撤销 |
cancelLogin() | 取消待完成的授权事务,保留已经建立的会话 |
退出断网时,服务端 token 可能尚未撤销,不能将本地清空当作远端撤销已完成。玩家恢复网络后可通过设备会话管理处理。游戏自己的业务会话也须独立退出;平台没有自动控制任意外部游戏会话的协议。
Keychain 删除也可能失败:当前实例仍清空身份并阻止旧候选恢复,但磁盘记录可能还在。重建 SDK 或重启 App 后不能假设该记录已经删除;如果服务端退出同时失败,旧 token 可能仍然有效。宿主收到 STORAGE_ERROR 应提示退出清理未完全完成,在设备解锁、权限恢复后保留当前实例重试清理,并完成服务端撤销。不要通过马上新建 SDK 来绕过存储错误。
受鉴权业务请求捕获发起时的账号。请求返回时如果账号已变化,抛出 SESSION_CHANGED,宿主丢弃结果,不将旧钱包、订单或角色渲染给新账号。订单写入已到达服务器时仍可能执行,切号并不撤销该订单;重新登录原账号后查询最终状态。
业务请求遇到指定的会话失效 401,或账号受限/应用不可用的指定 403 时,会清理仍对应这笔请求的当前会话。其他业务 403 不会一概退出;旧账号的迟到拒绝也不能清掉新账号。
密码与设备
sessions() 读取设备会话;revokeSession(id) 返回 current: true 时清理当前本地会话。revokeOtherSessions() 保留当前会话。修改玩家密码保留当前会话并撤销其他会话;短信重置成功清理当前 SDK 身份,服务端撤销目标玩家会话。
验收覆盖设备锁定与恢复、网络断开、Keychain 写入/删除失败、切号期间返回旧请求、应用停用/扩端复审和进程重启。存储操作失败可能触发 STORAGE_ERROR;宿主应告知恢复能力受影响,不能把存储失败隐藏为持久化成功。