Reputation: 1263
In my app, I have NSTimer
which updates UILabel every second. I've added UIBackgroundTaskIdentifier
before NSTimer
to let it run in background.
__block UIBackgroundTaskIdentifier bgTask = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
[[UIApplication sharedApplication] endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
}];
timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(updateTime) userInfo:nil repeats:YES];
[[NSRunLoop mainRunLoop] addTimer:updateTimer forMode:NSRunLoopCommonModes];
. . .
-(void)updateTime
{
secondsLeft -= 1;
//NSLog(@"Update time : %d ......",secondsLeft);
dispatch_async(dispatch_get_main_queue(), ^{
_timeLbl.text = [NSString stringWithFormat:@"%d",secondsLeft];
});
}
Problem is when we press home button app gets into background, timer is running but uilabel
is not updating. E.g. Say, _timeLbl
displaying '45'. Now if I press home button, app goes into background. After 10 sec. I click app icon to get app in foreground, and there I see '45' for a while (fraction of second) and then it display 35, instead of directly display 35. That means label is not getting updated with NSTimer
. Is there any workaround to solve this ?
Thanks !
Upvotes: 1
Views: 1276
Reputation: 8322
You need to use CLLocation Manager's api for background timer update otherwise NSTimer allow 10 min execution in background .
try this : https://stackoverflow.com/a/38472381/3901620
and also add this in info.plist
<key>UIBackgroundModes</key>
<array>
<string>location</string>
</array>
Upvotes: 0
Reputation: 1357
App Delegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[[UIApplication sharedApplication]setMinimumBackgroundFetchInterval:UIApplicationBackgroundFetchIntervalMinimum];
}
- (void)applicationWillResignActive:(UIApplication *)application {
[[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
}];
}
YOUR CONTROLLER.M
- (void)viewDidLoad {
[super viewDidLoad];
timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(timerTick:) userInfo:nil repeats:YES];
}
-(void) timerTick:(NSTimer *)timer1 {
int seconds = pauseTaskTime % 60;
int minutes = (pauseTaskTime - seconds) / 60;
lblTimer.text = [NSString stringWithFormat:@"%d:%.2d", minutes, seconds]
}
When you complete your code then follows these steps :
1. Go to your project name.
2. Click Capabilities
3. On your Background Modes.
Thank You
Upvotes: 1
Reputation: 1357
Use this Code
[[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:nil];
loop = [NSTimer scheduledTimerWithTimeInterval:0.25 target:self selector:@selector(Update) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:loop forMode:NSRunLoopCommonModes];
Upvotes: 0
Reputation: 1423
In your method -(void)updateTime
after setting the text in your label write [_timeLbl layoutIfNeeded];
.
E.g:
-(void)updateTime
{
secondsLeft -= 1;
//NSLog(@"Update time : %d ......",secondsLeft);
_timeLbl.text = [NSString stringWithFormat:@"%d",secondsLeft];
[_timeLbl layoutIfNeeded];
}
layoutIfNeeded checks that the view is needed to be updated or not and updates if needed. I one word it refreshes the view.
Upvotes: 0
Reputation: 705
this is working fine for me.
[[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:nil];
countDown = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(timeLeftSinceDate) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:countDown forMode:NSRunLoopCommonModes];
Upvotes: 0
Reputation: 412
Try updating the label using a reference date instead of instance variable secondsLeft.
secondsLeft = [[NSDate date] timeIntervalSinceDate:referenceDate]
Upvotes: 0
Reputation: 2294
Try this
-(void)updateTime {
secondsLeft -= 1;
//NSLog(@"Update time : %d ......",secondsLeft);
dispatch_async(dispatch_get_main_queue(), ^{
timeLbl.text = [NSString stringWithFormat:@"%d",secondsLeft];
});
}
If you change it on main queue, it will get updated. I faced it long back and sorted in this way.
Upvotes: 0