【问题标题】:CLLocationManager troubleshooting in iOS 8iOS 8 中的 CLLocationManager 故障排除
【发布时间】:2014-11-09 21:46:03
【问题描述】:

根据新的更改,我确实更新了CLLocationManager 的代码,并添加了NSLocationAlwaysUsageDescriptionNSLocationWhenInUseUsageDescription 键。

manager = [[CLLocationManager alloc] init];
manager.delegate = self;
manager.distanceFilter = kCLDistanceFilterNone;
manager.desiredAccuracy = kCLLocationAccuracyBest;
NSLog(@"%d",[CLLocationManager authorizationStatus]); // always output 0
// check if iOS 8
if ([manager respondsToSelector:@selector(requestAlwaysAuthorization)]) {
    [manager requestAlwaysAuthorization];
}
[manager startUpdatingLocation];

问题:该应用程序不再请求任何位置管理,即我在设置 -> 隐私 -> 位置服务下找不到它,locationManager:(CLLocationManager *)aManager didUpdateLocations:(NSArray *)locations 仍然没有被触发。我有什么遗漏吗?

编辑:[CLLocationManager authorizationStatus]0kCLAuthorizationStatusNotDetermined,因此我认为问题出在[manager requestAlwaysAuthorization] 以供参考这是我本地化的InfoPlist.strings(可能是它导致问题):

<key>NSLocationAlwaysUsageDescription</key>
<string>Text</string>

<key>NSLocationWhenInUseUsageDescription</key>
<string>Text</string>

调用[manager requestAlwaysAuthorization]被执行,locationManager:didFailWithError:被执行但未被触发。

尝试使用不同的 Plist,但仍然没有成功:

<key>NSLocationWhenInUseUsageDescription</key>
<string>Text</string>

<key>NSLocationUsageDescription</key>
<string>Text</string>

还有一点需要注意:我的 Plist 是本地化的,这会是个问题吗?

【问题讨论】:

  • 似乎应该可以。这是在设备还是模拟器上?模拟器在 xcode 6.1 中存在位置管理器问题。擦拭模拟器有时会有所帮助。另外,我认为这并不重要,但我认为您只需要两个 plist 键之一,而不是两者。
  • 实现locationManager:didFailWithError: 方法。叫吗?
  • @rmaddy 试过了,没有调用。
  • @EricS nop,设备。关于按键,刚试了1个,不行。
  • CoreLocation.framework 是否与应用关联?我想我曾经在未链接 CoreLocation 时看到过这个问题,这让我感到惊讶,因为我预计会出现链接错误而不是运行时错误。此外,检查 CLLocationManager 对象是否为 nil - 这可能有助于缩小范围。

标签: ios objective-c ios8 cllocationmanager


【解决方案1】:

您说您根本没有看到请求授权的警报,确认委托方法 didChangeAuthorizationStatus 没有触发,然后您转到设置应用程序 -> 隐私 -> 位置服务,并且该程序未在此处列出并且未列出拒绝定位服务。因此,这听起来像是一个 plist 问题。

就 info.plist 而言,我是在 Xcode 中完成的(对我来说,没有语言本地化会更简单一些)转到 info 选项卡并输入“NSLocationWhenInUseUsageDescription”(您还想添加“NSLocationAlwaysUsageDescription”)并输入说明。如果您看到弹出窗口(这是异步的),它正在工作。如果它找不到您为什么需要定位服务的描述,它不会向用户显示警报(必须显示您的描述),这当然意味着您不会获得授权。

来自 infoplist.strings https://developer.apple.com/library/ios/documentation/General/Reference/InfoPlistKeyReference/InfoPlistKeyReference.pdf 上的苹果文档:

“在 Info.plist 文件中查找键值的例程会考虑用户的语言偏好,并在存在时返回键的本地化版本(来自相应的 InfoPlist.strings 文件)。如果本地化版本的键不存在,例程返回 Info.plist 文件中存储的值。"

因此必须将这些键添加到 info.plist(可以在项目的 xcode 信息选项卡中完成),并且只有当它找到另一种语言的文件时,它才会尝试使用您的本地化值。

我将进入项目,选择目标,然后在构建设置旁边的信息选项卡中,确保您看到 plist 键 NSLocationAlwaysUsageDescription 已添加和描述。添加 plist 键时,我没有从下拉菜单中找到选择,并且有一个选项,隐私 - 位置使用说明,对我有用。只需复制“NSLocationAlwaysUsageDescription”这个词并添加描述。您也可以在使用时进行。它必须在那里才能工作。它需要在查找本地 plist 键之前找到全局。对于调试,您可以从本地化 plist 中删除键以启动并验证它是否与全局 plist 值一起使用。或者更确切地说:“从 plist 中删除本地化常量并且只有全局常量”没有理由只有全局 plist 值它不应该工作。如果您有多种翻译的语言需求,您只需要稍后添加本地化值,一旦您确认全局作品。顺序应该是让全局仅作为最佳实践首先工作,因为通过检查该步骤,您就知道第一部分是否正常工作。您不需要翻译主要 plist 描述的新项目可以添加而不是本地化。

如果您想要第二语言,请注意https://developer.apple.com/library/ios/documentation/General/Reference/InfoPlistKeyReference/Articles/AboutInformationPropertyListFiles.html 中的此示例。

info.plist的格式为:

<key>CFBundleDisplayName</key>
<string>TextEdit</string>

但如果你有一个法语 infoPlist.strings 格式是:

CFBundleDisplayName = "TextEdit";

【讨论】:

  • 您是否看到要求您批准定位服务的弹出窗口?如果你这样做并且你点击是,那么它就会被调用,如果你没有看到带有自定义 plist 字符串的弹出窗口,那么你有一个 plist 问题
  • 为了清楚起见,您是在设备还是模拟器上运行。如果在模拟器中,我不确定您是否可以在那里进行良好的测试。
  • 我知道使用模拟器还有另一个答案。我遇到了相反的问题,它让我在使用正确的 plist 字符串描述之前更改了位置
  • 我会接受这个答案。当您将添加“从 plist 中删除本地化常量并仅使用全局常量”的部分作为我的问题的主要解决方案时,我也会给予它赏金,因为正是它使它起作用。
  • 我补充说,最后作为总结,我删除了与 plist 或本地化无关的部分,例如谈论代表或允许的消息长度(似乎是对消息长度没有严格限制),只关注问题所在。
【解决方案2】:

如果您在模拟器上运行,有时模拟器无法获取自定义位置。要解决这个问题,首先选择Debug -> Location -> Apple,然后选择Debug -> Location -> Custom Location。它会帮助你。

【讨论】:

    【解决方案3】:

    也许你的 plist 不同,这是我在我的应用中使用的并且工作正常,我们使用的是 WhenInUse 选项:

    列表:

    <key>NSLocationWhenInUseUsageDescription</key>
    <string>Use location services only when the app is in use</string>
    

    位置管理器初始化:

    self.locationManager = [[CLLocationManager alloc] init];
    [self.locationManager setDelegate:self];
    
    if ([self.locationManager respondsToSelector:@selector(requestWhenInUseAuthorization)]) {
      [self.locationManager requestWhenInUseAuthorization];
    }
    

    位置管理器委托方法:

    - (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
    
      self.coordinate = newLocation.coordinate;
    }
    
    - (void)locationManager:(CLLocationManager *)manager
           didFailWithError:(NSError *)error {
    
      NSLog(@"%@", error.description);
    }
    
    - (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status {
    
        if ([self.locationManager respondsToSelector:@selector(requestWhenInUseAuthorization)]) {
          if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusAuthorizedWhenInUse) {
            [self startUpdatingLocation];
            [self startMonitoringSignificantLocationChanges];
          } else {
            [self setDefaultCoordinate];
          }
        } else {
          if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusAuthorized) {
            [self startUpdatingLocation];
            [self startMonitoringSignificantLocationChanges];
          } else {
            [self setDefaultCoordinate];
          }
        }
    }
    

    只要调用[self.locationManager requestWhenInUseAuthorization];,我就会收到授权警报,它可以在设备和模拟器中使用。

    另外,你说你的 plist 是本地化的,你有所有的本地化键吗?

    【讨论】:

    • 是的,你在问题中看到的plist在每个本地化字符串文件中都是一样的。
    【解决方案4】:

    您是否保持对CLLocationManager 对象的强引用?根据Apple doc,请求许可时是强制性的: https://developer.apple.com/Library/mac/documentation/CoreLocation/Reference/CLLocationManager_Class/index.html#//apple_ref/doc/uid/TP40007125-CH3-SW72

    【讨论】:

      猜你喜欢
      • 2014-11-10
      • 1970-01-01
      • 2013-07-15
      • 2010-11-30
      • 2021-09-11
      • 2012-02-18
      • 2011-03-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多