Storing Acceleration Data

We need to store the collected data to be able to draw it in the next step. The accelerometer of the iPhone collects data for each axis of the device—we get three Double values in each event. As the update interval of the events depends on the current state of the hardware, we also need to store the event’s timestamp so that later we’ll be able to calculate the swing’s frequency. Add a new Swift file using the shortcut N. Save the file as AccelerationData.swift.

Add the following struct to the file:

 struct​ ​AccelerationData​ {
 let​ timestamp: ​TimeInterval
 let​ value: ​Double
 }

The struct has two properties, one for storing the timestamp of the event and one for storing the actual value. The type TimeInterval is defined in Foundation, and it is just a typealias for Double. Type aliases are often used to make code more readable. This way the type of timestamp gives us additional information about the usage of that property.

Pro Tip: typealias for Your Own Types

images/aside-icons/tip.png

You can define your own type aliases. For example, when you have a property for a duration of seconds, you could define a type alias with typealias Second = Float. Then you can use Second interchangeably with Float. If requirements change later in the development process and Second needs to become an Int, you only have to change the type once.

Note that we don’t have to add an initializer because AccelerationData is a structure and, as such, gets a default initializer. It’s a good idea to use a struct here because the acceleration data is best represented by value type. To learn more about the difference between classes and structures, and when to use which, see the Swift documentation.[7]

Now we can add an array to store the motion events. Open the class MeasurementViewController and add the highlighted property below the motionManager property:

 let​ motionManager = ​CMMotionManager​()
»var​ xAccelerationData: [​AccelerationData​] = []

For now we need only one array for the x-axis—later we’ll add arrays for the other axes too.

To fill the array with acceleration data, add the highlighted lines in the following code to the method startMotionUpdates:

 func​ ​startMotionUpdates​() {
 
  motionManager.deviceMotionUpdateInterval = 1 / 60
 
  motionManager.​startDeviceMotionUpdates​(
  using: .xArbitraryZVertical,
  to: ​OperationQueue​()) { motion, error ​in
 
 guard​ ​let​ motion = motion ​else​ {
 return
  }
 
»let​ acceleration = motion.userAcceleration
»let​ timestamp = motion.timestamp
»let​ xData = ​AccelerationData​(timestamp: timestamp,
» value: acceleration.x)
»
»DispatchQueue​.main.async {
»self​.xAccelerationData.​append​(xData)
» }
  }
 }

With guard let, we unwrap the optional motion value. This means the program continues after the closing curly brace only if motion is not nil. In this case, the value is assigned to the nonoptional constant motion on the left side of the equal sign.

Even if the device is lying flat on the table, the accelerometer measures an acceleration—the gravitation. (The equivalence of acceleration and gravitation was first formulated by Albert Einstein in his general theory of relativity.) Fortunately, Apple provides us with a value where the gravitation is already deducted: userAcceleration. We assign this value to a constant because it makes the code that follows easier to read.

Next, we create an instance of AccelerationData with the timestamp of the motion event and the x-value of the acceleration. This instance is then added to the array of acceleration data for the x-axis.

Note that we have removed the print method because we don’t need it anymore.

Now that we have the data, we need a user interface to show it. We’re going to use a storyboard for the user interface.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.145.47.253