如何使用 Date() 函数和应用程序在前台和后台时的时间戳来获取经过的时间?
How can I use the Date() function and time stamps from when the app is in the foreground and background to get elapsed time?
我正在考虑使用 DataFormatter.localizedString... 并将该值设置为 2 个不同的变量,一个用于应用程序离开前台和应用程序返回前台的时间,然后将它们减去获取已用时间以将其设置为 breakSession.text...但我对 swift 有点陌生,不清楚如何使用 Date() 函数。我的主要目标是让 breakTimer 在应用程序处于后台时为 运行ning,而在应用程序处于前台时暂停,但用户仍应能够看到经过的时间。但显然,计时器不能在后台 运行...有人可以帮忙吗?
import UIKit
class HomeViewController: UIViewController {
@IBOutlet weak var focusSession: UILabel!
@IBOutlet weak var breakSession: UILabel!
/** Focus Time **/
var prodMinutes = String() // Productive time data from ViewController.swift arrives and is stored
lazy var intProdSeconds = (60*Int(prodMinutes)!) + 1
var focusTimer = Timer()
var isFocusTimerRunning = false // Make sure only one timer is running at a time
/** Break Time **/
var breakMinutes = String() // Break time data from BreaTimeViewController.swift arrives and is stored
lazy var intBrSeconds = (60*Int(breakMinutes)!) + 1
var breakTimer = Timer()
var isBreakTimerRunning = false
override func viewDidLoad() {
super.viewDidLoad()
let state: UIApplicationState = UIApplication.shared.applicationState
/** Focus Time **/
if isFocusTimerRunning == false && state == .active {
runProdTimer()
}
else {
focusTimer.invalidate()
}
/** Break Time (This part doesn't work)
if isBreakTimerRunning == false && state == .background {
runBrTimer()
}
else {
breakTimer.invalidate()
} **/
}
func runProdTimer() {
focusTimer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: (#selector(HomeViewController.updateProdTimer)), userInfo: nil, repeats: true)
isFocusTimerRunning = true
}
func runBrTimer() {
breakTimer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: (#selector(HomeViewController.updateBrTimer)), userInfo: nil, repeats: true)
isBreakTimerRunning = true
}
@objc func updateProdTimer() {
if intProdSeconds < 1 {
focusTimer.invalidate()
focusSession.text = "00:00"
}
else {
intProdSeconds -= 1
focusSession.text = prodTimeString(fTime: TimeInterval(intProdSeconds))
}
}
@objc func updateBrTimer() {
if intBrSeconds < 1 {
breakTimer.invalidate()
breakSession.text = "00:00"
}
else {
intBrSeconds -= 1
breakSession.text = brTimeString(bTime: TimeInterval(intBrSeconds))
}
}
func prodTimeString(fTime: TimeInterval) -> String {
let prodMinutes = Int(fTime) / 60 % 60
let prodSeconds = Int(fTime) % 60
return String(format: "%02d:%02d", prodMinutes, prodSeconds)
}
func brTimeString(bTime: TimeInterval) -> String {
let brMinutes = Int(bTime) / 60 % 60
let brSeconds = Int(bTime) % 60
return String(format: "%02d:%02d", brMinutes, brSeconds)
}
更新:好的,下面 Sunil Chauhan 的回答有点奏效了。我能够得到时间戳和东西。但是,我 运行 遇到了另一个问题,我不明白为什么..
@objc func appWillEnterForeground() {
endDate = Date()
let secondsPassedInBackground = endDate.timeIntervalSince(beginDate)
print(secondsPassedInBackground)
let updateBrTime = intBrSeconds - Int(secondsPassedInBackground) // Updated Break Time after user returns to the app aka foreground
breakSession.text = brTimeString(bTime: TimeInterval(updateBrTime))
}
在这个函数中,我基本上是想把经过的时间从 intBrSeconds 中减去它,这就像用户为自己设置的 "Break" 时间。因此,从本质上讲,当用户离开应用程序时,它作为 "Break Timer" 运行 的计时器。标签首先会正确更新,并根据经过的时间正确减去正确的秒数。然而,在经过的时间超过大约 30 秒左右之后,计时器开始增加。所以就像它被设置为 10:00.. 它会下降说,9:34 但是下次你离开应用程序在后台并回来时,它会说 9:55或大于 9:34 的东西,这是不应该发生的。我该如何解决这个问题?
试试这个:
var beginDate = Date()
var endDate = Date()
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: #selector(appWentInBackground), name: .UIApplicationDidEnterBackground, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(appWillEnterForeground), name: .UIApplicationWillEnterForeground, object: nil)
}
@objc
func appWentInBackground() {
beginDate = Date()
}
@objc
func appWillEnterForeground() {
endDate = Date()
let secondsPassedInBackground = endDate.timeIntervalSince(beginDate)
// secondsPassedInBackground passed while app was in background.
}
我正在考虑使用 DataFormatter.localizedString... 并将该值设置为 2 个不同的变量,一个用于应用程序离开前台和应用程序返回前台的时间,然后将它们减去获取已用时间以将其设置为 breakSession.text...但我对 swift 有点陌生,不清楚如何使用 Date() 函数。我的主要目标是让 breakTimer 在应用程序处于后台时为 运行ning,而在应用程序处于前台时暂停,但用户仍应能够看到经过的时间。但显然,计时器不能在后台 运行...有人可以帮忙吗?
import UIKit
class HomeViewController: UIViewController {
@IBOutlet weak var focusSession: UILabel!
@IBOutlet weak var breakSession: UILabel!
/** Focus Time **/
var prodMinutes = String() // Productive time data from ViewController.swift arrives and is stored
lazy var intProdSeconds = (60*Int(prodMinutes)!) + 1
var focusTimer = Timer()
var isFocusTimerRunning = false // Make sure only one timer is running at a time
/** Break Time **/
var breakMinutes = String() // Break time data from BreaTimeViewController.swift arrives and is stored
lazy var intBrSeconds = (60*Int(breakMinutes)!) + 1
var breakTimer = Timer()
var isBreakTimerRunning = false
override func viewDidLoad() {
super.viewDidLoad()
let state: UIApplicationState = UIApplication.shared.applicationState
/** Focus Time **/
if isFocusTimerRunning == false && state == .active {
runProdTimer()
}
else {
focusTimer.invalidate()
}
/** Break Time (This part doesn't work)
if isBreakTimerRunning == false && state == .background {
runBrTimer()
}
else {
breakTimer.invalidate()
} **/
}
func runProdTimer() {
focusTimer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: (#selector(HomeViewController.updateProdTimer)), userInfo: nil, repeats: true)
isFocusTimerRunning = true
}
func runBrTimer() {
breakTimer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: (#selector(HomeViewController.updateBrTimer)), userInfo: nil, repeats: true)
isBreakTimerRunning = true
}
@objc func updateProdTimer() {
if intProdSeconds < 1 {
focusTimer.invalidate()
focusSession.text = "00:00"
}
else {
intProdSeconds -= 1
focusSession.text = prodTimeString(fTime: TimeInterval(intProdSeconds))
}
}
@objc func updateBrTimer() {
if intBrSeconds < 1 {
breakTimer.invalidate()
breakSession.text = "00:00"
}
else {
intBrSeconds -= 1
breakSession.text = brTimeString(bTime: TimeInterval(intBrSeconds))
}
}
func prodTimeString(fTime: TimeInterval) -> String {
let prodMinutes = Int(fTime) / 60 % 60
let prodSeconds = Int(fTime) % 60
return String(format: "%02d:%02d", prodMinutes, prodSeconds)
}
func brTimeString(bTime: TimeInterval) -> String {
let brMinutes = Int(bTime) / 60 % 60
let brSeconds = Int(bTime) % 60
return String(format: "%02d:%02d", brMinutes, brSeconds)
}
更新:好的,下面 Sunil Chauhan 的回答有点奏效了。我能够得到时间戳和东西。但是,我 运行 遇到了另一个问题,我不明白为什么..
@objc func appWillEnterForeground() {
endDate = Date()
let secondsPassedInBackground = endDate.timeIntervalSince(beginDate)
print(secondsPassedInBackground)
let updateBrTime = intBrSeconds - Int(secondsPassedInBackground) // Updated Break Time after user returns to the app aka foreground
breakSession.text = brTimeString(bTime: TimeInterval(updateBrTime))
}
在这个函数中,我基本上是想把经过的时间从 intBrSeconds 中减去它,这就像用户为自己设置的 "Break" 时间。因此,从本质上讲,当用户离开应用程序时,它作为 "Break Timer" 运行 的计时器。标签首先会正确更新,并根据经过的时间正确减去正确的秒数。然而,在经过的时间超过大约 30 秒左右之后,计时器开始增加。所以就像它被设置为 10:00.. 它会下降说,9:34 但是下次你离开应用程序在后台并回来时,它会说 9:55或大于 9:34 的东西,这是不应该发生的。我该如何解决这个问题?
试试这个:
var beginDate = Date()
var endDate = Date()
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: #selector(appWentInBackground), name: .UIApplicationDidEnterBackground, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(appWillEnterForeground), name: .UIApplicationWillEnterForeground, object: nil)
}
@objc
func appWentInBackground() {
beginDate = Date()
}
@objc
func appWillEnterForeground() {
endDate = Date()
let secondsPassedInBackground = endDate.timeIntervalSince(beginDate)
// secondsPassedInBackground passed while app was in background.
}