3

I am creating app that needs to wake up in background at particular time .

I have tried :

  1. UILocalNotification : But i Don't want to use UILocalNotification because it needs user interaction to tap on notification and than only app will wake up and start location manager.

  2. I have also used [locationManager startUpdatingLocation]; enabled with background Modes Location updates, this is works but it will take lot of battery.

So with using new iOS 7 feature Silent pushNotification and didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler: method i need to start location manager in background,

-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler{

    NSLog(@"Receive RemoteNotification in fetchCompletionHandler with UserInfo:%@",userInfo);
    application.applicationIconBadgeNumber=0;
    __block UIBackgroundTaskIdentifier bgTask = [application beginBackgroundTaskWithExpirationHandler:^{

        [self.locationManager startUpdatingLocation];

        [application endBackgroundTask:bgTask];
        bgTask = UIBackgroundTaskInvalid;
    }];

}

Silent Push notification is working correctly ,

Payload for PushNotification:

{"aps" : {"content-available" : 1},"SilentPushId" : "07"}

But this will not start location manager , Please somebody help me.

EDIT:

If it is not possible please give me some suggestions.

4 Answers4

4

I have successfully implement this Using Silent Pushnotification & it Call startUpdatingLocation and I am able to get location data in delegate method :

Using This Payload:

{
    "aps": {
        "content-available": 1
    },
    "SilentPush": "4"
}

I have enabled location & remote notification for Background mode: enter image description here

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult result))handler
{
     __block UIBackgroundTaskIdentifier bgTask =0;
    UIApplication  *app = [UIApplication sharedApplication];
     bgTask = [app beginBackgroundTaskWithExpirationHandler:^{
        [self.locationManager startUpdatingLocation];

 }];

didUpdateLocations

- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
        lastLoc=[locations lastObject];
        [logFile addLocObject:[NSString stringWithFormat:@"Loc: %@",lastLoc]];
}
Maxim Korobov
  • 2,574
  • 1
  • 26
  • 44
1

You cannot. It is explicitly not permitted to start location services while the application is in the background. The user has to be aware of the start with the app open.

Imagine what subversive tracking would be available if you could send silent notifications to trigger a location update back to a server without the user knowing about it...

Wain
  • 118,658
  • 15
  • 128
  • 151
  • But 1st time User has open app it will take permission for `notification` & `Location` both. so what is problem with it? –  Feb 06 '14 at 12:23
  • :but i have seen many places where location manager is strating using background tasks. –  Feb 06 '14 at 12:27
  • I can't find the documentation just now but I'm pretty sure it is not permitted. You need to get the user to open the app. But, why do you want to do this anyway? – Wain Feb 06 '14 at 12:35
  • Wain Thnks for your responce : AS you say & i have read there is not any thing regarding to `startUpdatingLocation` in background in [Apple Docs](https://developer.apple.com/library/mac/documentation/CoreLocation/Reference/CLLocationManager_Class/CLLocationManager/CLLocationManager.html#//apple_ref/doc/uid/TP40007125-CH3-SW2) , it may be we can start it. –  Feb 06 '14 at 13:41
  • In searching i came to this thread http://stackoverflow.com/a/18962839/1597744 , Using it can i achieve my goal? –  Feb 06 '14 at 13:42
  • I have successfully starting locationManager through push in background, but got new issue [Check this](http://stackoverflow.com/questions/21626286/app-killed-by-os-in-ios7-after-some-seconds) –  Feb 07 '14 at 11:21
1

What you can do, in background, is receive significantLocation events and boundary events. I can imagine leveraging that capability to keep a recent locations log of sorts. When your remote notification is received, respond by sending last known location. With a bit of experimentation I am sure you could refine this to be reasonably accurate with little impact on the battery.

Dean Davids
  • 4,174
  • 2
  • 30
  • 44
  • I have successfully starting locationManager through push in background, but got new issue [Check this](http://stackoverflow.com/questions/21626286/app-killed-by-os-in-ios7-after-some-seconds) –  Feb 07 '14 at 11:20
0

If you want to update location in background mode, you just enable UIBackgroundModes in plist file. See startUpdatingLocation description in apple's doc..

If you start this service and your application is suspended, the system stops the delivery of events until your application starts running again (either in the foreground or background). If your application is terminated, the delivery of new location events stops altogether. Therefore, if your application needs to receive location events while in the background, it must include the UIBackgroundModes key (with the location value) in its Info.plist file.

You can enable this for background updation in your xcode5+ as like below..

enter image description here

Mani
  • 17,549
  • 13
  • 79
  • 100
  • imani: i have enabled both `Location updates & remote Notification` & in in your case are you call 'startUpdates' method in background ? –  Feb 06 '14 at 13:39
  • Apple will only allow this under certain circumstances. Very likely not here. – Dean Davids Feb 06 '14 at 16:21