2017-01-20 6 views
0

In meinem JavaScript, ich bin ein start Methode auf einige SWIFT-Code aufrufen:Timer funktioniert nicht in nativen reagieren-native Komponente

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 Code:

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

... Das startet einen Timer und sendet dann in diesem Beispiel wiederholt dieselbe Nachricht an meinen JavaScript-Code, der auf das Ereignis wartet.

Problem: Dieupdate Methode wird nicht einmal aufgerufen, wenn der Timer auf die Hauptlaufschleife Zugabe wie in this answer skizziert.

Gibt es einen einfachen Fehler, den ich hier mache? Ich bin neu zu schnell.

Wenn nicht, muss ich den Timer auf JS verschieben dann wiederholt den Swift-Code für die Daten ... Ich würde es lieber nicht tun, weil in meinem realen Szenario der Timer zurücksenden Daten bedingt ist, aber Ich schätze, das ist nicht so schlecht ...

+0

Versuchen Zusatz 'timer.fire()' nach Zugabe zu dem Runloop:

Dies kann durch Änderung der start Funktion der folgenden durchgeführt werden. – ebby94

+0

@ ebby94, die den Timer einmal auslöst. Ich habe einen Breakpoint innerhalb von 'update' getroffen und dann sendet er die Nachricht an den JS, aber yeah ... nur einmal. –

Antwort

0

Ich habe es herausgefunden. Der Timer muss aus irgendeinem Grund im Hauptthread eingerichtet werden und muss nicht zur Hauptlaufschleife hinzugefügt werden.

@objc func start() -> Void { 
    DispatchQueue.main.async(execute: { 
    Timer.scheduledTimer(
     timeInterval: 0.1, 
     target: self, 
     selector: #selector(self.update), 
     userInfo: nil, 
     repeats: true) 
    }) 
} 
Verwandte Themen