NSTimer stops running in the background after a while

Hi, I am developing an application in which I have to run the API every 30 seconds, so I created NSTimer for it. But when my application goes into the background timer, it stops shooting after 3-4 minutes. Thus, it only works for 3-4 minutes in the background, but not after that. How can I change my code so that the timer does not stop.

Here is my code.

- (IBAction)didTapStart:(id)sender {
    NSLog(@"hey i m in the timer ..%@",[NSDate date]);
    [objTimer invalidate];
    objTimer=nil;

    UIBackgroundTaskIdentifier bgTask = UIBackgroundTaskInvalid;
    UIApplication  *app = [UIApplication sharedApplication];
    bgTask = [app beginBackgroundTaskWithExpirationHandler:^{
        [app endBackgroundTask:bgTask];
    }];
    objTimer = [NSTimer scheduledTimerWithTimeInterval:30.0 target:self
                                                       selector:@selector(methodFromTimer) userInfo:nil repeats:YES];
    [[NSRunLoop currentRunLoop] addTimer:objTimer forMode:UITrackingRunLoopMode];
}

-(void)methodFromTimer{
    [LOG debug:@"ViewController.m ::methodFromTimer " Message:[NSString stringWithFormat:@"hey i m from timer ....%@",[NSDate date] ]];
    NSLog(@"hey i m from timer ....%@",[NSDate date]);
}

I even changed the code with the following:

[[NSRunLoop mainRunLoop] addTimer:objTimer forMode:NSRunLoopCommonModes];

That didn't work either.

+4
source share
4 answers

Do not create the UIBackgroundTaskIdentifier task as local and make it global, as shown below:

Step 1

Initiating varible

Step -2

ViewDidLoad Method and added barButton

Step -3

BarButton method call

Step -4

Timer method call

, - - 1 . , PLS, .

-, . enter image description here

, 3 . , 3- , uibackgroundtask .

: - bgTask = [app beginBackgroundTaskWithExpirationHandler: ^ {       [app endBackgroundTask: bgTask];// , , , , vairbles .   }];

, .

, ur, expirationHandler, , , .

Highlighted part is when I reached handler

+7

, NSTimer. , . API- , Apple. , , API. , .

, , Appcoda

+2

.

iOS7 3 . 10 , . , , , Bluetooth, "" .

, , " ".

. .

+2

, StackOverflow .

, . AppDelegate.RestartBackgroundTimer(), , - . , 3 ( ):

class AppDelegate: UIResponder, UIApplicationDelegate {
    static var backgroundTaskIdentifier: UIBackgroundTaskIdentifier? = nil;

    static func RestartBackgroundTimer() {
        if (AppDelegate.backgroundTaskIdentifier != nil) {
            print("RestartBackgroundTimer: Ended existing background task");
            UIApplication.sharedApplication().endBackgroundTask(AppDelegate.backgroundTaskIdentifier!);
            AppDelegate.backgroundTaskIdentifier = nil;
        }
        print("RestartBackgroundTimer: Started new background task");
        AppDelegate.backgroundTaskIdentifier = UIApplication.sharedApplication().beginBackgroundTaskWithExpirationHandler({
            UIApplication.sharedApplication().endBackgroundTask(AppDelegate.backgroundTaskIdentifier!);
            AppDelegate.backgroundTaskIdentifier = nil;
        })
    }
}

, . , ( , , Info.plist " " " / AirPlay" aka "audio" ):

import AVFoundation;

// setup audio to not stop in background or when silent
do {
    try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback);
    try AVAudioSession.sharedInstance().setActive(true);
} catch { }

Now, in the class for which the timer should work for more than 3 minutes (if in the background), you need to play the sound when only 30 seconds of background time are left. This will reset the background time to 3 minutes (just create "Silent.mp3", for example AudaCity, and drag it into the Xcode project).

To do all this, do the following:

import AVFoundation

class MyViewController : UIViewController {
    var timer : NSTimer!;

    override func viewDidLoad() {
        // ensure we get background time & start timer
        AppDelegate.RestartBackgroundTimer();
        self.timer = NSTimer.scheduledTimerWithTimeInterval(0.25, target: self, selector: #selector(MyViewController.timerInterval), userInfo: nil, repeats: true);
    }

    func timerInterval() {
        var bgTimeRemaining = UIApplication.sharedApplication().backgroundTimeRemaining;
        print("Timer... " + NSDateComponentsFormatter().stringFromTimeInterval(bgTimeRemaining)!);
        if NSInteger(bgTimeRemaining) < 30 {
            // 30 seconds of background time remaining, play silent sound!
            do {
                var audioPlayer = try AVAudioPlayer(contentsOfURL: NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource("Silent", ofType: "mp3")!));
                audioPlayer.prepareToPlay();
                audioPlayer.play();
            } catch { }
        }
    }
}
+2
source

All Articles