MotionKit — The Missing iOS CoreMotion Wrapper written in Swift

Haroon Baig
iOS App Development
5 min readFeb 16, 2015

If you’ve ever worked with the CoreMotion Framework, you’d probably agree, that its a curse. Apple puts too many restrictions, and provides various guidelines for the developers who want to leverage the power of sensors into their apps. Everybody knows that sensor enabled apps are power hungry , and many apps are rejected every year just because of the fact that they weren’t able to follow the proper guidelines, thus decreasing the battery performance drastically.

Same thing happened to me as well, a while ago. I recently joined Messiah as a Cofounder. Messiah is actually an emergency alert messenger, truly open sourced, to relay distress signal for the user in the case of an accident or emergency. Accident Detection was the core feature of this app, which needed some heavy computations with the data retrieved from some sensors like Accelerometer, Gyroscope and services like Device Motion. With the passage of time, our algorithm got pretty complex and it became really hard to maintain the code, specially the asynchronous calls of the CoreMotion Framework and the object lifecycle of the CMMotionManager throughout the app. So, long story short, I decided to make my own wrapper around the CoreMotion Framework, which just works and delivers what it says.

I named my wrapper, the MotionKit. MotionKit makes it easy for the developers to focus just on the logic, instead of dwindling around the core syntax and the object life-cycle stuff, having the performance metric in mind. You can do pretty much everything with it, i.e. you can retrieve all the sensor data with either push or pull method, recieve sensor data updates by using the powerful Trailing Closures or through the provided Delegates, use the helper methods which are included into the Kit, get the refined and processed data through the Device Motion service of the iOS which uses various sensor fusion algorithms to reduce the noise from the raw sensor data, and much much more.

How to install ?

Just go Here, clone the repository or Download it. Having that done, just copy the MotionKit.swift file into your Xcode project. Thats it. Now grab a cup of coffee, and see how the magic is been done.

Usage ( My favourite part )

The Magic Part is here.

First, initialise the MotionKit instance. Its a Must.

let motionKit = MotionKit()

Getting Accelerometer Data

Now lets say you wanna retrieve the Raw Accelerometer data from the MotionKit. Well, you can do this with just ‘two’ lines of code (without the Braces and formal stuff of course).

motionKit.getAccelerometerValues(interval: 1.0){
(x, y, z) in
//Do whatever you want with the x, y and z values
println("X: \(x) Y: \(y) Z \(z)")
}

Getting Gyroscope Data

Wanna use the Gyroscope ? Well, we’ve got you covered. Getting the raw Gyroscope data is as easy as getting a pie (and eating it too!)

motionKit.getGyroValues(interval: 1.0){
(x, y, z) in
//Do whatever you want with the x, y and z values
println("X: \(x) Y: \(y) Z \(z)")
}

Getting Magnetometer Data

Wanna feel the presence of a ghost inside your room by the Magnetic Field around your iDevice ? Well, it’ll take as much time as it takes to call a rescue service.

motionKit.getMagnetometerValues(interval: 1.0){
(x, y, z) in
//Do whatever you want with the x, y and z values
println("X: \(x) Y: \(y) Z \(z)")
}

What about the Device Motion service ?

I know you were thinking about this. I’m a ghost, haha.

Lemme talk a little bit about Device Motion service. If you are already familiar with this service, you can skip the beautiful and informative paragraph below (just kidding, its kinda boring, to be honest).

Actually, CoreMotion offers a ‘Device Motion’ service, which automatically processes and refines the raw sensor data coming from both the Accelerometer and Gyroscope. It uses something called ‘Sensor Fusion Algorithm’, which refines the raw data by measuring the Device’s attitude, rotation rate and the gravity metrics. CMDeviceMotion is an instance which holds all of these magical, processed and refined values but wait a minute ? Is that easy to grab those values ? Yes! but I’ve made it more easy through my MotionKit wrapper !

Getting the CMDeviceMotion instance

Well, you can grab that instance which has all those magical values by just … ok, I mean, have a look below.

motionKit.getDeviceMotionObject(interval: 1.0){
(deviceMotion) -> () in
var accelerationX = deviceMotion.userAcceleration.x
var gravityX = deviceMotion.gravity.x
var rotationX = deviceMotion.rotationRate.x
var magneticFieldX = deviceMotion.magneticField.x
var attitideYaw = deviceMotion.attitude.yaw
....
}

Thats it ! This was the magic I was talking about. But, there’s much more to it. Follow along with me, it’ll make your entire day.

Getting refined and processed Acceleration data

You can retrieve the user acceleration, which is already being processed and refined by the Device Motion service, having less noise than the raw Accelerometer data.

motionKit.getAccelerationFromDeviceMotion(interval: 1.0){
(x, y, z) -> () in
// Grab the x, y and z values
}

As easy as pie. Seriously. Wait, you can grab other sensors data as well, exactly like the method described above.

Getting Gravitational Acceleration

It’s easy Easy ! Thats what I wanna say !

motionKit.getGravityAccelerationFromDeviceMotion(interval: 1.0) {
(x, y, z) -> () in
// x, y and z values are here
}

Getting Magnetic Field around your device

See by yourself. You’ll die wondering how easy it was.

motionKit.getMagneticFieldFromDeviceMotion(interval: 1.0) {
(x, y, z, accuracy) -> () in
// Get the values with accuracy
}

Getting the Attitude metrics

The Device Attitude’s property has the following metrics (I wish I would’ve taken my Physics class in high school)
- Roll
- Pitch
- Yaw
- Rotation Matrix
- Quaternion
I dont know what those Alien looking terms actually mean (just kidding, I never took the physics classes but I was an active student at Khan’s Academy). You can grab all those values by just staring at the screen haha.

motionKit.getAttitudeFromDeviceMotion(interval: 1.0) {
(attitude) -> () in
var roll = attitude.roll
var pitch = attitude.pitch
var yaw = attitude.yaw
var rotationMatrix = attitude.rotationMatrix
var quaternion = attitude.quaternion
}

Easy Enough. Thanks to my parents who insisted me to learn Physics, me lucky.

Getting the Rotation Rate of your device

Warning ! Don’t blend your iDevice to measure its rotation rate !

motionKit.getRotationRateFromDeviceMotion(interval: 1.0) {
(x, y, z) -> () in
// There you go, grab the x, y and z values
}

I hope you haven’t tried blending your device to measure the Rotation Rate, huh!

Precautionary measures

Apple suggests using just one instance of the CMMotionmanager throughout your app to keeps things smoother by using less resources and battery power. I suggest you to stop receiving updates from the sensors as soon as you’re done. The methods for doing this are the following.

    //Make sure to call the required function when you're done
motionKit.stopAccelerometerUpdates()
motionKit.stopGyroUpdates()
motionKit.stopDeviceMotionUpdates()
motionKit.stopmagnetometerUpdates()

Delegate Methods

MotionKit provides the following Delegate Methods. You can either use Trailing Closures or these Delegate methods to get the sensor data. Your choice. Do as you please. Have a look at the provided Delegate Methods Here.

Our Reddit Channel

I’d love to hear from you. I have created a Reddit channel to discuss everything about MotionKit. You can either create an issue over there on GitHub to request a feature set, Or, you can ping me here. Our Reddit channel is /r/MotionKit/

For Questions, you can also use the StackOverflow tag ‘MotionKit’.

Verdict

Nothing else is left to say. Please support MotionKit by giving it a star. Fork it and send me a pull request if you wanna contribute. Till then, have a good time. Happy Coding.

--

--

Haroon Baig
iOS App Development

👋 I help companies in the crypto space produce better, insightful, & engaging content that people LOVE! Everything from ECDSA to zk-SNARKs, Bitcoin to Polkadot