ios, startMonitoringSignificantLocationChanges - sometimes breaks monitoring

后端 未结 1 1292
别跟我提以往
别跟我提以往 2020-12-13 11:50

I have strange problem with updating user\'s location. Sometimes my app updates location but from time to time breaks updating. I do not know where is problem, my code (from

相关标签:
1条回答
  • 2020-12-13 12:12

    I can't say for sure if this is all of you problem but I would make the following changes:

    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
    {
       // Moved to didFinishLaunching... you should not be recreating every time app
       // becomes active. You can check for locations key in the options Dictionary if
       // it is necessary to alter your setup based on background launch
    
       // Start location services
       locationManager = [[CLLocationManager alloc] init];
       locationManager.desiredAccuracy = kCLLocationAccuracyBest;
    
       // Only report to location manager if the user has traveled 1000 meters
       locationManager.distanceFilter = 1000.0f;
       locationManager.delegate = self;
       locationManager.activityType = CLActivityTypeAutomotiveNavigation;
    
       // Start monitoring significant locations here as default, will switch to
       // update locations on enter foreground
       [locationManager startMonitoringSignificantLocationChanges];
    
       // Hold in property to maintain reference
       self.locationManager = locationManager;
     }
    

    Following your lead, this would be all that remains in your didBecomeActive method (I would use willEnterForeground instead):

    - (void)willEnterForeground:(UIApplication *)application
    {
       [self.locationManager stopMonitoringSignificantLocationChanges];
       [self.locationManager startUpdatingLocation];
    }
    

    Entering into background, go back to significant location changes only:

    - (void)applicationDidEnterBackground:(UIApplication *)application
    {
        NSLog(@"Went to Background");
        // Need to stop regular updates first
        [self.locationManager stopUpdatingLocation];
        // Only monitor significant changes
        [self.locationManager startMonitoringSignificantLocationChanges];
    }
    

    In your delegate method, I recommend taking out all the conditional background testing. I am wrapping in background task identifier in case the app is in the background or goes into the background before finish. I am also responding on global thread so we don't block UI (optional):

    - (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
    {
    
        UIApplication *app = [UIApplication sharedApplication];
        __block UIBackgroundTaskIdentifier locationUpdateTaskID = [app beginBackgroundTaskWithExpirationHandler:^{
            dispatch_async(dispatch_get_main_queue(), ^{
                if (locationUpdateTaskID != UIBackgroundTaskInvalid) {
                    [app endBackgroundTask:locationUpdateTaskID];
                    locationUpdateTaskID = UIBackgroundTaskInvalid;
                }
            });
        }];
    
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    
            // You might consider what to do here if you do not ever get a location accurate enough to pass the test.
           // Also consider comparing to previous report and verifying that it is indeed beyond your threshold distance and/or recency. You cannot count on the LM not to repeat.
           if ([[locations lastObject] horizontalAccuracy] < 100.0f) {
                [self sendDataToServer:[locations lastObject]];
           }
    
            // Close out task Identifier on main queue
            dispatch_async(dispatch_get_main_queue(), ^{
                if (locationUpdateTaskID != UIBackgroundTaskInvalid) {
                    [app endBackgroundTask:locationUpdateTaskID];
                    locationUpdateTaskID = UIBackgroundTaskInvalid;
                }
            });
        });
    }
    

    See my project, TTLocationHandler

    on Github for some more examples of using Core Location the way you wish to use it.

    0 讨论(0)
提交回复
热议问题