Using NSTimer to play sound at set intervals, not working in the background Xcode6.4

I am new to writing applications.

Just wrote my first half marathon app. This is a start / walk timer that plays the sound “Run” or “Walk”, when it switches to the activity mode, users select these intervals. The application works fine on my phone when it is active, but stops in the background. I looked at a lot of posts on Stackflow, and many said you shouldn't use NStimer in the background.
I would like some help to make it work in the background. Thanks in advance.

I am using Xcode 6.4

My code is:

timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: Selector("Counting"), userInfo: nil, repeats: true) func Counting(){ timerCount += 1 tcSec = (timerCount % 3600 ) % 60 tcMin = (timerCount % 3600) / 60 tcHour = (timerCount / 3600) let strSec = String(format: "%02d", tcSec) let strMin = String(format: "%02d", tcMin) let strHour = String(format: "%02d", tcHour) totalTime.text = "\(strHour):\(strMin):\(strSec)" if isRunning == true { if runCounter != 0 { runCounter -= 1 tcSec = (runCounter % 3600 ) % 60 tcMin = (runCounter % 3600) / 60 tcHour = (runCounter / 3600) let strSec = String(format: "%02d", tcSec) let strMin = String(format: "%02d", tcMin) let strHour = String(format: "%02d", tcHour) timerLabel.text = "\(strHour):\(strMin):\(strSec)" } else { isRunning = false activityLabel.text = "Walk Time Left" playWalkSound() runCounter = runMax }} else { if walkCounter != 0 { walkCounter -= 1 tcSec = (walkCounter % 3600 ) % 60 tcMin = (walkCounter % 3600) / 60 tcHour = (walkCounter / 3600) let strSec = String(format: "%02d", tcSec) let strMin = String(format: "%02d", tcMin) let strHour = String(format: "%02d", tcHour) timerLabel.text = "\(strHour):\(strMin):\(strSec)" } else { isRunning = true activityLabel.text = "Run Time Left" playRunSound() walkCounter = walkMax }} } 
0
source share
1 answer

Since iOS 7 you only have 180 seconds of background time, but when you press the home button, you do not force the application to run in the background. You are creating a suspend application in the background. Your code does not run when you are in the background.

According to Apple :

When the user is not actively using your application, the system moves it to the background state. For many applications, the background state is just a brief stop on the way to pausing the application. Pausing applications is a way to increase battery life, which also allows the system to allocate important system resources for a new foreground application that has attracted the attention of users.

Applications need special permission to run in the background in order to perform certain limited actions, such as location, audio or Bluetooth, which will keep it in the background.

There is a trick that you can use, but you don’t allow the application for more than ~ 180 s , just implement the scheduledTimerWithTimeInterval:target:selector:userInfo:repeats: method as usual and put the following in AppDelegate :

 var backgroundUpdateTask: UIBackgroundTaskIdentifier = 0 func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { return true } func applicationWillResignActive(application: UIApplication) { self.backgroundUpdateTask = UIApplication.sharedApplication().beginBackgroundTaskWithExpirationHandler({ self.endBackgroundUpdateTask() }) } func endBackgroundUpdateTask() { UIApplication.sharedApplication().endBackgroundTask(self.backgroundUpdateTask) self.backgroundUpdateTask = UIBackgroundTaskInvalid } func applicationWillEnterForeground(application: UIApplication) { self.endBackgroundUpdateTask() } 

After 180 seconds, the timer will not start anymore, when the application returns to the foreground, it will start to light up again.

I highly recommend you read Apple's Background Execution tutorial, you can know how it works and fill your needs. Hope this helps you.

0
source

Source: https://habr.com/ru/post/1242820/


All Articles