1

When my app is downloading big file and user switching to the other app, i'm running background task like this:
beginBackgroundTaskWithExpirationHandler:
and then if user opening "app switcher" by double click, screenshot of my app is completely random. Sometimes it's showing view controller that was not even open in the app.

ignoreSnapshotOnNextApplicationLaunch not helping, because it's not working at all.

Apple says: Avoid updating your windows and views here: documentation, but I'm not updating views.

I'm also running timer, to check how much background time is left, and this timer is the cause of my problems. If I'm not creating it, everything is working perfect, but I cannot save download state in Expiration handler - not enough time.
How can i avoid this weird behaviour?

-(void)appDidEnterBackground {
    UIApplication *application = [UIApplication sharedApplication];
    __block UIBackgroundTaskIdentifier bgTask;
    bgTask = [application beginBackgroundTaskWithExpirationHandler:^{
        [application endBackgroundTask:bgTask];
        bgTask = UIBackgroundTaskInvalid;
    }];

    if(backgroundTimer == nil || ![backgroundTimer isValid]) {
        backgroundTimer = [[NSTimer alloc]
                initWithFireDate:[NSDate dateWithTimeIntervalSinceNow:0]
                        interval:1
                          target:self
                        selector:@selector(checkBackgroundTimeRemaining)
                        userInfo:nil
                         repeats:YES];
        [[NSRunLoop currentRunLoop] addTimer:backgroundTimer forMode:NSRunLoopCommonModes];
        [[NSRunLoop currentRunLoop] run];
    }
}

- (void)checkBackgroundTimeRemaining {
    NSTimeInterval timeRemaining = [[UIApplication sharedApplication] backgroundTimeRemaining];

    if(timeRemaining < 5) {
        if(backgroundTimer != nil) {
            [backgroundTimer invalidate];
            backgroundTimer = nil;
        }
        [downloadTask cancelByProducingResumeData:^(NSData *resumeData) {
            [self saveResumeData:resumeData];
        }];
    }
}
trickster77777
  • 1,198
  • 2
  • 19
  • 30

1 Answers1

1

Sometimes it's showing view controller that was not even open in the app.

This sounds really fishy and should never happen. Maybe you can add some code to show what you are doing?

ignoreSnapshotOnNextApplicationLaunch is irrelevant here since it's only used to determine what happens when the user taps on your icon again to open the app.

Did you maybe forget to call endBackgroundTask: when you've finished your background task?

I'm not sure what you intend with the timer? If it is to determine how much time is left for you to execute in the background, use UIApplication's backgroundTimeRemaining instead.

camimvogelsang
  • 289
  • 1
  • 4
  • 10
  • I've get rid of the timer now. I'm checking time remaining when another portion of the data downloaded. Still can not understand how timer could affect the work of the app switcher. – trickster77777 Jun 29 '14 at 11:43
  • The app switcher just shows the last view that was shown when your app went to the background. When you're fetching in the background, it is captured after you called the completion handler in application:performFetchWithCompletionHandler: – camimvogelsang Jun 29 '14 at 13:06