阅读主题
iOS Swift 快速接入
本次在 v0.1.0 增加原生 Swift SDK 源码,目标为 iOS 15+、Swift 5.9+。SDK 提供异步账号与业务接口,不依赖 H5 WebView,也不会自动生成登录框、浮球或账号中心。游戏方使用 UIKit、SwiftUI 或引擎界面实现交互。
当前 Windows 环境不能完成 Xcode/Apple SDK 编译与运行验收。源码、接口说明及示例可供接入;不能把源码检查视为 Apple 编译、Keychain 真机或 App Store 验收通过。
创建 iOS 应用
- 登录开发者控制台,创建应用并勾选 iOS;也可在已有应用的接入配置中增加 iOS。
- 新建或扩端都需要审核。扩端会让整款游戏重新待审并撤销原平台玩家会话;原有 App ID 与密钥保留。
- 审核通过后使用 iOS 专属 App ID。同一逻辑游戏最多包含 H5、Android、iOS 三端,三端共享
gameUserId,实际区服与存档仍由游戏服务器管理。 - 平台不会自动给既有演示应用增加 iOS,也没有可直接照抄的演示 iOS App ID。
服务端密钥仅交由游戏服务器保管。新应用必须通过 /api/server/auth/exchange 兑换,不能调用演示快捷交换接口。
安装 Swift Package
下载 iOS SDK 源码包,在下载中心核对 SHA-256 后解压。在 Xcode 的 Package Dependencies 中添加包含 Package.swift 的本地 StarlightSDK 目录,将同名 library product 链接到游戏 target。
交付是 Swift Package 源码,包含测试和宿主示例;不是已编译的 XCFramework、IPA 或已发布的远程 SPM 仓库。宿主设置 iOS 15 或更高部署目标,在 Apple 工具链中完成 Resolve Packages、构建及实际设备运行。
创建实例和交换回调
下面函数由宿主在主 actor 上调用。accountOrigin 是平台 API origin,gameExchangeURL 是游戏方自己提供的 HTTPS 身份交换入口,二者均须替换为实际地址。
swift
import Foundation
import StarlightSDK
@MainActor
func makeAccountSDK(
appID: String,
accountOrigin: URL,
gameExchangeURL: URL
) throws -> StarlightSDK {
guard gameExchangeURL.scheme == "https", gameExchangeURL.host != nil,
gameExchangeURL.user == nil, gameExchangeURL.password == nil,
gameExchangeURL.fragment == nil else {
throw StarlightError("INVALID_CONFIG", "游戏交换入口需要无内嵌凭据的 HTTPS URL")
}
let configuration = try StarlightConfiguration(
appId: appID,
baseURL: accountOrigin
)
// 默认传输拒绝重定向,防止凭据被带往其他地址。
let gameTransport = URLSessionTransport()
return StarlightSDK(
configuration: configuration,
storage: KeychainSessionStorage()
) { authorization in
var request = URLRequest(url: gameExchangeURL)
request.httpMethod = "POST"
request.timeoutInterval = 15
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.httpBody = try JSONEncoder().encode(authorization)
let (data, response) = try await gameTransport.send(request)
guard (200..<300).contains(response.statusCode) else {
throw StarlightError("GAME_EXCHANGE_FAILED", "游戏服务器兑换失败",
status: response.statusCode)
}
return try JSONDecoder().decode(StarlightSession.self, from: data)
}
}GAME_EXCHANGE_FAILED 是宿主示例自定义错误,不是平台 API 错误码。回调把 {appId, code, codeVerifier} 发给游戏服务器,由服务器添加 X-API-Key 完成平台兑换并返回 StarlightSession。密钥不进入 App。游戏服务器还需建立自己的业务会话,见可信服务端接入。
配置默认只接受 HTTPS origin,不带 /api、查询串、fragment 或用户密码。平台请求默认超时 15 秒,宿主自定义的交换回调需要自行设置超时。
初始化与登录
在宿主持有 SDK 实例期间调用以下方法;账号和密码由玩家输入,consentVersion 使用实际展示并同意的协议版本。
swift
@MainActor
func prepare(_ sdk: StarlightSDK) async throws -> StarlightSession? {
_ = try await sdk.initialize()
return try await sdk.restoreSession()
}
@MainActor
func signIn(_ sdk: StarlightSDK, account: String,
password: String, consentVersion: String) async throws {
let current = try await sdk.login(.password(
account: account, password: password,
consentVersion: consentVersion
))
// 使用可信 current.user.gameUserId 连接游戏自己的账号映射。
// 正式游戏角色与存档由游戏服务器提供。
_ = current.user.gameUserId
}initialize() 只读取配置;SDK 在 login 内生成 PKCE 和 state,验证授权返回后调用交换闭包,再发布会话。启动恢复与玩家登录要明确顺序;登录进行时恢复会返回 nil,不会抢先恢复旧 Keychain 身份。宿主调用处必须 do/catch 并显示错误,不依赖 onError 捕获所有失败。短信登录及其他参数见方法参考。
本地联调与验收
如本地平台仅有 HTTP,配置必须显式传 allowInsecureHTTPForDevelopment: true,宿主还需按实际网络方式配置调试 target 的 ATS、本地网络访问说明与权限。SDK 不会自动修改 Info.plist 或关闭系统网络保护。真机的 127.0.0.1 指向手机自身,应使用可达的开发服务器地址;外部环境使用 HTTPS。
在 Xcode 和设备上检查包解析、编译、真实网络、Keychain、启动恢复、登录取消、切号及前后台。演示订单不等于 Apple 内购:没有交付 Sign in with Apple、StoreKit、收据验证或 App Store 审核结果。
还需验证 403 账号受限/应用停用导致会话终止,以及 Keychain 删除失败与退出断网的组合。当前实例清内存不保证设备记录删除和远端撤销均成功,处理方式见会话页。
下一步阅读会话与生命周期,确认宿主如何处理旧请求和退出。