首页 文章

locationManager didEnterRegion未在XCode 9 Simulator中调用

提问于
浏览
0

我有一个做地理围栏的应用程序 . 当我在模拟器(Xcode 8.3.3和Xcode 9)中运行它时,一切似乎都有效,但我的CLLocationManager didEnterRegion永远不会被调用 .

当我在iPhone上运行应用程序时,无论是在现实世界中(进入某个区域)还是在Xcode中通过位置模拟运行,它都被称为正常 .

知道为什么会这样吗?

我发现的一个区别是模拟器在使用时只支持监控位置,所以我必须设置好所以我的plist文件中有两个权限字符串,但除此之外我感到难过 .

由于我不提供代码(它太复杂并且在我的应用程序中分发),让我注意一下模拟器中的工作原理:

  • 在我的应用程序方案中,我选中了“允许位置模拟”,并且我已经为我正在监控的位置添加了几个.gpx文件 . 我有一个默认的位置设置 .

  • 我启动时正在调用我的位置管理器委托 . 我得到了 . 在模拟器中使用了授权者,然后在电话上使用了 .

当位置改变时,将调用

  • locationManager(:didUpdateLocations :) .

  • 当调用didUpdateLocations时,我会执行以下操作:

for r in manager.monitoredRegions { 
    if let cr = r as? CLCircularRegion {
        if cr.contains(location.coordinate) {
            log.debug("Am in the region!")
        } else {
            let crLoc = CLLocation(latitude: cr.center.latitude,
                                  longitude: cr.center.longitude)
            log.debug("distance is: \(location.distance(from: crLoc))")
        }
}

它的工作原理 . 所以我的地区受到监控,我的位置就是我认为应该的位置 .

  • 最后,我的locationManager委托的monitoringDidFailFor和didFailWithError未被调用 . 并非他们从来没有 - 他们在开发过程中,但现在不是 .

所以我很难过 . 再次,它在手机上工作正常,而不是在模拟器中 .

我究竟做错了什么?

3 回答

  • 7

    好的,我发现了问题 . 首先,Xcode 9 / iOS 11需要进行更改 . 我向Apple提交了一个错误并收到以下信息:

    在iOS11中,如果所有应用程序都支持Always授权,则它们必须支持WhenInUse授权 . 通过此更改,位置服务使用情况说明密钥已更改 . 对于要获得“始终提示”的应用程序,他们必须在其应用程序的Info.plist中同时具有NSLocationAlwaysAndWhenInUseUsageDescription和NSLocationWhenInUseUsageDescription .

    因此,如果您正在呼叫: locationManager.requestAlwaysAuthorization() ,对于iOS 11,您需要同时拥有 NSLocationAlwaysAndWhenInUseUsageDescriptionNSLocationWhenInUseUsageDescription . 如果你希望你的应用程序继续在iOS 11之前工作,你还需要保留 NSLocationAlwaysUsageDescription ,这样你就有3把钥匙 .

    我用Ray Wenderlich教程证实了这一点,Kuhncj的参考 . 它不适用于Xcode 9,但适用于Xcode 8 .

    我的问题是我的错误 . 虽然我有3个正确的密钥,但在审查我要求权限的位置时,我有以下内容:

    var permission : Permission = SimulatorPlatform.isSimulator ? .locationWhenInUse : .locationAlways

    所以我基本上为模拟器和设备运行不同的代码 . 更改后,我的应用程序确实被调用到达受监控区域 .

  • 0

    模拟器确实支持区域监控,我认为你的第二点是问题 . 尝试改变 . authorizedWhenInIse to .authorizedAlways(即使你没有看到更新) . 我能够成功地使用Ray Wenderlich的“具有核心位置的地理围栏教程”来重现区域监控在模拟器中的作用 - 您可能想要查看他们的示例项目 . Apple说:

    如果授权状态为kCLAuthorizationStatusAuthorized,则您的应用可以接收其注册的任何地区的过境通知 . 如果授权状态设置为任何其他值,则应用程序不会收到这些通知 .

    注意:

    kCLAuthorizationStatusAuthorized = kCLAuthorizationStatusAuthorizedAlways

    奇怪的是,当模拟器设置为alwaysAuthorization时,您没有看到更新 . 我已经体验到模拟器在时间方面可能会非常偏离 . 即使苹果注意到测试时可能会出现并发症:

    在iOS模拟器或设备上测试区域监控代码时,请注意区域事件可能不会在跨越区域边界后立即发生 . 为防止虚假通知,iOS在满足某些阈值条件之前不会发送区域通知 . 具体而言,用户的位置必须越过区域边界,远离边界移动最小距离,并在报告通知之前保持在该最小距离至少20秒 . 特定阈值距离由当前可用的硬件和定位技术确定 . 例如,如果禁用Wi-Fi,则区域监控要少得多准确 . 但是,出于测试目的,您可以假设最小距离约为200米 .

    所有苹果参考文献来自:https://developer.apple.com/library/content/documentation/UserExperience/Conceptual/LocationAwarenessPG/RegionMonitoring/RegionMonitoring.html#//apple_ref/doc/uid/TP40009497-CH9-SW1

    Ray的教程似乎有效:https://www.raywenderlich.com/136165/core-location-geofencing-tutorial

  • 0

    For iOS 11 use the following in your info.plist:

    <key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
      <string>Need Location</string>
    
      <key>NSLocationAlwaysUsageDescription</key>
      <string>Need Location</string>
    
      <key>NSLocationWhenInUseUsageDescription</key>
      <string>Access For Location</string>
    

相关问题