在我的JavaScript中,我在一些快速代码上调用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
方法,如this answer中所述。
我在这里犯了一个简单的错误吗?我是斯威夫特的新手。
如果没有,我将不得不将计时器移动到JS然后重复调用数据的swift代码...我宁愿不这样做,因为在我的真实场景中,发送回数据的计时器是有条件的,但我想这样做也不错......
答案 0 :(得分:2)
想出来。由于某种原因,需要在主线程上设置计时器,而不需要将其添加到主运行循环中。
这可以通过将start
功能更改为以下内容来完成:
@objc func start() -> Void {
DispatchQueue.main.async(execute: {
Timer.scheduledTimer(
timeInterval: 0.1,
target: self,
selector: #selector(self.update),
userInfo: nil,
repeats: true)
})
}