2017-08-03 4 views
0

Ich habe einen Countdown-Timer-Schnittstellencontroller, der, sobald der Timer auf 00:00 herunterfährt, einen anderen Schnittstellencontroller startet. Wenn ich die Uhr aktiv halte, bis der Timer 00:00 erreicht, startet der zweite Schnittstellencontroller wie es sollte. Wenn die Uhr jedoch in den Ruhezustand wechselt, selbst wenn sie aktiv ist, bevor der Timer 00:00 erreicht, wird es eine Verzögerung von einigen Sekunden bis zu mehr als einer Minute geben, bevor der zweite Schnittstellencontroller gestartet wird.swift 3: App beobachten: Wenn die Uhr in den Ruhezustand geht, gibt es eine Verzögerung zwischen den Schnittstellencontrollern

Dieser Fehler wird nicht angezeigt, wenn im Uhrsimulator ausgeführt wird, gerade wenn ich auf dem tatsächlichen Gerät laufe.

Ich verwende Xcode 8 und schnell 3.

Hier ist mein Code von den ersten Schnittstellen-Controller:

// this func will update the countdown timer 
@objc private func updateTimer() { 
    totalNumberOfSeconds += 1 
    numberOfSeconds += 1 
    if (numberOfSeconds == numSecondsInMinute) { 
     numberOfSeconds = 0 
    } 

    // only attempt to open the RacingTimer interface if this IC is visible 
    if (isStillVisible) { 
     // change to the Racing Timer if the countdown timer hits 00:00 
     if (totalNumberOfSeconds > originalSecondsTimeInterval) { 
      // the watch must have gone to sleep when the countdown timer 
      // hit 00:00, so the total num secs is past the orig timer 
      // set the numberOfSeconds to total - original to pass to RacingTimer 
      numberOfSeconds = totalNumberOfSeconds - originalSecondsTimeInterval 

      // launch the racing timer 
      WKInterfaceController.reloadRootControllers(withNames: ["RacingTimer"], contexts: [numberOfSeconds]) 

      // destroy the timer and reset the vars 
      countdownClock.invalidate() 
      numberOfSeconds = 0 
      totalNumberOfSeconds = 0 
     } else if (totalNumberOfSeconds == originalSecondsTimeInterval) { 
      // launch the racing timer 
      WKInterfaceController.reloadRootControllers(withNames: ["RacingTimer"], contexts: nil) 

      // destroy the timer and reset the vars 
      countdownClock.invalidate() 
      numberOfSeconds = 0 
      totalNumberOfSeconds = 0 
     } 
    } 
} 


override func awake(withContext context: Any?) { 
    super.awake(withContext: context) 

    // get race and timer data 
    let numSecs = raceDS.timer * 60 
    originalSecondsTimeInterval = numSecs 
    cdt = NSDate(timeIntervalSinceNow: TimeInterval(numSecs)) 
    countdownTimer.setDate(cdt as Date) 
    countdownClock = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(updateTimer), userInfo: nil, repeats: true) 
    countdownTimer.start() 
} 


override func willActivate() { 
    // This method is called when watch view controller is about to be visible to user 
    super.willActivate() 
    nearestMinuteButtonOutlet.setTitle("will activate") // debug only 
    didAppear() 
} 


// set the visible boolean to true 
override func didAppear() { 
    super.didAppear() 
    isStillVisible = true 
    nearestMinuteButtonOutlet.setTitle("did appear") // debug only 
} 


// set the boolean to false 
override func didDeactivate() { 
    // This method is called when watch view controller is no longer visible 
    super.didDeactivate() 
    isStillVisible = false 
    nearestMinuteButtonOutlet.setTitle("sleeping") // debug only 
} 

ich ratlos wirklich bin, warum eine Verzögerung gibt es, wenn die Uhr geht schlafen. Jede Hilfe würde sehr geschätzt werden. TIA.

+0

Ok, also habe ich das Problem herausgefunden. Es ist nicht so, dass der zweite Schnittstellencontroller beim Start verzögert wird. Wenn die Uhr in den Ruhezustand wechselt, wird die Timer-Variable (countdownClock) nicht weiter im Hintergrund verarbeitet. Es hört auf. Wenn dies geschieht, wird die Funktion updateTimer() nicht aufgerufen, daher wird die Variable totalNumberOfSeconds nicht inkrementiert usw. – CMan

+0

Gibt es eine Möglichkeit, den CountdownClock im Hintergrund laufen zu lassen, wenn die Uhr in den Ruhezustand wechselt? – CMan

Antwort

0

Ab watchOS3 gibt es keine Lösung, eine Timer im Hintergrund zu haben. Timer Objekte sollten nicht für genaue Zeitmessungen unter iOS entweder verwendet werden. Auf iOS haben Sie die Alternative, eine CADisplayLink für genaue Zeiten zu verwenden, jedoch ist dies unter watchOS3/4 nicht verfügbar.

Um die Zeit im Hintergrund zu messen, sollten Sie das aktuelle Datum speichern, bevor die App in den Hintergrund wechselt, und die verstrichene Zeit berechnen, wenn die App erneut gestartet wird.

Wenn Sie einfach die anderen InterfaceController benötigen, um zu sehen, wenn der Benutzer Ihre App öffnet, können Sie die beschriebene Methode mit Datumsangaben verwenden und Sie können zu Ihrer anderen InterfaceController navigieren, sobald der Benutzer Ihre App erneut öffnet.

Wenn Sie Code benötigen, der ausgeführt wird, wenn der Countdown beendet ist, sollten Sie lieber eine Hintergrundaufgabe einplanen, sie sind im Moment die einzigen Methoden, Code im Hintergrund auf watchOS auszuführen.

+1

Danke David. Ich fand ähnliche Probleme und schlug Arbeitsumgebungen auf anderen Boards vor, also ist das meine Richtung. Ich speichere nur den Datums-/Zeitstempel in didDeactivate() und berechne wie viel Zeit verstrichen ist, sobald der WilleAppear() ausgelöst wird und addiere die verstrichene Zeit zu meinem Gesamtsekundenzähler. Ein bisschen hässlich, aber wenn das nötig ist, dann muss ich das tun. – CMan

Verwandte Themen