Проблема с получением текущего местоположения

Я хочу получить текущее местоположение устройства. Код нормально работает. Это дает местоположение, если пользователь не изменил статус авторизации приложения для службы определения местоположения. Я также могу проверить, отказал ли пользователь в разрешении на службу определения местоположения.

Проблема возникает, когда пользователь отменяет авторизацию приложения для использования службы определения местоположения, а затем снова авторизует. В этом случае, после этого, если я попытаюсь получить местоположение, он выдает nil, хотя он вызывал

- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status

метод делегата со статусом 3, т.е. kCLAuthorizationStatusAuthorized.

Код для получения текущего местоположения:

CLLocation * location = self.locationManager.location;

Метод получения:

- (CLLocationManager *)locationManager
{
    if (!locationManager)
    {
        locationManager = [[CLLocationManager alloc] init];
        locationManager.delegate = self;
    }

    return locationManager;
}

Метод делегата CLLocationManager:

- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status
{
    DLog(@"Location authorization changed : %d", status);

    // If user has denied permission for location service
    if (status == kCLAuthorizationStatusDenied)
    {
        DLog(@"Location service denied.");

        // If authorization status changed method is already called, then SDK will not call again on same object.
        // Thus, set CLLocationManager object to nil so that next time we try to get location, it will create a new object,
        // and that will send message about authorization status changed.
        self.locationManager.delegate = nil;
        self.locationManager = nil;
    }
    else if (status == kCLAuthorizationStatusNotDetermined)
    {
        // If authorization status changed method is already called, then SDK will not call again on same object.
        // Thus, set CLLocationManager object to nil so that next time we try to get location, it will create a new object,
        // and that will send message about authorization status changed.
        self.locationManager.delegate = nil;
        self.locationManager = nil;
    }
    else if (status == kCLAuthorizationStatusAuthorized)
    {

    }
}

Любая идея об этом?


person Geek    schedule 01.04.2014    source источник
comment
в приведенном выше примере вы устанавливаете для locationManager.delegate значение nil, если авторизация отменяется... вы когда-нибудь устанавливали его снова для соответствующего класса?   -  person Volker    schedule 01.04.2014
comment
только что заметил, что вы также установили для locationManager значение nil...   -  person Volker    schedule 01.04.2014
comment
Основываясь на ваших комментариях в коде, вы где-то воссоздаете объект locationManager - вы уверены, что это срабатывает, когда вы устанавливаете self.locationServiceDisabled = false ?   -  person Paulw11    schedule 01.04.2014
comment
@Volker Я снова установил метод получения. Добавлен рассматриваемый метод получения.   -  person Geek    schedule 01.04.2014
comment
Я не вижу, чтобы вы когда-либо начинали обновлять свое местоположение ( cllocationmanager startupdatinglocation )   -  person Nils Ziehn    schedule 01.04.2014
comment
@Paulw11 Флаг self.locationServiceDisabled больше не используется. Я обновил свой код, о котором идет речь.   -  person Geek    schedule 01.04.2014
comment
@NilsZiehn Это не вызов этого метода делегата. И это должно указывать местоположение на CLLocation * location = self.locationManager.location; строке.   -  person Geek    schedule 01.04.2014
comment
В документах Apple говорится о свойстве местоположения менеджера местоположения: значение этого свойства равно нулю, если данные о местоположении никогда не были получены. По этой причине вам нужно как-то обновить местоположение вашего iPhone! Чтобы это произошло, вы должны вызвать метод startupdatinglocation... менеджера местоположения!   -  person Nils Ziehn    schedule 01.04.2014
comment
@NilsZiehn Да, это было причиной. Вы можете опубликовать это как ответ.   -  person Geek    schedule 01.04.2014


Ответы (2)


self.locationManager.location это nil, так как вы так и не начали обновлять местоположение.

В документах Apple говорится о свойстве location для locationManager:

Значение этого свойства равно нулю, если данные о местоположении никогда не были получены.

По этой причине вам нужно как-то обновить местоположение вашего iPhone!

Apple Docs CLLocationManager

Обычно это означает, что вы хотите позвонить

[self.locationManager startUpdatingLocation]

но вы также можете использовать

[self.locationManager startMonitoringSignificantLocationChanges]

person Nils Ziehn    schedule 01.04.2014
comment
Я бы хотел, чтобы вы добавили сюда весь текст вашего комментария. Это сделало бы этот ответ намного лучше. Спасибо. - person Geek; 02.04.2014

Если вы установите для делегата значение nil, вы не будете получать обновления об изменениях статуса авторизации, не так ли?

self.locationManager.delegate = nil;

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

- (void)startUpdatingLocation
person Morpheus78    schedule 01.04.2014
comment
Если вы хотите внимательно посмотреть мой код, то ясно, что в методе получения я снова устанавливаю делегата. - person Geek; 02.04.2014