I'm trying to use this cool timer from kavsoft
But when i hide app or turn off screen device (not close app) this timer after a couple of seconds or minutes in the background mode stops counting and stops. If I open the application, it continues to count down again.
I tried on the original code and on my modified one. In mine, I made the format of hours minutes seconds. In any of them, counting in background mode stops working. Is any way to fix it? it may take up to 2 hours for my needs in app to work in background mode. Here is my modifed code in swift
import SwiftUI
import UserNotifications
struct TimerDiscovrView : View {
@State var start = false
@State var to : CGFloat = 0
@State var MaxCount = 0
@State var count = 0
var testTimer: String
var testName: String
@State var time = Timer.publish(every: 1, on: .main, in: .common).autoconnect()
var body: some View{
ZStack{
//заливка экрана
Color.black.opacity(0.06).edgesIgnoringSafeArea(.all)
VStack{
ZStack{
Circle()
.trim(from: 0, to: 1)
.stroke(Color.black.opacity(0.09), style: StrokeStyle(lineWidth: 35, lineCap: .round))
.frame(width: 280, height: 280)
Circle()
.trim(from: 0, to: self.to)
.stroke(Color.red, style: StrokeStyle(lineWidth: 35, lineCap: .round))
.frame(width: 280, height: 280)
.rotationEffect(.init(degrees: -90))
VStack{
Text("\(valueFormat(mCount: count/3600)):\(valueFormat(mCount: count/60%60)):\(valueFormat(mCount: count%60))")
.font(.system(size: 45))
.fontWeight(.bold)
.padding(.top)
.padding(.bottom)
Text(LocalizedStringKey("Total time")).lineLimit(2)
Text("\(valueFormat(mCount: MaxCount/3600)):\(valueFormat(mCount: MaxCount/60%60)):\(valueFormat(mCount: MaxCount%60))")
.font(.title)
}
}
VStack {
HStack(spacing: 20){
Button(action: {
if self.count == MaxCount {
self.count = 0
withAnimation(.default){
self.to = 0
}
}
self.start.toggle()
}) {
HStack(spacing: 15){
Image(systemName: self.start ? "pause.fill" : "play.fill")
.foregroundColor(.white)
//текст на кнопке
// Text(self.start ? "Pause" : "Play")
// .foregroundColor(.white)
}
.padding(.vertical)
.frame(width: (UIScreen.main.bounds.width / 2) - 55)
.background(Color.red)
.clipShape(Capsule())
.shadow(radius: 6)
}
Button(action: {
self.count = 0
withAnimation(.default){
self.to = 0
}
}) {
HStack(spacing: 15){
Image(systemName: "arrow.clockwise")
.foregroundColor(.red)
//текст на кнопке
// Text("Restart")
// .foregroundColor(.red)
}
.padding(.vertical)
.frame(width: (UIScreen.main.bounds.width / 2) - 55)
.background(
Capsule()
.stroke(Color.red, lineWidth: 2)
)
.shadow(radius: 6)
}
}
Text(LocalizedStringKey("Set timer for")).font(.subheadline).lineLimit(1)
Text("\(testName)").font(.title).lineLimit(2)
VStack {
Text(LocalizedStringKey("Attention")).font(.footnote).foregroundColor(.gray).fixedSize(horizontal: false, vertical: true)
}.padding(.horizontal)
}
.padding(.top)
.padding(.bottom, 30)
}
}.navigationBarTitle(LocalizedStringKey("Set timer"), displayMode: .inline)
.onAppear(perform: {
if self.MaxCount == 0 {
let arrayTimer = testTimer.split(separator: " ")
if arrayTimer.count > 1 {
let counts = Int(arrayTimer[0]) ?? 0
/// Преобразование в секунды
switch arrayTimer[1] {
case "min":
self.MaxCount = counts*60
case "hour":
self.MaxCount = counts*3600
case "hours":
self.MaxCount = counts*3600
default:
self.MaxCount = counts
}
}
}
UNUserNotificationCenter.current().requestAuthorization(options: [.badge,.sound,.alert]) { (_, _) in
}
})
.onReceive(self.time) { (_) in
if self.start{
if self.count != MaxCount {
self.count += 1
print("hello")
withAnimation(.default){
self.to = CGFloat(self.count) / CGFloat(MaxCount)
}
}
else {
self.start.toggle()
self.Notify()
}
}
}
}
func Notify(){
let content = UNMutableNotificationContent()
/// key - ключ_локализованной_фразы, comment не обязательно заполнять
content.title = NSLocalizedString("Perhaps your test is ready", comment: "")
/// с аргументами (key заменяете на нужное)
// Вид локализованной строки в файлах локализации "key %@"="It,s time to check your %@";
content.body = String.localizedStringWithFormat(NSLocalizedString("It's time to check your %@", comment: ""), self.testName)
let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 1, repeats: false)
let req = UNNotificationRequest(identifier: "MSG", content: content, trigger: trigger)
UNUserNotificationCenter.current().add(req, withCompletionHandler: nil)
}
func valueFormat(mCount: Int) -> String {
String(format: "%02d", arguments: [mCount])
}
}