Over the coming weeks we are going to delve in to Core Motion and look at what is available and what can be done with the data that your device provides.
Core Motion was introduced in iOS 4 and provided a way for your app to get data from the sensors on your phone. When Apple introduced the iPhone 5s, they changed the game a little by adding a motion coprocessor. This smaller processor has a single job of handling sensor data recorded by the various sensors on the device even while the device is asleep. It quietly stores this information until the phone wakes up and an app requests the data. The processor requires a lot less power to run, and thus it keeps going 24 hours a day silently keeping this data.
The sensors that Core Motion handles include the accelerometer, gyroscope, pedometer, as well as the magnetometer, and barometer.
The CMMotionManager
The CMMotionManager is the object used to manage Core Motion. The types of data it manages are listed in the documentation on the Core Motion manager class. Briefly, the data includes accelerometer, which is the instantaneous acceleration over 3 dimensions. It also includes gyroscope data which includes the rotation around 3 axis. It includes magnetometer data which indicates the devices orientation relative to the Earth’s magnetic field, and finally, it includes device-motion data. This last part of data is processed by what Apple calls its Core Motion sensor fusion algorithm.
The CMMotionManager is quite a large class because of how it manages all the aspects of Core Motion. In this tutorial we will just look at adding Core Motion to a test app, and then enabling the accelerometer updates, and then logging these to the console.
Getting Started
To get started, download the beginning project. It’s a single view application, so you can download it here, or just create your own single view application.
Step 1 is to import CoreMotion in to ViewController.swift:
import CoreMotion
Next, add the following to viewDidLoad:
let motionManager = CMMotionManager() override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. if motionManager.isAccelerometerAvailable { } }
On line 1 we create our motionManager which is a CMMotionManager.
Line 7 we are checking that accelerometer data is available, and if so, we will begin our work on line 8.
If modify the code above to include the following, and then run the app on a device, you will see a lot of accelerometer updates logged to the console.
if motionManager.isAccelerometerAvailable { motionManager.accelerometerUpdateInterval = 0.1 motionManager.startAccelerometerUpdates(to: OperationQueue.main) { (data, error) in print(data) } }
Line 2 is where we set the interval. This is how often we want to receive updates from the accelerometer. I set it to 0.1 which is 10 updates per second. It can go quicker, but the fastest is determined by your hardware. Apple indicates that the updates can come in as quickly as 100Hz on all devices normally, and often quicker. Apple suggests that if accuracy in delivery is important, it is best you analyse the provided time stamp for each sample.
Line 3 we start the accelerometer updates. We also have a handler which is called each time updates are made.
Line 4 we just print the data which provides the x, y, and z, as well as a time stamp for each update.
Go ahead and run the app and move the phone around to see how accelerometer data is represented in the console. To help you understand what the numbers mean, here is how you can interpret them.
If you hold the iPhone vertically with the screen facing towards you, X is the left to right axis. Y is the up and down axis, and Z is the 3rd dimension going from you straight through the screen to behind the phone.
If your phone is laying on its back with the screen facing up, z will be around -1 (or 1G). If it’s laying screen down, it will be around +1G. If you put the phone balancing on its left side, gravity is following the X axis. Because the left side of the phone is on the desk, the reading of X will change to -1G.
If you want to stop accelerometer updates, you can simply call the stopAccelerometerUpdates() method on the motionManager object.
If you do not want constant updates, you can call startAccelerometerUpdates() without specifying the handler. To get accelerometer data when doing it this way, call the accelerometerData method which returns a CMAccelerometerData which is a snapshot of the values at the moment you make a call to that method.
What’s Next?
Although this tutorial was brief, we will move through the various classes and items available in Core Motion. For some tutorials we may combine two together where that makes sense.
There is no sample project to download with the completed code because of it being fairly straight forward, but below is a copy of ViewController.swift which you can paste in your app to test this out if you get stuck with the instruction above.
import UIKit import CoreMotion class ViewController: UIViewController { let motionManager = CMMotionManager() override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. if motionManager.isAccelerometerAvailable { motionManager.accelerometerUpdateInterval = 0.01 motionManager.startAccelerometerUpdates(to: OperationQueue.main) { (data, error) in print(data) } } } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } }
Leave a Reply
You must be logged in to post a comment.