【发布时间】:2019-09-09 08:00:40
【问题描述】:
我正在使用 Google Firestore 作为我正在制作的 iOS 应用的后端服务器。我正在尝试加入一个倒数计时器来表示游戏何时开始,但是,使用网络时间而不是设备时间来确保每个人同时开始游戏是至关重要的。
基本思想是从 Firebase 检索当前时间戳,从我希望游戏开始时的另一个时间戳值中减去它,然后每秒不断刷新按钮文本(不是标签,因为我需要能够按下它以揭示更多信息)与时差。
当应用程序启动时,计时器工作得非常好,没有/非常小的延迟但是,如果我更改我希望游戏开始的时间值,按钮文本会由于某种原因出现故障。即使在调试区域,我也可以看到它的滞后。
我已经完成了所有的数学计算和转换。当前时间戳是一个 timeIntervalSince1970 值,我将其转换为格式为“HH:mm:ss”的字符串。我正在从 firebase 服务器值中检索此值。我希望游戏开始时的另一个时间戳是我存储在 Firestore 集合中的字符串值。
我将这两个字符串值发送到为我找到差异的函数,并将按钮文本设置为该值。这很简单,但我不明白为什么当我更改第二个时间戳值时它开始滞后。如果我第三次更改它,应用程序仍然运行,但计时器基本上每 8 秒左右冻结一次。
覆盖 func viewDidAppear(_ animated: Bool) {
DispatchQueue.main.async {
let timer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { timer in
Firestore.firestore().collection("countdown").document("thursday")
.addSnapshotListener { documentSnapshot, error in
guard let document = documentSnapshot else {
print("Error fetching document: \(error!)")
return
}
guard let theTime = document.data() else {
print("Document data was empty.")
return
}
print("Current data: \(theTime)")
let stringData = "\(theTime)"
let finalTime = stringData.substring(from: 9, to: 16)
// 也许不是获得正确格式的最传统方法,但它对我有用。我当然愿意接受建议。
var currentTimeStamp: Double?
let ref = Database.database().reference().child("serverTimestamp")
ref.setValue(ServerValue.timestamp())
ref.observe(.value, with: { snap in
if let t = snap.value as? Double {
currentTimeStamp = t/1000
let unixTimestamp = currentTimeStamp
let date = Date(timeIntervalSince1970: unixTimestamp!)
let dateFormatter = DateFormatter()
dateFormatter.timeZone = TimeZone(abbreviation: "EDT") //Set timezone that you want
dateFormatter.locale = NSLocale.current
dateFormatter.dateFormat = "HH:mm:ss" //Specify your format that you
let strDate = dateFormatter.string(from: date)
let dateDiff = self.findDateDiff(time1Str: strDate, time2Str: finalTime)
print("This is the countdown time: \(dateDiff)")
}
})
}
}
}
// 这只是函数内部的一个峰值,它执行所有数学运算并在按钮文本中输出倒计时时间。我有许多适用于所有场景的 if 语句来计算“HH:mm:ss”格式。
如果小时 >= 10 && 分钟 >= 10 && 秒
self.time.setTitle(("\(Int(hours)):\(Int(minutes)):0\(Int(seconds))"), for: .normal)
我希望按钮文本以正确的倒计时时间刷新。我希望当我更改 Firestore 时间戳值时,按钮文本会自动刷新并且不会滞后。
实际结果是滞后了。
【问题讨论】:
标签: swift firebase timestamp google-cloud-firestore countdown