문제

EDIT: Ok, I just have noticed that the problem is exclusive of iOS 7. I'm still being unable to solve it, however, so I suppouse I'll try with the sugestions bellow. Thanks to all!

¡Hi! I'm programming a navigator app, and I need to update the user position whenever is possible. I have two View Controllers that use CLLocation manager. In both of them I've added this line:

#import <CoreLocation/CoreLocation.h>

And then added the to the interface declaration, and I'm setting this as a property in the .h file, and synthetizing afterwards:

@property (strong, nonatomic) CLLocationManager *locationManager;

After that, I'm launching de locationManager in the viewDidLoad, this way:

if(self){
    locationManager = [[CLLocationManager alloc] init];
    //locationManager.delegate = self;
    [locationManager setDelegate:self];
    [locationManager setDistanceFilter:kCLHeadingFilterNone];
    [locationManager setDesiredAccuracy:kCLLocationAccuracyBestForNavigation];
    [locationManager startUpdatingLocation];
}

And here are my delegate methods.

For the first View:

#pragma mark - CLLocationManagerDelegate

- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
    NSLog(@"didFailWithError: %@", error);
    UIAlertView *errorAlert = [[UIAlertView alloc]
                           initWithTitle:@"Error" message:@"Failed to Get Your Location" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
    [errorAlert show];
}

- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
    NSLog(@"didUpdateToLocation: %@", newLocation);
    CLLocation *currentLocation = newLocation;

    if (currentLocation != nil) {
        homeLatitude = [[NSString stringWithFormat:@"%.8f",  currentLocation.coordinate.latitude] doubleValue];
        homeLongitude = [[NSString stringWithFormat:@"%.8f", currentLocation.coordinate.longitude] doubleValue];
        NSLog(@"Updated! -> hl = %f, hlg = %f", homeLatitude, homeLongitude);
    }
}

For the second view. As you can see, I replaced the old didUpdateToLocation with didUpdateLocations, as a desperate try.

#pragma mark - CLLocationManagerDelegate

- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
    NSLog(@"didFailWithError: %@", error);
    UIAlertView *errorAlert = [[UIAlertView alloc]
                           initWithTitle:@"Error" message:@"Failed to Get Your Location"       delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
    [errorAlert show];
}

/*- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation   *)newLocation fromLocation:(CLLocation *)oldLocation
{
    NSLog(@"didUpdateToLocation: %@", newLocation);
    CLLocation *currentLocation = newLocation;

    if (currentLocation != nil) {
        NSLog(@"Tarzan boy");
        _testLabel.text = [NSString stringWithFormat:@"Oh DAMN!!!!"];
    }
}*/

-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations {
    NSLog(@"didUpdateToLocation: %@", [locations lastObject]);
    CLLocation *currentLocation = [locations lastObject];
    if (currentLocation != nil) {
        currentLatitude = [[NSString stringWithFormat:@"%.8f", currentLocation.coordinate.latitude] doubleValue];
        currentLongitude = [[NSString stringWithFormat:@"%.8f", currentLocation.coordinate.longitude] doubleValue];
        NSLog(@"Updated! (MapWithRoutesViewController) -> hl = %f, hlg = %f", currentLatitude, currentLongitude);
        _testLabel.text = [NSString stringWithFormat:@"Update! -> hl = %f, hlg = %f", currentLatitude, currentLongitude];

        //Aquí es donde borramos el lugar al que llegaron.
        if(mapView){
            if(followMe){
                CLLocationCoordinate2D *c = &((CLLocationCoordinate2D){.latitude = currentLatitude, .longitude = currentLongitude});
                [mapView.mapView as_setCenterCoordinate:*c zoomLevel:32 animated:NO];
                _ourStepper.value = [mapView.mapView as_zoomLevel];
            }

        if([mapView getNearestDestinyDistance:currentLocation] < 150.0){
            NSLog(@"Hay que eliminar el primer destino del MapView");
            mapView.destinoActual++;
        }

        if([mapView getNearestPointDistance:currentLocation] > 200.0){
            NSLog(@"Hay que recalcular la ruta al destinoActual");
            SpinnerView *spinner = [SpinnerView loadSpinnerIntoView:self.view];
            spinner.tag = 98;
            while (![mapView recalculateRoutesTo:currentLocation]) {
                //do nothin...
            }
            [spinner removeSpinner];

        }
    }
}
//[locationManager stopUpdatingLocation];
}

As you can see, the line

//[locationManager stopUpdatingLocation];

is commented. Well, the problem is driving me crazy is that the code above works as a charm in the first view controller, and update periodically as I expected. But in the second view, it works only the first time, and never updates again. I programmed these methods in different times, so I can't remember if I did something to the first view I didn't to the second. But they are in the same app, so I assume there's no problem with libraries or permissions. Any help or hint is welcome, thanks!

도움이 되었습니까?

해결책 3

Found the solution here. The locationManager works when I launch it this way:

if(self){
     locationManager = [[CLLocationManager alloc] init];
     [locationManager setDelegate:self];
     [locationManager setDistanceFilter:kCLHeadingFilterNone];
     //change the desired accuracy to kCLLocationAccuracyBest
     [locationManager setDesiredAccuracy:kCLLocationAccuracyBest];
     //SOLUTION: set setPausesLocationUpdatesAutomatically to NO
     [locationManager setPausesLocationUpdatesAutomatically:NO];
     [locationManager startUpdatingLocation];
}

I'll work anyway in performance like Rob suggested. Thanks to all for the help!

다른 팁

First off, if you are doing navigation, you should be registering for significant change notifications. Go read the documentation on that here. It's much more efficient. You will have to turn it off when you are not using it, but it's much better. Support for it goes all the way back to iOS 4. That's 99% of the user population for sure.

I had a similar situation in my application and implemented a singleton that handles all location updates and then fires off NSNotificaitons to the foreground threads.

  • Create a singleton class that handles the location updates View would
  • register to listen to LOCATION_CHANGE updates perhaps Background
  • singleton object registers as the delegate for the location manager

This may not be the answer you are looking for but i know it worked in my case.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top