Join Steven Lipton for an in-depth discussion in this video Add elapsed tIme, part of Advanced iOS App Development: Core Motion.
- [ Voiceover] The Pedometer application so far, cannot measure pace for all devices. We tried using the built in average pace, to the CM Pedometer class, but that didn't work for the iPhone 5s I'm using. Pace, however, is a calculated value, and it's a good example of getting around the lack of device availability. I've got distance on this device, and all I need is time to compute pace on my own. Let's add elapsed time to the app, from that I'll compute an average pace. An easy way to get elapsed time, is to add a counter to the current timer, and display the counter.
At the top of the code, add the following two declarations: var elapsed seconds equals 0.0 and let interval equals 0.1 I'll use elapsed seconds as a counter, and interval as an increment. I'll change my timer to use this interval. Slide down to start timer.
Change the time interval from 1.0 to interval. In the completion block, add an increment to elapsed seconds. Self.elapsed seconds plus, equals self.interval. With an elapsed time property, I'll display it on the application in the status label. However, most people don't like a simple count of seconds, but want a minutes and seconds count.
I'll make another quick function to convert minutes to seconds as a string. So just above start timer here, I'm going to add func minutesSeconds using seconds as a double, and returning the string. So I can convert minutes, I'll do let minutePart equal int seconds divided by 60 as an integer.
And for the seconds, we'll use the modulo get the remainder. So we'll get let secondsPart equal int seconds and we'll get the remainder of 60. And then I'm going to return a string, formatted, with a leading zero, two digits long of an integer, a colon and then another two digit with a leading zero integer.
And then I'm going to use a minutePart, and the secondsPart. And that'll leave me a nice little formatted string for my time. Now I can use this for the elapsed time, and I can go back into display Pedometer data. And I'll stick this one at the top. statusLabel.text equals Pedometer On and I'll concatenate that minutesSeconds function.
And then I'll put the elapsedSeconds in there. Next I'll make a function for a computed pace dividing the elapsed seconds over the distance. I might get a division by zero error, at a zero distance. So I'll place this in an if else to return zero if distance is zero. So we'll make another function, we'll actually put that above displayPedometerData. And I'm going to call that func calculatedPace and that's going to return a double.
If distance is greater than zero, return elapsed seconds divided by the distance which gives us our computed pace. Other wise, we'll use the else and return zero. I can now go down to where it is at isPaceAvailable. And the else for that, I originally had pace not supported, I'm going to comment out those two lines.
So I'm going to change in this else to paceLabel.text equals average pace colon, and then I'm going to use my calculated pace for that. And end the quote. And then we're going to print that. Okay so we're ready to run the application.
And we're still using the 5s here. So I'm going to go ahead and run. Let's take a look at it on QuickTime. Which I have it up here. And I can go ahead and hit start. And start doing my run, and you can see that the pace is there. And there we go, we have a pace that's actually being calculated as we run. And if we click over here, you can see it all as well, in the console.
Okay go ahead and stop. Once you stop the application, take a look at the average pace. We're getting data in seconds per meter. While internally, that's fine, it's not a useful measurement for a user. I'll change it to minutes per mile, which is usually measured as minutes and seconds. Add a conversion constant above the if statement. So go ahead and close this up again, and right above the isPaceAvailable, put a constant in of minutesPerMile and that happens to equal 1609.34 as a conversion constant.
So I can now go back down to where I said paceLabel.text. And I'm going to actually change this now, I can get rid of this calculated pace, so now I'll add minutesSeconds and then add calculated pace times my constant minutes per mile to get a correct average pace. Now I'm also going to do the same thing up here for my pace that I'll calculate from the device itself if it does actually have pace available.
So here we're going to change this to minutesSeconds again. That's going to be pace times our constant minutesPerMile. Okay. We can stop the old one, start the new one, launch the app. And start it. And now you'll see that we get an average pace if you start running with it. And do your run in place you'll start seeing that you're getting a average pace show up.
And you can go ahead and stop it now, since we're getting it now. And you can start to see that we got numbers of the distance. And we've got an average pace here, that's written out in a form that makes sense. In this case I've got an 18.58 minute per mile. That's how you can let all your devices get some kinds of data, is by computing from one thing to another. The trick for pace, though, only works if your device has distance data. Check if all the stats are available before you start computing things. Come up with strategies that either tell the user this won't work on the device, or find ways to compute what core motion can't give you.
- Reading Core Motion data
- Understanding Core Motion methods
- Creating a pedometer app
- Using pace and distance data from Core Motion
- Pushing and pulling device motion data
- Accessing the altitude sensors
- Working with the motion activity manager (CMMotionActivityManager)