【问题标题】:Rotate SCNNode to North without permission for location tracking未经许可将 SCNNode 向北旋转以进行位置跟踪
【发布时间】:2019-09-16 05:37:30
【问题描述】:

我们想旋转一个SCNNode 以匹配北方向。

Arkit 允许将其 z 轴与北方对齐,但这需要用户许可才能进行位置跟踪,我们不想要求它。 见gravityandheading

因此,我们尝试使用 CMDeviceMotion 的磁场属性。但我们不知道该怎么做。 可能有一些矩阵计算,但我们暂时不掌握。 见magneticfield

任何帮助将不胜感激!谢谢!

【问题讨论】:

  • 如果需要节点与北轴精确对齐;请记住,在很多情况下,仅使用设备传感器来确定方向是不够的,因为电磁场的干扰太强会造成相当大的误差。
  • 不,没有位置许可你不能得到它! , 如果您需要将任何节点向北旋转,您必须知道设备面向的位置,为此您需要位置权限

标签: ios augmented-reality arkit compass-geolocation


【解决方案1】:

未经用户许可,您不能使用位置跟踪

以下是有关如何为AR 应用NON-AR 应用 正确设置它的一些提示:

iOS 11 及更高版本中,您需要执行以下操作才能使定位正常工作:

  • 将密钥添加到您的info.plist 并请求位置管理器的授权以启动它。 info.plist 中有两个Property List Keys 用于位置授权。 需要其中一个或两个键。在非 AR 应用中,如果两个键都不存在,您可以调用 startUpdatingLocation 方法,但位置管理器实际上不会启动。它也不会向代理发送失败消息(因为它从未启动,所以它不会失败)。 如果您添加一个或两个密钥但忘记明确请求授权,它也会失败

info.plist 文件中使用这两个Property List Keys。自 iOS 11 发布以来就使用它们

<key>NSLocationWhenInUseUsageDescription</key>
  <string>App needs an access to your location (in foreground)</string>

<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
  <string>App needs an access to your location (in background)</string>

这两个Property List Keys 早前已弃用不要使用这些键):

    <key>NSLocationUsageDescription</key>
      <string>App needs an access to your location (in background)</string>

    <key>NSLocationAlwaysUsageDescription</key>
      <true/>

AR 应用代码如下所示:

let configuration = ARWorldTrackingConfiguration()

func session(_ session: ARSession, didFailWithError error: Error) {

    switch error.code {
    case 101:
        configuration.worldAlignment = .gravity
        restartSession()
    default:
        configuration.worldAlignment = .gravityAndHeading
        restartSession()
    }
}   
func restartSession() {    
    self.sceneView.session.pause()
    self.sceneView.session.run(configuration, options: [.resetTracking, 
                                                        .removeExistingAnchors])
}

对于非 AR 应用,请使用以下两种实例方法:requestAlwaysAuthorization()(在应用运行时请求使用位置服务的权限)和requestWhenInUseAuthorization()(在应用处于前台时请求使用位置服务的权限)。

您的代码用于非 AR 应用应如下所示:

import CoreLocation

class ViewController: UIViewController, CLLocationManagerDelegate {

    var locationManager = CLLocationManager()

    func updateMyLocation() {

        locationManager.delegate = self
        locationManager.desiredAccuracy = kCLLocationAccuracyThreeKilometers

        if locationManager.respondsToSelector(#selector(CLLocationManager.requestWhenInUseAuthorization)) {
            locationManager.requestWhenInUseAuthorization()
        } else {
            locationManager.startUpdatingLocation()
        }
    }
}

另外,您可以申请Always Authorization:

let locationManager = CLLocationManager()   

func enableLocationServices() {

    locationManager.delegate = self

    switch CLLocationManager.authorizationStatus() {

        case .notDetermined:
            // Request when-in-use authorization initially
            locationManager.requestWhenInUseAuthorization()
            break

        case .restricted, .denied:
            // Disable location features
            disableMyLocationBasedFeatures()
            break

        case .authorizedWhenInUse:
            // Enable basic location features
            enableMyWhenInUseFeatures()
            break

        case .authorizedAlways:
            // Enable any of your app's location features
            enableMyAlwaysFeatures()
            break
    }      
}

希望这会有所帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-02-15
    • 2015-09-14
    • 2021-07-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-29
    相关资源
    最近更新 更多