Core Motion Swift Closure问题

时间:2014-06-10 10:50:04

标签: ios xcode swift core-motion ios8

我正在尝试将obj-c中构建的旧游戏应用程序转换为新的swift代码。我在解决swift闭包以及如何在“startAccelerometerUpdatesToQueue”方法中使用它们时遇到了一些问题。

我已经用这种方式初始化了运动管理器

motionManager!.accelerometerUpdateInterval = (1/40)

然后在我的视图控制器的viewdidload中

var queue:NSOperationQueue
motionManager?.startAccelerometerUpdatesToQueue(queue, withHandler: {(accelerometerData :     CMAccelerometerData, error : NSError) in


})
“startAccelerometerUpdatesToQueue”给了我一个错误,我很确定我不理解正确的闭包语法。

有什么想法吗?

3 个答案:

答案 0 :(得分:6)

实际上,你只是签名错了 - 你的闭包的参数需要是选项(因为它们是从Objective-C传递的,它们可能是nil)。因此,您提供的参数与现有方法签名不匹配,因此您会收到错误。

看看iOS 8 API docs,他们还提供Swift签名:

func startAccelerometerUpdatesToQueue(_ queue: NSOperationQueue!,
                          withHandler handler: CMAccelerometerHandler!)

CMAccelerometerHandler定义为

typealias CMAccelerometerHandler = (CMAccelerometerData!, NSError!) -> Void

因此,您的电话应该是:

motionManager?.startAccelerometerUpdatesToQueue(queue, withHandler: {(accelerometerData :     CMAccelerometerData!, error : NSError!) in


})

与任何以闭包作为最后一个参数的函数/方法一样,你可以将它从参数列表中删除并在调用之后写入它(尾随闭包语法 - 这个例子也省略了类型,因为它们可以推断,但这是可选的):

motionManager?.startAccelerometerUpdatesToQueue(queue) { accelerometerData, error in

}

答案 1 :(得分:0)

CMMotionManager

object是iOS提供的运动服务的入口。这些服务为应用提供加速度计数据,旋转速度数据,磁力计数据以及其他设备动态数据,例如态度。这些类型的数据来自设备的加速度计和(在某些型号上)其磁力计陀螺仪

以指定间隔处理动作更新

要以特定的时间间隔接收动作数据,应用程序会调用一个“start”方法,该方法接受一个操作队列( NSOperationQueue 的实例)和一个特定类型的块处理程序来处理这些更新。运动数据被传递到块处理程序中。更新频率由“interval”属性的值决定。

  • 加速度计。

设置 accelerometerUpdateInterval 属性以指定更新间隔。调用 startAccelerometerUpdatesToQueue:withHandler:方法,传入 CMAccelerometerHandler 类型的块。加速度计数据作为 CMAccelerometerData 对象传递到块中。

  • 陀螺

  • 磁力。

  • 设备动作。

为块处理程序提供加速度计更新的间隔(以秒为单位)。

<强>声明

SWIFT

var accelerometerUpdateInterval:NSTimeInterval

<强>讨论 系统为 startAccelerometerUpdatesToQueue:withHandler 中指定的块处理程序提供加速度计更新:定期由此属性的值确定。

间隔单位以秒为单位。此属性的值上限为最小值和最大值;最大值由硬件支持的最大频率决定。如果您的应用程序对加速数据的间隔敏感,则应始终检查已交付的 CMAccelerometerData 实例的时间戳,以确定真正的更新间隔。

状况 适用于iOS 4.0及更高版本。

答案 2 :(得分:0)

import UIKit
import CoreMotion

class ViewController: UIViewController {

    let motionManager = CMMotionManager()
    var timer: Timer!

    override func viewDidLoad() {
        super.viewDidLoad()

        motionManager.startAccelerometerUpdates()
        motionManager.startGyroUpdates()
        motionManager.startMagnetometerUpdates()
        motionManager.startDeviceMotionUpdates()

        timer = Timer.scheduledTimer(timeInterval: 3.0, target: self, selector: #selector(ViewController.update), userInfo: nil, repeats: true)
    }

    @objc func update() {

        if let accelerometerData = motionManager.accelerometerData {
            print(accelerometerData)
        }
        if let gyroData = motionManager.gyroData {
            print(gyroData)
        }
        if let magnetometerData = motionManager.magnetometerData {
            print(magnetometerData)
        }
        if let deviceMotion = motionManager.deviceMotion {
            print(deviceMotion)
        }
    }

}