【问题标题】:didChangeAuthorizationStatus not called after changing status更改状态后未调用 didChangeAuthorizationStatus
【发布时间】:2015-01-15 00:38:51
【问题描述】:

我有一个问题,在用户 (1) 接受或 (2) 拒绝我使用位置服务的请求后,没有调用 locationManager:didChangeAuthorizationStatus。通过放置不同的NSLog 语句,我得出的结论是,当我请求授权时调用该方法,而不是在用户做出选择时调用。有没有人有同样的问题?如果有,你是怎么解决的?

这是我如何初始化我的location manager

if (_locationManager == nil) {
  NSLog(@"Creating location manager");
  _locationManager = [[CLLocationManager alloc] init];
  _locationManager.delegate = self;
  _locationManager.distanceFilter = kCLDistanceFilterNone;
  _locationManager.desiredAccuracy = kCLLocationAccuracyBest;
}

if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusNotDetermined) {
  NSLog(@"Not determined");
  if ([[NSUserDefaults standardUserDefaults] boolForKey:@"dynamicNotifOn"]) {
    [_locationManager requestAlwaysAuthorization];
  } else {
    [_locationManager requestWhenInUseAuthorization];
  }
} else if (...) {...

方法如下:

- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status {
  NSLog(@"Callback");
  if (status == kCLAuthorizationStatusAuthorizedAlways || status == kCLAuthorizationStatusAuthorizedWhenInUse) {
    NSLog(@"Authorized");
    [_mainButton setIsLoading:NO];
    [self startGettingLocation];
  } else if (status == kCLAuthorizationStatusDenied || status == kCLAuthorizationStatusRestricted) {
    NSLog(@"Denied");
    _currentState = CurrentStateError;
    [_mainButton setUpButtonForState:_currentState];
  }
}

在我按下初始化位置管理器(顶部代码块)的按钮后,控制台打印出如下内容:

Creating location manager
Not determined
Callback

然后我在弹出的 AlertView 中做出选择:

*nothing*

【问题讨论】:

    标签: ios objective-c cllocationmanager


    【解决方案1】:

    就我而言,问题出在非主线程中。 只需确保在主线程上创建位置管理器即可。

    【讨论】:

    • 这真的成功了!我只是尝试在主线程上请求权限,但创建 CLLocationManager 至少同样重要!
    【解决方案2】:

    上面的例子有几个奇怪的地方:

    1. 委托回调 locationManager:didChangeAuthorizationStatus: 以 NotDetermined 状态调用?!?文档中明确写了委托回调方法只有在授权状态发生变化时才会调用,但在上面的例子中没有。可能是一个错误。

    2. 在 Paulw11 的回答中指出,即使用户已经获得了应用程序的授权,我们也必须始终请求许可?!?在我看来,应用程序首先必须调用 CLLocationManager.authorizationStatus 并仅在授权未确定(即用户仍未授权我们的应用程序)时请求授权 - Apple 文档中也有说明。

    【讨论】:

      【解决方案3】:

      您不应该检查kCLAuthorizationStatusNotDetermined - 只需每次都请求授权 -

      if (self.locationManager == nil) {
        NSLog(@"Creating location manager");
        self.locationManager = [[CLLocationManager alloc] init];
        self.locationManager.delegate = self;
        self.locationManager.distanceFilter = kCLDistanceFilterNone;
        self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
      
        if ([[NSUserDefaults standardUserDefaults] boolForKey:@"dynamicNotifOn"]) {
           [self.locationManager requestAlwaysAuthorization];
        } else {
           [self.locationManager requestWhenInUseAuthorization];
        }
      }
      

      当我使用您的委托方法时,我得到以下输出 -

      2015-01-15 12:07:43.357 LocationAuthDemo[9942:500036] Callback
      2015-01-15 12:07:51.389 LocationAuthDemo[9942:500036] Callback
      2015-01-15 12:07:51.389 LocationAuthDemo[9942:500036] Authorized
      

      您从委托方法调用的任何方法是否会更新 UI 元素?如果是这样,您应该在主队列中调度它们。

      【讨论】:

      • 您好,感谢您的回复。我现在已经做出了改变,但我仍然在为同样的问题而苦苦挣扎。用户接受或拒绝我的请求后,该方法不会被调用。
      • 不,它们不会更新任何 UI 元素 - 它只是启动一个计时器并更新位置。我的打印语句也没有被调用。我会尝试将它分派到主队列,看看是否可行。
      • 如何声明locationManager 属性?有没有可能已经发布了?
      • 这里是我用来测试的示例代码-gist.github.com/paulw11/84b18044942e2ceea52a
      • 我在implementation (.m) 文件的@interface 部分声明它。我怀疑它已经发布了,我使用了strong and nonatomic。是的,我做了和你完全相同的事情——但是我的NSLog-statement 和其他方法没有在方法中调用。这对我来说完全是个谜
      猜你喜欢
      • 1970-01-01
      • 2021-01-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-29
      • 2021-06-15
      相关资源
      最近更新 更多