Core Motion Swift 关闭问题

Posted

技术标签:

【中文标题】Core Motion Swift 关闭问题【英文标题】:Core Motion Swift Closure issue 【发布时间】:2014-06-10 10:50:04 【问题描述】:

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

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

motionManager!.accelerometerUpdateInterval = (1/40)

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

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


)

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

有什么想法吗?

【问题讨论】:

【参考方案1】:

实际上,你只是弄错了签名——闭包的参数必须是可选的(因为它们是从 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


【讨论】:

【参考方案2】:

CMMotionManager

object 是 iOS 提供的运动服务的网关。这些服务为应用程序提供加速度计数据、旋转速率数据、磁力计数据和其他设备运动数据,例如姿态。这些类型的数据源自设备的加速度计和(在某些型号上)其磁力计陀螺仪

以指定的间隔处理运动更新

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

加速度计。

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

陀螺仪。

磁力计。

设备运动。

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

声明

斯威夫特

var accelerometerUpdateInterval: NSTimeInterval

讨论 系统向 startAccelerometerUpdatesToQueue:withHandler 中指定的块处理程序提供加速度计更新:由该属性的值确定的定期间隔。

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

可用性 适用于 iOS 4.0 及更高版本。

【讨论】:

【参考方案3】:
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)
        
    


【讨论】:

以上是关于Core Motion Swift 关闭问题的主要内容,如果未能解决你的问题,请参考以下文章

Core Motion 陀螺仪旋转有问题

SWIFTUI 和 Core Motion

Core Motion:如何判断“向上”是哪条路?

Core Motion传感器原始数据

Core Motion 是不是需要授权/.plist 信息?

使用 Core Motion 从加速度计数据中获取位移