如何解决WKExtendedRuntimeSession 在大约 30 秒后停止?
这真的让我抓狂。我在这里尝试了各种组合以达到这一点。它有时有效,而其他时候无效。当它起作用时,它会在后台自行停止。请帮忙。总的来说,我对编码完全是个菜鸟,并尝试了许多不同的方法,所以我对它的笨拙表示歉意。
if inspectionTime == true {
if stopWatchManager.mode == .stopped {
ZStack{
HStack {
if stopWatchManager.minutesElapsed > 0 {
if stopWatchManager.secondsElapsed < 10 {
Text("\(stopWatchManager.minutesElapsed) :0")
.font(.largeTitle)
.contentShape(Rectangle())
.onTapGesture(count: 2,perform: {
stopWatchManager.resetToZero()
})
.foregroundColor(isPressingDown ? .green : .white)
.gesture(LongPressGesture(minimumDuration: 0.5)
.sequenced(before: LongPressGesture(minimumDuration: .infinity))
.updating($isPressingDown) { value,state,transaction in
switch value {
case .second(true,nil): //This means the first Gesture completed
state = true
default: break
}
})
}
else {
Text("\(stopWatchManager.minutesElapsed) :")
.font(.largeTitle)
.contentShape(Rectangle())
.onTapGesture(count: 2,nil): //This means the first Gesture completed
state = true
default: break
}
})
}
}
Text("\(stopWatchManager.secondsElapsed,specifier: "%.02f")")
.font(.largeTitle)
.contentShape(Rectangle())
.onTapGesture(count: 2,perform: {
stopWatchManager.resetToZero()
})
.foregroundColor(isPressingDown ? .green : .white)
.gesture(LongPressGesture(minimumDuration: 0.5)
.sequenced(before: LongPressGesture(minimumDuration: .infinity))
.updating($isPressingDown) { value,transaction in
switch value {
case .second(true,nil): //This means the first Gesture completed
state = true
default: break
}
})
.onChange(of: isPressingDown,perform: { value in
if isPressingDown == false {
if session.state == WKExtendedRuntimeSessionState.notStarted{
session.start()}
if showCountdown == false {
showCountdown = true
DispatchQueue.main.asyncAfter(deadline: .now() + 13.5){
if showCountdown == true {
stopWatchManager.start()
showCountdown = false}
}
}
else if showCountdown == true{
stopWatchManager.start()
showCountdown = false
}
turnGreen = false
}
else if isPressingDown == true{
// DispatchQueue.main.asyncAfter(deadline: .now() + 0.5){
WKInterfaceDevice.current().play(.click)
// }
}
if showCountdown == true && isPressingDown == true {
turnGreen = true
}
})
}
if showCountdown == true {
CountdownView()}
Rectangle()
.contentShape(Rectangle())
.onTapGesture(count: 2,perform: {
stopWatchManager.resetToZero()
showCountdown = false
})
.gesture(LongPressGesture(minimumDuration: 0.5)
.sequenced(before: LongPressGesture(minimumDuration: .infinity))
.updating($isPressingDown) { value,transaction in
switch value {
case .second(true,nil): //This means the first Gesture completed
state = true
default: break
}
})
.opacity(0.1)
.foregroundColor(.black)
.gesture(LongPressGesture(minimumDuration: 0.5)
.sequenced(before: LongPressGesture(minimumDuration: .infinity))
.updating($testing) { value,nil): //This means the first Gesture completed
state = true
default: break
}
})
}
}
else if stopWatchManager.mode == .running {
ZStack{
HStack{
if stopWatchManager.minutesElapsed > 0 {
if stopWatchManager.secondsElapsed < 10 {
Text("\(stopWatchManager.minutesElapsed) :0")
.font(.largeTitle)
.contentShape(Rectangle())
.onTapGesture(count: 2,perform: {
stopWatchManager.resetToZero()
})
.foregroundColor(isPressingDown ? .green : .white)
.gesture(LongPressGesture(minimumDuration: 0.5)
.sequenced(before: LongPressGesture(minimumDuration: .infinity))
.updating($isPressingDown) { value,transaction in
switch value {
case .second(true,nil): //This means the first Gesture completed
state = true
default: break
}
})
}
else {
Text("\(stopWatchManager.minutesElapsed) :")
.font(.largeTitle)
// .frame(width: 500.0,height: 500.0)
.contentShape(Rectangle())
.onTapGesture(count: 2,nil): //This means the first Gesture completed
state = true
default: break
}
})
}
}
Text(String(format: "%.02f",stopWatchManager.secondsElapsed))
.font(.largeTitle)
//.frame(width: 500.0,height: 500.0)
.contentShape(Rectangle())
.onTapGesture {
if stopWatchManager.mode == .running {
stopWatchManager.stop()
}
}
.onChange(of: stopWatchManager.secondsElapsed,perform: {value in
if stopWatchManager.secondsElapsed >= 60{
stopWatchManager.secondsElapsed = 0
stopWatchManager.minutesElapsed = stopWatchManager.minutesElapsed + 1
}})
}
Rectangle()
.contentShape(Rectangle())
.onTapGesture{
if stopWatchManager.mode == .running {
stopWatchManager.stop()
}
}
.gesture(LongPressGesture(minimumDuration: 0.5)
.sequenced(before: LongPressGesture(minimumDuration: .infinity))
.updating($isPressingDown) { value,nil): //This means the first Gesture completed
state = true
default: break
}
})
.opacity(0.01)
.foregroundColor(.black)}}}
class StopWatchManager: ObservableObject {
var session = WKExtendedRuntimeSession()
let scoreList = ScoreList()
@AppStorage("countdown") var countdown = "15"
@AppStorage("bigDNF") var bigDNF: Bool = false
@Published var secondsElapsed = 0.00
@Published var minutesElapsed = 0
@Published var mode: stopWatchMode = .stopped
@State private var timeRemaining = 100
let countdownTimer = Timer.publish(every: 1,on: .main,in: .common).autoconnect()
@ObservedObject var scoreStore = ScoreStore()
@AppStorage("newScore") var newScore = ""
@AppStorage("save") var save = false
@AppStorage("plus2") var plus2 = false
var timer = Timer()
func start() {
session = WKExtendedRuntimeSession()
if session.state == WKExtendedRuntimeSessionState.notStarted{
session.start()}
mode = .running
WKInterfaceDevice.current().play(.start)
secondsElapsed = 0
minutesElapsed = 0
timer = Timer.scheduledTimer(withTimeInterval: 0.01,repeats: true) { timer in
self.secondsElapsed += 0.01
}
}
func stop() {
let formattedSeconds = String(format: "%.02f",secondsElapsed)
timer.invalidate()
mode = .stopped
WKInterfaceDevice.current().play(.start)
if plus2 == true {
secondsElapsed = secondsElapsed + 2
}
//DispatchQueue.main.asyncAfter(deadline: .now() + 1.0)
if minutesElapsed > 0{
newScore = "\(minutesElapsed) :\(formattedSeconds)"
save = true
}
else {
newScore = "\(formattedSeconds)"
}
save = true
// session.invalidate()
}
func resetToZero() {
secondsElapsed = 0
minutesElapsed = 0
WKInterfaceDevice.current().play(.click)
bigDNF = false
}
}
解决方法
WatchOS 故意限制在后台执行的机会,因为它会耗尽电池电量。不需要后台任务来实现秒表。
当您的应用出现在屏幕上时,您需要运行一个计时器,以便定期更新显示。要跟踪经过的时间,您可以简单地记录秒表开始的 Date
。由于时间总是向前推进,因此当应用程序不在屏幕上时,您不需要后台任务。当用户返回您的应用时,您可以根据该开始日期简单地计算并显示经过的时间。
我在下面包含了一个最小的秒表视图。请注意,UserDefaults
无法存储 Date
对象,因此我将开始日期存储为 Double
- 自参考日期以来的时间。
也不需要手势识别器 - 您只需使用 Button
struct StopwatchView: View {
@AppStorage("running") var running = false
@AppStorage("started") var started = Date.distantPast.timeIntervalSinceReferenceDate
let timer = Timer.publish(every: 0.2,on: .main,in: .common).autoconnect()
@AppStorage("minutes") var elapsedMinutes = 0
@AppStorage("seconds") var elapsedSeconds = 0
@State var elapsed = "00:00"
var body: some View {
VStack {
Text(elapsed).onReceive(timer) { input in
self.elapsed = elapsedTime()
}.font(.system(.headline,design: .monospaced))
Spacer()
Button( action: {
self.running.toggle()
if self.running {
self.started = Date().timeIntervalSinceReferenceDate
}
}) {
Text(self.running ? "Stop":"Start")
}.buttonStyle(BorderedButtonStyle(tint: self.running ? Color.red : Color.green))
}
.padding()
}
func elapsedTime() -> String {
if self.running {
let startDate = Date(timeIntervalSinceReferenceDate: self.started)
let elapsedTime = max( Date().timeIntervalSince(startDate),0)
elapsedMinutes = Int(elapsedTime / 60)
elapsedSeconds = Int(elapsedTime - Double(elapsedMinutes * 60))
}
return String(format:"%02d:%02d",elapsedMinutes,elapsedSeconds)
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。