0

I am using beacons in my app (app set to background) and I am setting series of UILocalNotifications on beacon:DidExitRegion: (kind of alarm when beacon is lost).

Edit: When app is in the background, user exits region, then the notifications are set properly. When user wants to close the app while it's still being in background with the notifications set, I want to disable them all. /edit

The problem is, that I want to disable all those notifications in AppWillTerminate. According to documetation when app is in suspended state (waiting in background for getting signal from the beacon - CoreLocation), the appWillTerminate is not called. Users will often close the app while it is in background and alarms-notifications will not be removed.

What is the possible way to get rid of those notifications?

I've got 1 suggestion: perform "artificial" finite-length tasks in background (like here) and actually run the app after receiving beacon:didExitRegion: -> it doesn't get suspended, appWillTerminate will be called. It will, however work only for max 10 minutes and I don't think it's elegant thing to do.

Maybe other ways to do it? Thanks.

izik461
  • 1,131
  • 12
  • 32

3 Answers3

1
// Specify custom data for the notification
NSDictionary *infoDict = [NSDictionary dictionaryWithObject:@"someValue" forKey:@"someKey"];
localNotif.userInfo = infoDict;

You can give your notification a key to identify and can delete it by

UIApplication *app = [UIApplication sharedApplication];
NSArray *eventArray = [app scheduledLocalNotifications];
for (int i=0; i<[eventArray count]; i++)
{
UILocalNotification* oneEvent = [eventArray objectAtIndex:i];
NSDictionary *userInfoCurrent = oneEvent.userInfo;
NSString *key=[NSString stringWithFormat:@"%@",[userInfoCurrent valueForKey:@"someKey"]];
if ([uid isEqualToString:uidtodelete])
  {
    //Cancelling local notification
    [app cancelLocalNotification:oneEvent];
    break;
  }
}

From Apple docs:

For applications that do not support background execution or are linked against iOS 3.x or earlier, this method is always called when the user quits the application. For applications that support background execution, this method is generally not called when the user quits the application because the application simply moves to the background in that case. However, this method may be called in situations where the application is running in the background (not suspended) and the system needs to terminate it for some reason.

applicationWillTerminate when is it called and when not

If your app has background enabled use:

- (void)applicationDidEnterBackground:(UIApplication *)application

//Location manager delegate

 -(void)locationManager:(CLLocationManager *)manager didDetermineState:(CLRegionState)state forRegion:(CLRegion *)region
{
if (state == CLRegionStateInside)
{
    //Start Ranging
    [manager startRangingBeaconsInRegion:self.beaconRegion];
}
else
{
    //Stop Ranging here
}
}
Community
  • 1
  • 1
Mukesh
  • 3,680
  • 1
  • 15
  • 32
  • It's a way to disable specific notification. I am actually using it to delete notifications from specific beacon. Problem is, that I can't use it while closing the app, because appWillTerminate is not called. – izik461 May 18 '15 at 09:07
  • Methods you are writing about are to be launched when pressing home button while app is in the foreground. My app is in background (code not actually running, waiting for trigger from CoreLocation -> app gets suspended state) and suspended app will not call appWillTerminate on closing (double press home button and "swipe up the app"), in which I want to delete notifications. – izik461 May 18 '15 at 10:39
  • yes i got ,but if even the app is removed from the background, the beacon location manger delegate function still works.You can use those function and remove all the notification.I have edited the function.Check if this way works for you – Mukesh May 18 '15 at 13:58
  • I've edited my question. I think that we got misunderstood the situation at the beginning. Please. take a look now. – izik461 May 19 '15 at 08:42
0

If an app is terminated by the iOS (e.g. after you swipe up in the task switcher) then the next time you enter/exit a beacon region, the AppDelegate's didFinishLaunchingWithOptions method will be called before didEnterRegion or didExitRegion. You can therefore:

  1. Initialize a _launchTimetimestamp in didFinishLaunchingWithOptions.

  2. In didExitRegion check to see if the _launchTimestamp is less than a second or so in the past, and if so suppress notifications.

davidgyoung
  • 63,876
  • 14
  • 121
  • 204
  • I've edited my question. The situation is slightly different than what you did solve. didExitRegion is not to be called second time (notifications are set while exiting region for the 1st time), and the notifications are to be disabled while swiping up the app. – izik461 May 19 '15 at 08:41
  • Does didFinishLaunchingWithOptions get called before the notifications appear in this case? If so, you could use it to cancel them. – davidgyoung May 19 '15 at 11:37
0

You can't perform any action when the user swipes up your app in the task switcher. There are no callbacks, appWillTerminate or otherwise. This is by design.

You might be able to rework your delayed notifications so they are sent immediately by your app after a timed delay under programmatic control. That way, they are only sent if the app is still running when the timer goes off. The trick is that your app may be suspended for other reasons (user locks the phone, switches to another app) so you probably need a background task to do this. The limit in iOS 7+, by the way, is now 3 minutes not 10 minutes, so that is the longest you could delay notifications reliably.

davidgyoung
  • 63,876
  • 14
  • 121
  • 204
  • Yay, it's the answer I was most afraid of. So it's going to be like my suggestion at the end of my question. Just to keep it alive for certain amount of time by background task. Thanks for suggestion. – izik461 May 19 '15 at 12:56