未经许可将 SCNNode 向北旋转以进行位置跟踪

Posted

技术标签:

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

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

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

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

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

【问题讨论】:

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

希望这会有所帮助。

【讨论】:

以上是关于未经许可将 SCNNode 向北旋转以进行位置跟踪的主要内容,如果未能解决你的问题,请参考以下文章

未经许可的地理定位[重复]

在pointOfView获得ARK的Y旋转

如何在 SceneKit 中移动旋转的 SCNNode?

如何围绕多个轴和不同角度旋转 SCNNode?

SceneKit - 旋转和动画SCNNode

SCNNode 枢轴位置