CustomCommand Interface
The process of implementing API interfaces using CustomCommand is as follows:
1 Inject CustomeCommand listener into the host
let gameHandle: RuntimeGameHandle
gameHandle.setCustomCommandListener("sampleLogin") { request, handle in
// validate params, returns error when params are invalid
guard let username = request["username"] as? String else {
handle.fail(errorCode: 20001, errorMsg: "invalid username")
return
}
guard let nonce = request["nonce"] as? Int32 else {
handle.fail(errorCode: 20001, errorMsg: "invalid nonce")
return
}
guard let data = request["data"] as? Data else {
handle.fail(errorCode: 20001, errorMsg: "invalid cert")
return
}
// simulate async requests
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
handle.success(result: ["username": username + "_login", "age": 18, "data": data, "nonce": nonce])
}
}
2 Implement Custom Listening
let gameHandle: RuntimeGameHandle
gameHandle.setCustomCommandListener(CustomCommandListener())
class CustomCommandListener: TJCustomCommandListener {
func onCustomCommand(command: String, request: NSDictionary, handle: TJCustomCommandHandle) {
switch command {
case "sampleLogin":
// validate params, returns error when params are invalid
guard let username = request["username"] as? String else {
handle.fail(errorCode: 20001, errorMsg: "invalid username")
return
}
guard let nonce = request["nonce"] as? Int32 else {
handle.fail(errorCode: 20001, errorMsg: "invalid nonce")
return
}
guard let data = request["data"] as? Data else {
handle.fail(errorCode: 20001, errorMsg: "invalid cert")
return
}
// simulate async requests
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
handle.success(result: ["username": username + "_login", "age": 18, "data": data, "nonce": nonce])
}
default:
handle.fail(errorCode: 20000, errorMsg: "command not found")
}
}
}
3 Implement API interfaces in JavaScript
In JavaScript, you can access tj and cusObj variables. tj is used to call and add APIs, and cusObj is used to store functions for internal use.
tj.customCommand
Call the corresponding Swift method via tj.customCommand.
tj.sampleLogin = function (obj) {
tj.customCommand("sampleLogin", obj);
};
The obj parameter contains not only the corresponding interface parameters but also interface callbacks. The callback parameters are defined as follows:
| Parameter Name | Type | Required | Description |
|---|---|---|---|
success | Function | Yes | Callback function for successful interface call |
fail | Function | No | Callback function for interface call failure |
complete | Function | No | Callback function for the end of interface call (executed upon both successful and failed calls) |
API Call Example
tj.sampleLogin({
username: "test",
nonce: 123,
data: data,
success: function (res) {
console.log(
`sampleLogin: user=${res.username}, age=${res.age}, nonce=${res.nonce}`,
);
},
fail: function (res) {
console.error(`login fail: ${res.errorCode}, ${res.errorMsg}`);
},
});
tj.customCommandSync
Synchronous calls to the swift interface are implemented through tj.customCommandSync.
API Call Example
tj.sampleLoginSync = function (obj) {
return tj.customCommandSync("sampleLogin", obj);
};
4 Pass in custom initialization JavaScript
options[TJConstants.CUSTOM_SCRIPT_FILES] = getCustomScriptFiles()
options[TJConstants.CUSTOM_SCRIPT_CONTENTS] = getCustomScripts()
func getCustomScriptFiles() -> [String] {
var files: [String] = []
if let authJsUrl = Bundle(for: type(of: self)).url(
forResource: "auth",
withExtension: "js") {
files.append(authJsUrl.path)
}
if let adJsUrl = Bundle(for: type(of: self)).url(
forResource: "ad",
withExtension: "js") {
files.append(adJsUrl.path)
}
return files
}
func getCustomScripts() -> [String] {
return [
"""
tj.sampleLogin = function(obj) {
tj.customCommand("sampleLogin", obj);
}
"""
]
}
5 Execute JavaScript during runtime
When the host is running, you can call RuntimeHandle.runCustomScript to execute JavaScript code. The code can access the tj and cusObj variables.
func runCustomJavascriptObject() {
let script = """
console.log("runCustomJavascript");
return {name: "john", age: 18, pass: true, score: [40.2, 40, 70.2]};
"""
gameHandle.runCustomScript(script) { result, error in
if let error = error {
print("error: \(error)")
} else {
let result = (result as? NSDictionary)!
print("name: \((result["name"] as? String)!)")
print("age: \((result["age"] as? Int32)!)")
print("pass: \((result["pass"] as? Bool)!)")
let score = result["score"] as! [Double]
print("score: \(score[0]), \(score[1]), \(score[2])")
}
}
}