2

I'd like to show a (local) notification to the user when my app is terminated, be it by iOS itself or by the user via the task switcher.

When iOS kills the app because of memory pressure the applicationWillTerminate function is called on my AppDelegate, so I can schedule a local notification in that case.

However, when the user kills the app by swiping it to the top in the task switcher, the applicationWillTerminate function is not called (as stated in the Apple docs and various answers here on SO). And yet, there are apps that still do succeed in showing a (local) notification to the user in that case (especially fitness tracking apps, e.g. Human), asking the user to restart the app so the background tracking can continue.

I can think of some (mostly awkward, or at least battery consuming) ways to get this done, but is there a nice way to show such a notification to the user? Especially to do so almost instantly after the app is killed by the user, which excludes a lot of possible workarounds with scheduling and cancelling local notifications every n seconds in the background ...

TheEye
  • 9,280
  • 2
  • 42
  • 58
  • You can find much about this on apple docs, but if app is suspended then appwillterminates will never get called but if its in background then it will get called for the case when user kills it https://developer.apple.com/library/ios/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/TheAppLifeCycle/TheAppLifeCycle.html#//apple_ref/doc/uid/TP40007072-CH2-SW3 – Adnan Aftab Aug 11 '15 at 15:07
  • Yes, that one I know - it's the "user kills app" case I'm interested in ... – TheEye Aug 12 '15 at 06:29

2 Answers2

1

Found it ... apparently the apps that show a notification like the one I want to show do it by using background location updates to (re)schedule a local notification so it will never show up, and once they are killed by the user the notification stays active and fires.

Doesn't sound that nice, but probably it's the only way to do it apart from pinging the app from the server periodically.

It would be nice to have a more decent (and energy-efficient) way to do this, e.g. by consistently getting the time to do something just before an app is terminated, no matter the reason for termination.

TheEye
  • 9,280
  • 2
  • 42
  • 58
0

I tried like this:

  • Must enable background mode (bluetooth, voip, location service)
  • Add this code in didFinishLaunchingWithOptions:

    [self addLocalNotification];
    [NSTimer scheduledTimerWithTimeInterval:9.0f
                                         target:self
                                   selector:@selector(addLocalNotification)
                                       userInfo:nil
                                        repeats:YES];
    
  • in addLocalNotification

    - (void) addLocalNotification{
    NSDate * theDate = [[NSDate date] dateByAddingTimeInterval:10]; // set a localnotificaiton for 10 seconds
    
    UIApplication* app = [UIApplication sharedApplication];
    NSArray*    oldNotifications = [app scheduledLocalNotifications];
    
    
    // Clear out the old notification before scheduling a new one.
    if ([oldNotifications count] > 0)
        [app cancelAllLocalNotifications];
    
    // Create a new notification.
    UILocalNotification* alarm = [[UILocalNotification alloc] init];
    if (alarm)
    {
        alarm.fireDate = theDate;
        alarm.timeZone = [NSTimeZone defaultTimeZone];
        alarm.repeatInterval = 0;
        alarm.alertBody =@"App must run" ;
    
        [app scheduleLocalNotification:alarm];
    }}
    

And it works for me. addLocalNotification will run as long as app run/background. Once it is Terminated already scheduled local notification will fire on time. Time interval we can change on our interest.

Naga Harish M
  • 2,779
  • 2
  • 31
  • 45