Swift 3 - How to make timer work in background

跟風遠走 提交于 2019-12-28 06:01:02

问题


i am trying to do an application which can make a timer run in background.

here's my code:

let taskManager = Timer.scheduledTimer(timeInterval: 10, target: self, selector: #selector(self.scheduleNotification), userInfo: nil, repeats: true)
        RunLoop.main.add(taskManager, forMode: RunLoopMode.commonModes)

above code will perform a function that will invoke a local notification. this works when the app is in foreground, how can i make it work in the background?

i tried to put several print lines and i saw that when i minimize (pressed the home button) the app, the timer stops, when i go back to the app, it resumes.

i wanted the timer to still run in the background. is there a way to do it?

here's what i want to happen:

run app -> wait 10 secs -> notification received -> wait 10 secs -> notification received -> and back to wait and received again

that happens when in foreground. but not in background. pls help.


回答1:


you can go to Capabilities and turn on background mode and active Audio. AirPlay, and picture and picture.

It really works . you don't need to set DispatchQueue . you can use of Timer.

Timer.scheduledTimer(withTimeInterval: 1, repeats: true) { (t) in

   print("time")
}



回答2:


A timer can run in the background only if both the following are true:

  • Your app for some other reason runs in the background. (Most apps don't; most apps are suspended when they go into the background.) And:

  • The timer was running already when the app went into the background.




回答3:


============== For Objective c ================

create Global uibackground task identifier.

UIBackgroundTaskIdentifier bgRideTimerTask;

now create your timer and add BGTaskIdentifier With it, Dont forget to remove old BGTaskIdentifier while creating new Timer Object.

 [timerForRideTime invalidate];
 timerForRideTime = nil;

 bgRideTimerTask = UIBackgroundTaskInvalid;

 UIApplication *sharedApp = [UIApplication sharedApplication];       
 bgRideTimerTask = [sharedApp beginBackgroundTaskWithExpirationHandler:^{

                            }];
 timerForRideTime =  [NSTimer scheduledTimerWithTimeInterval:1.0
                                                                                 target:self
                                                                               selector:@selector(timerTicked:)
                                                                               userInfo:nil
                                                                                repeats:YES]; 
                                                   [[NSRunLoop currentRunLoop]addTimer:timerForRideTime forMode: UITrackingRunLoopMode];

Here this will work for me even when app goes in background.ask me if you found new problems.




回答4:


Timer won't work in background. For background task you can check this link below...

https://www.raywenderlich.com/143128/background-modes-tutorial-getting-started




回答5:


You dont really need to keep up with a NSTImer object. Every location update comes with its own timestamp.

Therefore you can just keep up with the last time vs current time and every so often do a task once that threshold has been reached:

            if let location = locations.last {
                let time = location.timestamp

                guard let beginningTime = startTime else {
                    startTime = time // Saving time of first location time, so we could use it to compare later with subsequent location times.
                    return //nothing to update
                }

                let elapsed = time.timeIntervalSince(beginningTime) // Calculating time interval between first and second (previously saved) location timestamps.

                if elapsed >= 5.0 { //If time interval is more than 5 seconds
                    //do something here, make an API call, whatever.

                    startTime = time
                }
}



回答6:


As others pointed out, Timer cannot make a method run in Background. What you can do instead is use while loop inside async task

DispatchQueue.global(qos: .background).async {
                while (shouldCallMethod) {
                    self.callMethod()
                    sleep(1)
                }
}


来源:https://stackoverflow.com/questions/42319172/swift-3-how-to-make-timer-work-in-background

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!