跳到主要内容

CustomCommand 接口

使用 CustomCommand 实现 API 接口流程如下:

在宿主中注入 CustomeCommand 监听​

let gameHandle: RuntimeGameHandle
gameHandle.setCustomCommandListener("sampleLogin") { request, handle in
// 参数校验,如果参数不合法,返回错误
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
}

// 延迟返回结果,模拟异步请求
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
handle.success(result: ["username": username + "_login", "age": 18, "data": data, "nonce": nonce])
}
}

实现自定义监听​

let gameHandle: RuntimeGameHandle
gameHandle.setCustomCommandListener(CustomCommandListener())

class CustomCommandListener: TJCustomCommandListener {
func onCustomCommand(command: String, request: NSDictionary, handle: TJCustomCommandHandle) {
switch command {
case "sampleLogin":
// 参数校验,如果参数不合法,返回错误
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
}

// 延迟返回结果,模拟异步请求
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")
}
}
}

在 javascript 里实现 API 接口​

javascript 中可以访问 tj 和 cusObj 变量。tj 用于调用和添加 API, cusObj 用于存放内部使用的功能。

tj.customCommand 通过 tj.customCommand 来调用对应的 swift 方法.

tj.sampleLogin = function (obj) {
tj.customCommand("sampleLogin", obj);
};

obj 参数除了包含对应接口参数,还包含接口回调。回调参数定义如下:

参数名类型必填说明
successFunction是接口调用成功的回调函数
failFunction否接口调用失败的回调函数
completeFunction否接口调用结束的回调函数(调用成功、失败都会执行)

API 调用示例

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

通过 tj.customCommandSync 来实现对 swift 接口的同步调用。

API 调用示例

tj.sampleLoginSync = function (obj) {
return tj.customCommandSync("sampleLogin", obj);
};

传入自定义初始化 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);
}
"""
]
}

运行中执行 javascript​

宿主运行中,可以调用 RuntimeHandle.runCustomScript 来执行 javascipt 代码。代码中可以访问 tj 和 cusObj 变量。

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