How to get accurate location update when application is killed?

别来无恙 提交于 2019-12-25 03:42:24

问题


I'm developing a location based application where user can stored number of locations and when user passed near by that stored location, application will notify user by local notification.

I've used following code to achieve this feature:


-(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
   if([[UIApplication sharedApplication] backgroundRefreshStatus] == UIBackgroundRefreshStatusDenied){

         [self showAlertWithTitle:@"" andMessage:@"The app doesn't work without the Background App Refresh enabled. To turn it on, go to Settings > General > Background App Refresh."];
  }else if([[UIApplication sharedApplication] backgroundRefreshStatus] == UIBackgroundRefreshStatusRestricted){

    [self showAlertWithTitle:@"" andMessage:@"The functions of this app are limited because the Background App Refresh is disable."];
  } else {
    if ([launchOptions objectForKey:UIApplicationLaunchOptionsLocationKey]) {

        // This "afterResume" flag is just to show that he receiving location updates
        self.shareModel.afterResume = YES;

        self.shareModel.anotherLocationManager = [[CLLocationManager alloc]init];
        self.shareModel.anotherLocationManager.delegate = self;
        self.shareModel.anotherLocationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters; //kCLLocationAccuracyBestForNavigation
        self.shareModel.anotherLocationManager.activityType = CLActivityTypeOtherNavigation;
        [self.shareModel.anotherLocationManager startUpdatingLocation];
                 self.shareModel.anotherLocationManager.pausesLocationUpdatesAutomatically = YES;


        if(IS_OS_8_OR_LATER) {
            if ([self.shareModel.anotherLocationManager respondsToSelector:@selector(requestWhenInUseAuthorization)]) {
                [self.shareModel.anotherLocationManager requestWhenInUseAuthorization];
            }
            [self.shareModel.anotherLocationManager requestAlwaysAuthorization];
        }

        [self.shareModel.anotherLocationManager startMonitoringSignificantLocationChanges];
    }
  }
}

-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations {

CLLocation *currentLocation = [locations lastObject];

latitudeTemp = currentLocation.coordinate.latitude;
longitudeTemp = currentLocation.coordinate.longitude;

[self locationChangeLogic];    

//If the timer still valid, return it (Will not run the code below)
if (self.shareModel.timer)
    return;

self.shareModel.bgTask = [BackgroundTaskManager sharedBackgroundTaskManager];
[self.shareModel.bgTask beginNewBackgroundTask];

//Restart the locationMaanger after 30 Seconds
self.shareModel.timer = [NSTimer scheduledTimerWithTimeInterval:30
                                                         target:self
                                                       selector:@selector (restartLocationUpdates)
                                                       userInfo:nil
                                                        repeats:YES];

//Will only stop the locationManager after 10 seconds, so that we can get some accurate locations
//The location manager will only operate for 10 seconds to save battery
NSTimer * delay10Seconds;
delay10Seconds = [NSTimer scheduledTimerWithTimeInterval:10
                                                  target:self
                                                selector:@selector(stopLocationDelayBy10Seconds)
                                                userInfo:nil
                                                 repeats:YES];
}

- (void)applicationDidEnterBackground:(UIApplication *)application {
      [self.shareModel.anotherLocationManager startMonitoringSignificantLocationChanges];
}

- (void)applicationDidBecomeActive:(UIApplication *)application {
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.


//Remove the "afterResume" Flag after the app is active again.
self.shareModel.afterResume = NO;

if(self.shareModel.anotherLocationManager)
    [self.shareModel.anotherLocationManager stopMonitoringSignificantLocationChanges];

self.shareModel.anotherLocationManager = [[CLLocationManager alloc]init];
self.shareModel.anotherLocationManager.delegate = self;
self.shareModel.anotherLocationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters; //kCLLocationAccuracyBestForNavigation;
self.shareModel.anotherLocationManager.activityType = CLActivityTypeOtherNavigation;
[self.shareModel.anotherLocationManager startUpdatingLocation];

if(IS_OS_8_OR_LATER) {
    if ([self.shareModel.anotherLocationManager respondsToSelector:@selector(requestWhenInUseAuthorization)]) {
        [self.shareModel.anotherLocationManager requestWhenInUseAuthorization];
    }
    [self.shareModel.anotherLocationManager requestAlwaysAuthorization];
}
[self.shareModel.anotherLocationManager startMonitoringSignificantLocationChanges];
}

By using above code, i'm able to get location even application killed by User but not as accurate as it should be. Sometime i didn't get location and sometime i get location after passing that stored location. I need to show location notification exactly when user enter in that specific radius.

Please help me for solving this issue.

Thanks in advance.


回答1:


Region Monitoring (Geofencing) serve my requirement.

You can use few following link for more information:

  1. https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/LocationAwarenessPG/RegionMonitoring/RegionMonitoring.html

  2. http://www.rapidvaluesolutions.com/tech_blog/geofencing-using-core-location-for-regional-monitoring-in-ios-applications/

Thanks all..



来源:https://stackoverflow.com/questions/29248637/how-to-get-accurate-location-update-when-application-is-killed

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!