如何在iOS中使用Swift正确获取加速度计数据?

8

我正在尝试记录iPhone加速度计的数据(我的iPhone 5s),并使用String(format: "%.2f", data)将数据标记在屏幕上,其中data是我要记录的特定轴的值。为此,我设置了一个CMMotionManager并开始记录加速度计数据,并且我有一个定时器不断更新标签中的文本。然而,Xcode给出了一个错误:"fatal error: unexpectedly found nil while unwrapping an Optional value"。以下是相关的代码:

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.

    //if accelerometer can be used, start it
    if (motionManager.accelerometerAvailable) {

        motionManager.accelerometerUpdateInterval = 0.1

        motionManager.startAccelerometerUpdates()
        let timer = NSTimer.scheduledTimerWithTimeInterval(0.1, target: self, selector: Selector("update"), userInfo: nil, repeats: true)
    }



}

func update () {
    if (motionManager.accelerometerActive) {

        accelX.text = String(format: "%.2f", motionManager.accelerometerData.acceleration.x)
    }

}

当我将accelX.text赋值更改为简单字符串时,错误停止了,因此我认为创建错误的可选变量与加速计有关。就我所知,如果您有任何建议,或者如果我完全错了,并且有更好、更容易的方法,我肯定会感激您的帮助。


1
你在哪一行出现了错误?我猜是在 accelX.text = ... 这一行吗?首先,你的 motionManageraccelerometerData 成员可能为 nil,所以你必须先检查它是否有值可显示。像这样:if let accelData = motionManager.accelerometerData { accelX.text = String(format: "%.2f", accelData.acceleration.x) } - Romain
解决了,谢谢!不过我有几个问题。为什么accelerometerData是可选值(即当计时器和加速度计以相同速度(10 fps)运行时,它为什么不总是有值),你是怎么知道它是可选值的? - user4390998
请查看苹果文档中有关该特定属性的信息:https://developer.apple.com/library/ios/documentation/CoreMotion/Reference/CMMotionManager_Class/index.html#//apple_ref/occ/instp/CMMotionManager/accelerometerData。它说`var accelerometerData: CMAccelerometerData! { get }!`表示可选项,下面的描述已经说明了一切。我认为这是因为当您要求iOS开始监视加速度数据时,一开始该数据未初始化,并在几分之一秒后实例化。 - Romain
顺便说一下,更准确地说,“!” 表示“显式展开可选项”,这意味着它是一个常规的可选项,可以在不展开的情况下使用,就像你所做的那样。但是,它仍然可能为 nil(正如你所见),如果您没有首先检查它,仍然可能会导致运行时错误。 - Romain
您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - Romain
显示剩余2条评论
2个回答

12

NSHipster有一篇很好的文章介绍核心动作(Core Motion):http://nshipster.com/cmdevicemotion/

使用以下模式定期更新UI与运动数据的更好方法如下所示:

if manager.accelerometerAvailable {
     manager.accelerometerUpdateInterval = 0.1
     manager.startAccelerometerUpdatesToQueue(NSOperationQueue.mainQueue()) {
     [weak self] (data: CMAccelerometerData!, error: NSError!) in
          accelX.text = String(format: "%.2f", data.acceleration.x)
     }
}

3
你可以获取x、y或z的值,并打印你想要的值的警报。
motionManager.accelerometerUpdateInterval = 5.0
motionManager.startAccelerometerUpdates(to: OperationQueue.current!) { (data, error) in
        if let myData = data{
            print(myData)
            if myData.acceleration.y < -0.2{
                let alert = UIAlertController(title: "Message ", message: "new text", preferredStyle: UIAlertControllerStyle.alert)
                alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler: nil))
                self.present(alert, animated: true, completion: nil)

            }
        }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接