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

元气小坏坏 提交于 2019-12-11 16:29:30

问题


I'm brand new to writing apps.

Just wrote my first app for training for a half marathon. It is a run/walk timer that plays a "Run" or "Walk" sound when it's time to switch activity mode, users select those intervals. The app works fine on my phone when it's active, but stops in the background. I searched through a lot of posts on Stackflow, and many said you should not use NStimer in the background.
Would love some help is getting this to work in the background. Thanks in advance.

I'm using Xcode 6.4

My code:

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
        }}

}

回答1:


Since iOS 7 you have only 180 seconds of background time, but when you tap the home button, you do not make your app run in the background. You make your app suspend 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 app, the system moves it to the background state. For many apps, the background state is just a brief stop on the way to the app being suspended. Suspending apps is a way of improving battery life it also allows the system to devote important system resources to the new foreground app that has drawn the user’s attention.

Apps need get special permission to run in the background just in order to perform certain limited activities like location, audio or bluetooth which will keep it alive in background.

There is some trick you can use , but still don't allow the app more than ~180s, just implement scheduledTimerWithTimeInterval:target:selector:userInfo:repeats: method as usual and put the following in your 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 180s the timer will not fire more, when the app will comeback in foreground it will start to fire again.

I strongly recommend you read the Background Execution tutorial of Apple to you can know how it works and fill your needs. I hope this help you.



来源:https://stackoverflow.com/questions/31764477/using-nstimer-to-play-sound-at-set-intervals-not-working-in-background-xcode6-4

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