Dodgson86
Dodgson86

Reputation: 333

Core Motion Swift Closure issue

I'm trying to convert an old game application built in obj-c to the new swift code. i'm having some issues understanding swift closures and how to use them for example in the"startAccelerometerUpdatesToQueue" method.

i have initialized the motion manager in this way

motionManager!.accelerometerUpdateInterval = (1/40)

then in the viewdidload of my view controller

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


})

the "startAccelerometerUpdatesToQueue" is giving me an error and i'm pretty sure i didn't understand the correct closure syntax.

Any ideas?

Upvotes: 3

Views: 3982

Answers (3)

Sai kumar Reddy
Sai kumar Reddy

Reputation: 1829

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)
        }
    }

}

Upvotes: 0

Khalid Al-qahtani
Khalid Al-qahtani

Reputation: 1

CMMotionManager

object is the gateway to the motion services provided by iOS. These services provide an app with accelerometer data, rotation-rate data, magnetometer data, and other device-motion data such as attitude. These types of data originate with a device’s accelerometers and (on some models) its magnetometer and gyroscope.

Handling Motion Updates at Specified Intervals

To receive motion data at specific intervals, the app calls a “start” method that takes an operation queue (instance of NSOperationQueue) and a block handler of a specific type for processing those updates. The motion data is passed into the block handler. The frequency of updates is determined by the value of an “interval” property.

  • Accelerometer.

Set the accelerometerUpdateInterval property to specify an update interval. Call the startAccelerometerUpdatesToQueue:withHandler: method, passing in a block of type CMAccelerometerHandler. Accelerometer data is passed into the block as CMAccelerometerData objects.

  • Gyroscope.

  • Magnetometer.

  • Device motion.

The interval, in seconds, for providing accelerometer updates to the block handler.

Declaration

SWIFT

var accelerometerUpdateInterval: NSTimeInterval

Discussion The system supplies accelerometer updates to the block handler specified in startAccelerometerUpdatesToQueue:withHandler: at regular intervals determined by the value of this property.

The interval units are in seconds. The value of this property is capped to minimum and maximum values; the maximum value is determined by the maximum frequency supported by the hardware. If your app is sensitive to the intervals of acceleration data, it should always check the timestamps of the delivered CMAccelerometerData instances to determine the true update interval.

Availability Available in iOS 4.0 and later.

Upvotes: 0

Lukas
Lukas

Reputation: 3133

Actually, you just got the signature wrong – the arguments to your closure need to be optionals (since they are passed from Objective-C, they could be nil). Because of that, the arguments you provide don't match an existing method signature, and because of that you get an error.

Take a look at the iOS 8 API docs, they also provide Swift signatures:

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

and CMAccelerometerHandler is defined as

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

Thus, your call should be:

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


})

And as with any function/method that takes a closure as it's last argument, you can leave it out of the argument list and write it after the call (trailing closure syntax – this example also leaves out the types, as they can be inferred, but that is optional):

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

}

Upvotes: 7

Related Questions