在我的JavaScript中,我在一些swift代码上调用start
方法:
import {NativeModules} from "react-native";
// somewhere in JS
NativeModules.MyTestClass.start();
// somewhere else I'm listening for events from the swift code
const myModule = new NativeEventEmitter(NativeModules.MyTestClass);
const subscription = myModule.addListener("testEvent", message => {
console.log(message);
});
Swift代码:
import Foundation
@objc(MyTestClass)
class MyTestClass: RCTEventEmitter {
let testEventName = "testEvent"
override func supportedEvents() -> [String]! {
return [testEventName]
}
@objc func start() -> Void {
let timer = Timer.scheduledTimer(
timeInterval: 0.1,
target: self,
selector: #selector(self.update),
userInfo: nil,
repeats: true)
RunLoop.main.add(timer, forMode: RunLoopMode.commonModes)
}
@objc func update() {
print("test")
self.sendToJs(message: "test")
}
@objc private func sendToJs(message: String) -> Void {
self.sendEvent(withName: testEventName, body: message)
}
}
它启动了一个计时器,然后,在本例中,重复地向我的JavaScript代码发送相同的消息来侦听事件。
问题:即使将计时器添加到主运行循环中,也不会调用update
方法,如本答案所示。
我在这里犯了一个简单的错误吗?我是swift的新手。
如果没有,我将不得不将计时器移动到JS,然后重复调用数据的swift代码。。。我宁愿不这么做,因为在我的真实场景中,计时器发送回数据是有条件的,但我想这样做还不错。。。
想明白了。由于某些原因,需要在主线程上设置计时器,而无需将其添加到主运行循环中。
这可以通过将start
功能更改为以下内容来实现:
@objc func start() -> Void {
DispatchQueue.main.async(execute: {
Timer.scheduledTimer(
timeInterval: 0.1,
target: self,
selector: #selector(self.update),
userInfo: nil,
repeats: true)
})
}