3

After reading about Swift Closures and trying to use the same syntax to pass a anonymous function into the handler I cannot get it to compile. How can I correctly re-create the following functioning objective c code in Swift?

Here is the objective c code that I am trying to re-create in swift

 [self.motionManager
     startAccelerometerUpdatesToQueue:[[NSOperationQueue alloc] init]
     withHandler:^(CMAccelerometerData *data, NSError *error)
     {

         dispatch_async(dispatch_get_main_queue(),
                        ^{

                            float xx = data.acceleration.x;
                            float yy = -data.acceleration.y;
                            float angle = atan2(yy, xx);

                            self.dropitBehavior.gravity.angle = angle;
                         });
     }
 ];

Here are few failed attempts at re-creating the code in swift:

self.motionManager.startAccelerometerUpdatesToQueue(NSOperationQueue(), withHandler: {
            (data: CMAccelerometerData(), error: NSError()) -> Void = {
                dispatch_async(dispatch_get_main_queue()) {
                    var xx = data.acceleration.x
                    var yy = -data.acceleration.y
                    var angle = atan2(yy, xx)

                    self.dropitBehavior.gravity.angle = angle
                }
            }
  })

self.motionManager.startAccelerometerUpdatesToQueue(NSOperationQueue(), withHandler: {
            (data: CMAccelerometerData(), error: NSError()) {
                dispatch_async(dispatch_get_main_queue()) {
                    var xx = data.acceleration.x
                    var yy = -data.acceleration.y
                    var angle = atan2(yy, xx)

                    self.dropitBehavior.gravity.angle = angle
                }
            }
 })

1 Answer 1

12

By doing CMAccelerometerData() and NSError() you are actually calling the initializers of those classes. You just need to use their types. However, because in objective-C, pointers can be nil, when you translate the types to Swift, you need to use optionals. The convention is to use Implicitly Unwrapped Optionals. Also, you separate the parameters of an anonymous closure with in not additional curly brackets:

self.motionManager.startAccelerometerUpdatesToQueue(NSOperationQueue(), withHandler: {
    (data: CMAccelerometerData!, error: NSError!) in
    // internal implementation
})

Also, because the types can be inferred from the parameter type, you don't have to even specify the types for the parameters:

self.motionManager.startAccelerometerUpdatesToQueue(NSOperationQueue(), withHandler: {
    (data, error) in
    // internal implementation
})

Also, if a block is the last parameter to a method / function call, you can define it outside of the parenthesis:

self.motionManager.startAccelerometerUpdatesToQueue(NSOperationQueue()) {
    (data, error) in
    // internal implementation
}

This way you don't need the closing ) after the closure.

That creates the final version with your internal implementation:

self.motionManager.startAccelerometerUpdatesToQueue(NSOperationQueue()) {
    (data, error) in
    dispatch_async(dispatch_get_main_queue()) {
        var xx = data.acceleration.x
        var yy = -data.acceleration.y
        var angle = atan2(yy, xx)

        self.dropitBehavior.gravity.angle = angle
    }
}
Sign up to request clarification or add additional context in comments.

7 Comments

Thanks for the answer. Although I am getting an error 'Missing argument for parameter #2 in call' which highlights the dispatch_async line
@nearpoint Sorry, I was missing the opening curly bracket of the async block. I updated my answer
Ah thanks so much this answer is extremely helpful. I will reference it many times
ah and knowing about the third point (if the closure if the last argument you can put it outside the parentheses) makes me understand better why dispatch_async syntax is the way it is
@nearpoint Yup, the syntax can look somewhat strange with that until you get used to it
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.