2017-08-03 11 views
0

私はカウントダウンタイマーインターフェイスコントローラを持っています。タイマーが00:00になると別のインターフェイスコントローラを起動します。タイマーが00:00に達するまで時計をアクティブに保つと、2番目のインターフェイスコントローラが起動します。ただし、時計がスリープ状態になると、タイマーが00:00になる直前にアクティブになっていても、2番目のインターフェイスコントローラが起動するまで数秒から数分の遅延があります。swift 3:時計のアプリ:時計がスリープ状態になるとインターフェイスコントローラ間に遅延があります

この欠陥は、実際のデバイスで実行しているときに時計シミュレータで実行しているときは表示されません。

私はXcodeの8を使用し、迅速な3

だがここで最初のインターフェースコントローラからの私のコードです:

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

私が見れば遅延があります理由として損失で本当によ寝る。どんな助けでも大歓迎です。 TIA。

+0

これで問題はわかりました。 2番目のインターフェイスコントローラが起動に遅れているわけではありません。時計がスリープ状態になると、Timer変数(countdownClock)はバックグラウンドで処理を続行しません。それは止まる。これが起こると、updateTimer()関数が呼び出されないので、totalNumberOfSeconds変数はインクリメントされません。 – CMan

+0

時計がスリープ状態になるときにcountdownClockをバックグラウンドで実行する方法はありますか? – CMan

答えて

0

watchOS3から、Timerをバックグラウンドで実行する方法はありません。 TimeriOSでの正確な時間測定には、オブジェクトを使用しないでください。 iOSには正確なタイミングにCADisplayLinkを使用する代わりにwatchOS3/4には表示されません。

バックグラウンドでの時間を測定するには、アプリがバックグラウンドになる前に現在の日付を保存し、アプリが再び起動されたときの経過時間を計算する必要があります。

ユーザーがアプリを開くまでに他のInterfaceControllerが表示されている必要がある場合は、日付を使用して説明した方法を使用して、別のInterfaceControllerに移動することができます。

カウントダウンが終了したときに実行するコードが必要な場合は、バックグラウンドタスクをスケジュールしてください。バックグラウンドでコードを実行する唯一の方法は、現時点ではwatchOSです。

+1

Davidに感謝します。私は同様の問題を発見し、他のボード上で回避策を提案したので、それは私が取る方向です。私はdidDeactivate()に日付/タイムスタンプを保存して、willAppear()が起動してから経過した時間を計算し、経過時間をtotal秒カウンタに加算します。少し醜いですが、それが必要ならば、それは私がする必要があります。 – CMan

関連する問題