Skip to main content

Quick Integration of iOS SDK

It is recommended to refer to the source code of the Demo project for reading

1 Obtain Credentials​

Integrating the SDK requires first creating an application in the minigame host Console, obtaining the APP KEY, APP SECRET, and Service Token specific to each application.

When starting the SDK, it needs to be initialized via APP KEY and APP SECRET.The access party can also contact Unity to create App Service Token / App Key / App Secret.

The following is an example of test App Service Token / App Key / App Secret

  • App Service Token

  • App Key: AKIDt1vMSYVFf1twI53iDecobx6QsTK0

  • App Secret: ufzN1iD8PsnMW0ViDCMhpJFBiLR1E1Xf

Service Token is mainly used to call the following API to obtain the game list, from which Game ID can be retrieved to start the game.

Use a token to obtain a list of minigames

The platform can use the server token to obtain the list of minigames of the host application.

Example of request:

GET /api/game/list?appId={appId} HTTP/1.1
Host: minihost.tuanjie.cn
Authorization: Bearer {service_token}

Request Parameter Description:

ParameterDescription
appIdHost Application ID
AuthorizationServer token, formatted as Bearer {service_token}

Response Example:

HTTP/1.1 200 OK
Content-Type: application/json

[
{
"id": "67b*********************",
"appId": "67b*********************",
"name": "name",
"briefIntro": "briefIntro",
"gameType": "weixinminigame",
"iconUrl": "https://minihost.cdn.tuanjie.cn/game_app/67b6eb506ffcda2559ecd19d/app_icon/********.png",
"launchKey": "67b*********************",
}
]

Response field description:

FieldDescription
idGame ID
appIdHost Application ID
nameGame Name
briefIntroGame Introduction
gameTypeGame Type
iconUrlGame Icon URL
launchKeyThe return value here is the game ID

In a real production environment, Service Token should be used on the server side, and the above API should be called from the server. In the Demo project, Service Token is used on the Client side, which is just an example and not recommended for use in a production environment.

2 Import SDK​

  • Integrating the SDK requires iOS 12.0 or later, and running mini games properly requires iOS 14.0 or later.

  • Add webglhost.xcframework and webglhost_runtime.xcframework to the Xcode project.

import webglhost_runtime

3 Initialize the SDK​

Initialize TJHostHandle within the Host SDK. Subsequent game control-related APIs depend on this instance. You can determine whether the initialization was successful by checking if the return value of TJHostHandle.initialize is null.

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
}

// end of hostHandle initialization
}
}

4 Launch a single-instance game​

4.1 Launch Game Page​

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)
}

4.2 Initialize Host​

After the page finishes loading, use the initialized instance of TJHostHandle to create and initialize RuntimeGameHandle, which operates throughout the entire lifecycle of the minigame.


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
}

// end of RuntimeGameHandle
}
}

4.3 Set game startup parameters​

Here, the Host SDK will request the Host Server and obtain the game package download URL and game type based on the LAUNCH KEY. For the full list of parameters, refer to the API Reference. After success, game resources can be loaded.

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
}

// end of set game start options
}
}

4.4 Load Game Resources​

After success, the game interface will be added to the specified view container, request focus, and start the game.

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

// end of loading game resources
}

4.5 Start the Game​

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

gameHandle.play() // start game
}

4.6 Close the Game​

Add a game close listening callback to handle the game close logic

gameHandle.setOnTJCloseListener {
// stop game
gameHandle.stop()

self.dismiss(animated: true)
}

5 Multi-instance Game Management ​

The host provides MultiGameLauncher to manage multiple game instances. When the number of instances reaches the upper limit, it will automatically stop an instance based on time and then reuse it as a new instance.

5.1 Initialize the multi-instance upper limit​

MultiGameLauncher.configMaxGame(max: 3) // default uninitialized number: 1

5.2 Launch Game Page​

Manage game pages for multiple game instances through MultiGameLauncher, distinguishing different game pages based on 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)
}

5.3 Initialize Host​

Creating a host for multiple instances requires binding through the gameId. If a host has already been created for an instance, the original host will be reused.

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: use gameId to find the corresponding instance
MultiGameLauncher.createGameHandle(hostHandle, gameId, self) { gameHandle, err in
guard let gameHandle else {
return
}

self.gameHandle = gameHandle
}
}
}

5.4 Set game startup parameters​

Here, the Host SDK will request the Host Server and obtain the game package download URL and game type based on the LAUNCH KEY. For the full list of parameters, refer to the API Reference. After success, game resources can be loaded.

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
}

// end of set game start options
}
}

5.5 Load game resources​

After success, the game interface will be added to the specified view container, request focus, and start the game.

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

// end of loading game resources
}

5.6 Start the Game​

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

gameHandle.play() // start game
}

5.7 Pause Game​

Add a game close listening callback to handle the game close logic

gameHandle.setOnTJCloseListener {
if let gameId = self.gameId {
MultiGameLauncher.pause(gameId: gameId)
} else {
gameHandle.stop()
}

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

5.8 Resume Game​

When the game page is reopened, the game needs to be restored

override func viewWillAppear(_: Bool) {
// configure hot-start params
if let gameId {
let enterOption = MiniGameLaunchOption.Builder()
.scene(1002)
.shareTicket("1002")
.build()
MultiGameLauncher.resume(gameId: gameId, enterOption)
}
}
MultiGameLauncher.resume(gameId: gameId)

5.9 Stop game​

When the game needs to be stopped or the page needs to be released, call MultiGameLauncher.stop(gameId: gameId) to release all associated information

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

5.10 Destroy Instance​

When an instance needs to be released, call MultiGameLauncher.destroy(gameId: gameId) to release the content associated with the instance. Destroying the instance will stop the game and release the instance.

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