Local notification on application termination

14,799

Solution 1

You will not receive any notice when it gets terminated, when your app is suspended in the background.

iOS will send a kill -9 signal for your apps progress and you app is just killed, this is the same thing that happens when the user kills your app from the quicklaunch tray.

From the Apple documentation:

Even if you develop your app using iOS SDK 4 and later, you must still be prepared for your app to be killed without any notification. The user can kill apps explicitly using the multitasking UI. In addition, if memory becomes constrained, the system might remove apps from memory to make more room. Suspended apps are not notified of termination but if your app is currently running in the background state (and not suspended), the system calls the applicationWillTerminate: method of your app delegate. Your app cannot request additional background execution time from this method.

Solution 2

Applications can create a local notification at a "future" date and time which could be used to notify the user that the application was terminated. If they then tap the application they can then restart your app.

This is working in my app that uses/requires Bluetooth Central in the info.plist (so it will run in the background). I assume that you will have configured your application to run in the background in your info.plist as well.

- (void)applicationWillTerminate:(UIApplication *)application
{
    // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
    // Schedule an alarm here to warn the user that they have terminated an application and if they want to re-activate it.

    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.soundName = @"sonar";
        alarm.alertBody =@"Background uploads are disabled. Tap here to re-activate uploads." ;

        [app scheduleLocalNotification:alarm];
    }

}

Solution 3

I was having the same issue as yourself. However, I discovered if I didn't set a fireDate it started to work.

- (void)applicationWillTerminate:(UIApplication *)application
{
//Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:

#if __IPHONE_OS_VERSION_MAX_ALLOWED > __IPHONE_6_1
    if(floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_6_1){
        //Annoy The User - Set a badge
        [application setApplicationIconBadgeNumber:1];

        //Try and alert the user
        UILocalNotification *notification = [[UILocalNotification alloc] init];
        notification.alertBody = @"Tracking disabled. Tap to resume.";
        notification.soundName = UILocalNotificationDefaultSoundName;
        [application scheduleLocalNotification:notification];
    }
#endif
}

I must warn you though, it doesn't work on an empty application. It does work on my application which has plenty of views in memory, therefore it must be related to the amount of time it takes to dealloc its memory.

W

Solution 4

I was able to schedule local notification in the appWillTerminate, using below code:

    let localNotification = UILocalNotification.init()
    localNotification.fireDate = Date.init(timeIntervalSince1970: Date().timeIntervalSince1970 + 1.5)
    localNotification.timeZone = TimeZone.current
    localNotification.repeatInterval = NSCalendar.Unit(rawValue: 0)
    localNotification.alertBody = "Did terminate app"
    localNotification.soundName = "sonar"
    UIApplication.shared.scheduleLocalNotification(localNotification)
    // block main thread
    DispatchQueue.global().async {
        sleep(1)
        DispatchQueue.main.sync {
            CFRunLoopStop(CFRunLoopGetCurrent())
        }
    }
    CFRunLoopRun()
Share:
14,799
Swati
Author by

Swati

I have an experience of more than 8 years into mobile app development with building products from scratch to finish. I have been working in agile and scrum development. Involved in App architecture design, database structuring and product design. My primary languages of interest have been Objective-C and Swift 5. I have also worked extensively on PHP, MySQL, App Analytics, Git.

Updated on June 15, 2022

Comments

  • Swati
    Swati about 2 years

    I am working on an application which will not work if terminated. It has some background tasks. I want to show a local notification if the app is terminated. There are applications which do this which means this is doable. But I am not able to find out a way.

    I have tried to set up a local notification in applicationWillTerminate: method of appdelegate as well as added a notification of app termination in my viewcontroller but none of the methods get called when app is actually terminated.

    - (void)applicationWillTerminate:(UIApplication *)application
    {
        NSLog(@"terminated");
        UIApplication * app = [UIApplication sharedApplication];
        NSDate *date = [[NSDate date] dateByAddingTimeInterval:15];
        UILocalNotification *alarm = [[UILocalNotification alloc] init] ;
        if (alarm) {
            alarm.fireDate = [NSDate date];
            alarm.timeZone = [NSTimeZone defaultTimeZone];
            alarm.repeatInterval = 0;
            alarm.alertBody = @"This app does not work if terminated";
            alarm.alertAction = @"Open";
            [app scheduleLocalNotification:alarm];
        }
    
        [app presentLocalNotificationNow:alarm];
        // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
    }
    

    Any help would be great.

    Thanks in Advance !!!

  • Swati
    Swati almost 11 years
    then how does other apps like sleep if u can do this?
  • rckoenes
    rckoenes almost 11 years
    Not sure, I just know that when the system kills an app the is not informed about it and the process is just stopped and the memory is cleared out.
  • Swati
    Swati almost 11 years
    what is the use of applicationWillTerminate then?
  • Swati
    Swati almost 11 years
    Suspended apps are not notified of termination but if your app is currently running in the background state (and not suspended), the system calls the applicationWillTerminate: method of your app delegate. Does this mean that If I user exits the application from quicklaunch tray and I have written this in my application. bti = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{}]; ApplicationwillTerminate method will be called?
  • rckoenes
    rckoenes almost 11 years
    If could, it is a least what I understand from the documentation. But it could also mean that your app needs background running support state like audio, voip, location tacking or accessory.
  • Swati
    Swati almost 11 years
    Thanks @rckoenes. I have acheived this.. :)
  • Swati
    Swati almost 11 years
    I want to know how the volume can also be handled for device not in the app. This app "Sleep if you can" increases volume even if the volume is decreased by user.
  • Amit
    Amit over 9 years
    Hi, I have a similar app where i m working with BLE. But applicationWillTerminate method never gets called. Any advice?
  • John Ballinger
    John Ballinger over 9 years
    How are you testing that applicationWillTerminate is being called? How are you quiting the app?
  • imcc
    imcc over 8 years
    is correct. You can simply add sleep(2) in applicationWillTerminate:
  • viral
    viral over 7 years
    Worked for me. Thank You.
  • Mahesh Narla
    Mahesh Narla about 7 years
    How does this worked for you? will you please explain , I wrote the same but i didn't received notification after terminating app.
  • Mahesh Narla
    Mahesh Narla about 7 years
    @iOSAppDev will you please explain how does this app will terminate method called.
  • viral
    viral about 7 years
    @MaheshNarla Same way that's mentioned in answer. The only difference was that I added '1' second time interval instead of '10' in the answer.