Почему делегат CLLocationManager не вызывается в iPhone SDK 4.0? - PullRequest
12 голосов
/ 17 июня 2010

Это код, который я имею в своем классе AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {    

    CLLocationManager *locationManager = [[CLLocationManager alloc] init];
    locationManager.delegate = self;
    locationManager.distanceFilter = 1000;  // 1 Km
    locationManager.desiredAccuracy = kCLLocationAccuracyKilometer;
    [locationManager startUpdatingLocation];
}

И это метод делегата, который я имею в своем классе AppDelegate

    //This is the delegate method for CoreLocation
- (void)locationManager:(CLLocationManager *)manager
    didUpdateToLocation:(CLLocation *)newLocation
           fromLocation:(CLLocation *)oldLocation
{

        //printf("AppDelegate latitude %+.6f, longitude %+.6f\n", newLocation.coordinate.latitude, newLocation.coordinate.longitude);

}

Он работает в 3.0, 3.1, 3.1.3, но не работает в симуляторе 4.0 и на устройстве одновременно.

В чем причина?

Ответы [ 5 ]

21 голосов
/ 23 мая 2012

У меня была похожая ошибка, и теперь она решена. Проблема заключается в локальном объявлении переменной locationManager. Вместо этого объявите его как переменную класса и убедитесь, что он сохраняется либо напрямую, либо через свойство retain (или в строгом, если вы используете ARC). Это решает проблему! Проблема была в том, что переменная de locationManager была освобождена и никогда не обновляла делегата. Вот код:

.h файл:

#import <UIKit/UIKit.h>
#import <MapKit/MapKit.h>
#import <CoreLocation/CoreLocation.h>


@interface MapViewController : UIViewController <MKMapViewDelegate, CLLocationManagerDelegate> {
@private
    MKMapView *_mapView;
    CLLocationManager *_locationManager;
}

@property(nonatomic, strong) CLLocationManager *locationManager;

@end

.m файл:

self.locationManager = [[CLLocationManager alloc] init];
_locationManager.delegate = self;
_locationManager.desiredAccuracy = kCLLocationAccuracyBest;
[_locationManager startUpdatingLocation];

Надеюсь, это поможет.

2 голосов
/ 17 июня 2010

Получается ли когда-нибудь -locationManager:didFailWithError: в вашем делегате? Я просто думаю, может быть, вы в какой-то момент отказали в доступе к данным о местонахождении, и теперь вам не предлагается, но доступ запрещен.

1 голос
/ 11 марта 2019

Я сходил с ума, пытаясь понять, почему только один из нескольких классов, использующих CLLocationManager, никогда не сможет получить вызов любого методов CLLocationManagerDelegate.

Оказывается: этот класс был инициализирован из неосновного потока, поэтому его CLLocationManager был создан в неосновном потоке ... он мог даже быть временным потоком.В любом случае, завершение вызова для инициализации моего класса с помощью приведенного ниже кода - это все, что нужно для вызова методов моего делегата CLLocationManager.

dispatch_sync(dispatch_get_main_queue(), 
                    ^{
                         // create your class that will create a CLLocationManager here.
                     });

Итак, нижняя строка: не создавайте CLLocationManager ни на чем, кромеосновной поток, иначе вы никогда не вызовете свои методы делегата!Я когда-то знал это ... просто давно ... вздох.Потраченный впустую день, чтобы понять это снова!Поскольку все CLLocationManager SO, которые я читал, никогда не упоминали об этом, я публикую это здесь.Надеюсь, это кому-нибудь поможет!

0 голосов
/ 11 сентября 2013

Поместите коды в viewController, "который передается в navigationController".

Мой код.

В SomeViewController.h

#import <MapKit/MapKit.h>
@interface SomeViewController : UIViewController<CLLocationManagerDelegate>{
}
@property (nonatomic, strong) CLLocationManager *locationManager;
@end

В SomeViewController.m

#import "SomeViewController.h"

@implementation SomeViewController


-(void)findLocation{
    if ([CLLocationManager locationServicesEnabled]) {
        if (!self.locationManager) {
            self.locationManager = [[CLLocationManager alloc] init];
            self.locationManager.delegate = self;
            self.locationManager.distanceFilter = kCLDistanceFilterNone;
            self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
            [self.locationManager startUpdatingLocation];
        }
    }
}
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations{
    NSLog(@"didUpdateLocations");

    CLLocation *lo = [locations objectAtIndex:0];
    NSLog(@"latitude = %f, longitude = %f", lo.coordinate.latitude, lo.coordinate.longitude);

    [manager stopUpdatingHeading];
}
-(void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation{
    NSLog(@"didUpdateToLocation");}
-(void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error{
    NSLog(@"didFailWithError");
    [manager stopUpdatingLocation];
}

Проблема, я думаю, из-за ARC, locationManager выпущен.

0 голосов
/ 17 июня 2010

Вы уверены, что не освобождаете менеджера местоположений где-нибудь? Код, который у вас есть, показывает, что он размещается в методе didFinishLaunching ..., но затем о нем забывают (хотя он все еще сохраняется и должен работать).

Видите ли вы даже это начальное всплывающее окно, спрашивающее вас, можно ли узнать местоположение пользователя?

...