跳到主要内容

iOS SDK 快速集成

此部分内容建议参考 Demo 项目源码 阅读

1. 获取凭据​

集成 SDK 需要先在 小游戏宿主控制台 中创建应用,获得每个应用专属的 APP KEY, APP SECRET 及 Service Token 后。 启动 SDK 时,需要通过 APP KEY,APP SECRET 初始化。接入方也可联系 Unity 以创建 App Service Token / App Key / App Secret。

如下是测试用 App Service Token / App Key / App Secret 示例

  • App Service Token
  • App Key: AKIDt1vMSYVFf1twI53iDecobx6QsTK0
  • App Secret: ufzN1iD8PsnMW0ViDCMhpJFBiLR1E1Xf

Service Token 的主要作用是调用以下 API 获取游戏列表,并可从中获取 Game ID 以启动游戏。

使用令牌获取小游戏列表

实际生产环境中,Service Token 应该在服务端使用,从服务端调用上面的 API 。Demo 项目中,Service Token 是在客户端使用,这个仅仅是一个实例,不建议在生产环境中这样使用。

2. 导入 SDK​

  • 集成 SDK 需要 iOS 12.0 及以上系统版本,正常运行小游戏需要 iOS 14.0 及以上系统版本。
  • webglhost.xcframework 以及 webglhost_runtime.xcframework 添加到 Xcode 工程中。
import webglhost_runtime

3. 初始化 SDK​

初始化 Host SDK 内 TJHostHandle 后续游戏控制相关 API 依赖此实例,可通过检查 TJHostHandle.initialize 返回值是否为空判断是否初始化成功。

func initTJHostHandle() {
// AKIDcv9N9wkDXKZ7gDoB2avKlu0N8tnS is a test [Demo App Key]
// sp9ZsGlNLmTSX9o0sa29C5FwmxemUV8A is a test [Demo App Secret]
TJHostHandle.initialize("AKIDcv9N9wkDXKZ7gDoB2avKlu0N8tnS", "sp9ZsGlNLmTSX9o0sa29C5FwmxemUV8A") { hostHandle, error in
guard let hostHandle else {
return
}

// 初始化完成 hostHandle
}
}

3. 启动单实例游戏​

3.1 启动游戏页面​

func launchHostView(gameId: String) {
guard let hostHandle else {
return
}

let hostViewController = HostViewController()
hostViewController.gameId = gameId
hostViewController.hostHandle = hostHandle
hostViewController.modalPresentationStyle = .fullScreen
hostViewController.delegate = self

present(hostViewController, animated: true)
}

3.2 初始化宿主​

页面加载完后,使用 TJHostHandle 初始化后的实例创建并初始化 RuntimeGameHandle,RuntimeGameHandle 作用于整个小游戏生命周期。


override func viewDidLoad() {
super.viewDidLoad()

guard let _ = hostHandle, let _ = gameId else {
return
}

initGameHandle()
}

func initGameHandle() {
hostHandle.createGameHandle(self) { gameHandle, error in
guard let gameHandle, error == nil else {
return
}

// 初始化完成 RuntimeGameHandle
}
}

3.3 设置游戏启动参数​

此处 Host SDK 将根据请求 Host Server 并根据 LAUNCH KEY 获取游戏包下载 URL 及游戏类型,全部参数列表参考 API Reference,成功后可加载游戏资源。

func setGameStartOptions() {
let options: [String: Any] = {
TJConstants.LAUNCH_KEY: "LAUNCH KEY",
TJConstants.USER_ID: "gust",
}

gameHandle.setGameStartOptions(options) { error in
guard error == nil else {
return
}

// 启动参数设置完成
}
}

3.4 加载游戏资源​

成功后游戏界面会被添加至指定视图容器中,请求焦点,并启动游戏。

gameHandle.start(onShowMsg: "start game") { error in
guard error == nil else {
return
}

// 游戏加载完成
}

3.5 启动游戏​

func showGame() {
guard let gameHandle else {
return
}

gameHandle.play() // 启动游戏
}

3.6 关闭游戏​

添加关闭游戏监听回调,处理关闭游戏逻辑

gameHandle.setOnTJCloseListener {
// 停止游戏
gameHandle.stop()

self.dismiss(animated: true)
}

4. 多实例管理游戏​

宿主提供了MultiGameLauncher管理多个游戏实例,当实例达到上限后会依据时间自动停止实例后作为新实例启用。

4.1 初始化多实例上限​

MultiGameLauncher.configMaxGame(max: 3) // 默认未初始化数量: 1

4.2 启动游戏页面​

通过 MultiGameLauncher 管理多个游戏实例的游戏页面,根据 gameId 区分不同游戏页面。

func launchHostView(gameId: String) {
guard let hostHandle else {
return
}

let hostViewController = MultiGameLauncher.launch(gameId: gameId, HostViewController.self)
hostViewController.gameId = gameId
hostViewController.hostHandle = hostHandle
hostViewController.modalPresentationStyle = .fullScreen
hostViewController.delegate = self

present(hostViewController, animated: true)
}

4.3 初始化宿主​

多实例创建宿主需要通过 gameId 来进行绑定,当实例已经创建过宿主则会复用原宿主。

class HostViewController: UIViewController {
var hostHandle: TJHostHandle?
var gameHandle: RuntimeGameHandle?
var gameId: String?
override func viewDidLoad() {
super.viewDidLoad()

guard let gameId, let hostHandle else {
dismiss(animated: true)
return
}

// createGameHandle 时通过 gameId 找到绑定的实例
MultiGameLauncher.createGameHandle(hostHandle, gameId, self) { gameHandle, err in
guard let gameHandle else {
return
}

self.gameHandle = gameHandle
}
}
}

4.4 设置游戏启动参数​

此处 Host SDK 将根据请求 Host Server 并根据 LAUNCH KEY 获取游戏包下载 URL 及游戏类型,全部参数列表参考 API Reference,成功后可加载游戏资源。

func setGameStartOptions() {
let options: [String: Any] = {
TJConstants.LAUNCH_KEY: "LAUNCH KEY",
TJConstants.USER_ID: "gust",
}

gameHandle.setGameStartOptions(options) { error in
guard error == nil else {
return
}

// 启动参数设置完成
}
}

4.5 加载游戏资源​

成功后游戏界面会被添加至指定视图容器中,请求焦点,并启动游戏。

gameHandle.start(onShowMsg: "start game") { error in
guard error == nil else {
return
}

// 游戏加载完成
}

4.6 启动游戏​

func showGame() {
guard let gameHandle else {
return
}

gameHandle.play() // 启动游戏
}

4.7 暂停游戏​

添加关闭游戏监听回调,处理关闭游戏逻辑

gameHandle.setOnTJCloseListener {
// 暂停游戏,重新进入游戏可继续
if let gameId = self.gameId {
MultiGameLauncher.pause(gameId: gameId)
} else {
gameHandle.stop()
}

self.dismiss(animated: true)
}
MultiGameLauncher.pause(gameId: gameId)
MultiGameLauncher.pauseAll()

4.8 恢复游戏​

当游戏页面被重新打开后,需要恢复游戏

override func viewWillAppear(_: Bool) {
// 设置热启动进入参数
if let gameId {
let enterOption = MiniGameLaunchOption.Builder()
.scene(1002)
.shareTicket("1002")
.build()
MultiGameLauncher.resume(gameId: gameId, enterOption)
}
}
MultiGameLauncher.resume(gameId: gameId)

4.9 停止游戏​

当游戏需要被停止或需要释放页面时需调用 MultiGameLauncher.stop(gameId: gameId) 以释放所有关联信息

MultiGameLauncher.stop(gameId: gameId)
MultiGameLauncher.stopAll()

4.10 销毁实例​

当实例需要被释放时需调用 MultiGameLauncher.destroy(gameId: gameId) 释放实例相关的内容,销毁实例会停止游戏并释放该实例

MultiGameLauncher.destroy(gameId: game)
MultiGameLauncher.destroyAll()