3

My app uses CoreMotion to allow the player to move when the device is tilted. It worked perfectly in Swift 2 but when I updated it to Swift 3 it has stopped working. I am not receiving any accelerometer updates.

override func didMove(to view: SKView) {
    manager.startAccelerometerUpdates()
    manager.accelerometerUpdateInterval = 0.1
    manager.startAccelerometerUpdates(to: OperationQueue.main){ (data, Error) in
        if let accelerometerData = self.manager.accelerometerData {
            self.physicsWorld.gravity = CGVector(dx: accelerometerData.acceleration.y * 10, dy: accelerometerData.acceleration.x * 10)
        }
    }
}
MarkHim
  • 5,686
  • 5
  • 32
  • 64
Euan
  • 43
  • 5
  • You said: "it has stopped working". I can only guess that you mean that it compiles and runs fine, but your handler is never called. Is that right? – Coder-256 Feb 02 '17 at 16:27

1 Answers1

2

NSError has been renamed to Error in Swift 3, so please make your Error variable camelCase (lowercase in your situation). It should have been camelCase since it's a variable, anyways.

Here is a new version of the function with that and other minor errors fixed (NOTE MY COMMENT ABOUT SWAPPING X AND Y):

override func didMove(to view: SKView) {
    manager.accelerometerUpdateInterval = 0.1
    manager.startAccelerometerUpdates(to: OperationQueue.main) { data, _ in
        if let accelerometerData = data {
            // IMPORTANT: Are you intentionally swapping x and y here? -----------> ↓
            self.physicsWorld.gravity = CGVector(dx: accelerometerData.acceleration.y * 10,
                                                 dy: accelerometerData.acceleration.x * 10)
        }
    }
}

And here is the original function with just the variable renamed (NOTE: There are a few programming mistakes in here, I don't recommend using it):

override func didMove(to view: SKView) {

    manager.startAccelerometerUpdates()
    manager.accelerometerUpdateInterval = 0.1
    manager.startAccelerometerUpdates(to: OperationQueue.main) { (data, error) in

        if let accelerometerData = self.manager.accelerometerData {
            self.physicsWorld.gravity = CGVector(dx: accelerometerData.acceleration.y * 10, dy: accelerometerData.acceleration.x * 10)
        }

    }
}

EDIT: You should not use the main queue as your OperationQueue for recieving Accelerometer updates. See Apple's documentation.

Coder-256
  • 5,212
  • 2
  • 23
  • 51
  • I have tried using your solution but it still doesn't call the accelerometer, i do get a message in the log "if we're in the real pre-commit handler we can't actually add any new fences due to CA restriction". Im not sure if this is the problem. – Euan Feb 03 '17 at 04:18
  • Are you sure that the handler is not called? Try putting: `print("Got accelerometer data: \(accelerometerData)")` after the `if let accelerometerData...` line. Also, which version of the code are you using? – Coder-256 Feb 03 '17 at 14:27
  • I'm sure that the handler isn't called, the log only displays `[App] if we're in the real pre-commit handler we can't actually add any new fences due to CA restriction` Im using the code you suggested above – Euan Feb 04 '17 at 04:11
  • I'm sure that the handler is called, because [that log message can be safely ignored](http://stackoverflow.com/a/39997761/3398839). Please research any errors you have before posting. Anyways, add a `print` statement right below the `didMove` function to make sure that the handlers are even registered. Also see my edit. – Coder-256 Feb 04 '17 at 13:05
  • Thank you. I saw that it wasnt being called and i was able to track the problem to the view controller not loading the .swift file – Euan Feb 09 '17 at 04:43