You will learn to make fluid digital interactive experiences that are suitable for gaming and use the advanced sensor hardware built into the iPhone and iPad. This includes drawing 2D graphics, playing sounds and music, integrating with Game Center, the iOS physics engine and detecting device orientation and location.
Upon completing this course, you will be able to:
1. Use the reverse geocode service to convert latitude and longitude to location names
2. Implement GeoFences to make an app efficiently monitor an iOS device’s location
3. Leverage the power of accelerometers, magnetometers and gyroscopes to orient a device in physical space
4. Create an app that responds to ambient light levels by using screen brightness as a proxy
5. Play sound effects and other media as audio
6. Make a game like Pong
7. Make a game like Breakout
8. Manipulate graphics in a game environment
9. Use the physics engine to create realistic game worlds
10. React to multi-touch events for complex interaction design
11. Detect and respond to collisions and contacts efficiently
12. Chain complex sequences of actions, animations and sounds with precision
13. Animate multi-frame sprites
14. Create particle systems to simulate fire, smoke and magic (and more!)
15. Interface with Game Center to create leaderboards and achievements that can be shared through social networks

PP

HS

Apr 27, 2017

Filled StarFilled StarFilled StarFilled StarFilled Star

Great course! A good overview to work with games, sensors and media.

From the lesson

Location, Locomotion and Motion

In this week we are going to do a deep dive on the sensors in the iOS platform. Sensors are one of the aspects of smartphones that make them a unique platform and form a bridge between the digital and physical world. We will look at different ways of bridging that divide with location sensors (and street address look-ups via reverse geocoding), geofencing and motion sensors. This will give you the skills to write code that makes your apps aware of the world around them and possibly even react to a user’s physical movement.

Taught By

Don Patterson

Sam Kaufman

Transcript

[MUSIC] Okay we've requested permissions we've got our info.plist set up, now let's set up that location manager and let's set up an initial view of our map. And then we'll make sure that user tracking is working through using that simulated file. So let's do that next. Go back to our code, first thing I going to do is I'm going to go to our storyboard. And what I want to do here is a couple things. I'm going to select on my Map View, over here on the left, and I'm going to go ahead and change this from standard to hybrid. I'd like to be able to see the satellite imagery in addition to the street maps so that I can make sure that everything is working okay. If I just see that street maps, it's going to be a little difficult for me to debug. Now if we go back to our view controller, what we're doing now in this section, is we're setting application manager and the map. All right, so our location manager we haven't even declared a location manager. And so we need to declare that locally. So let me go down here and get some boilerplate code for us. Well it's not boilerplate but it's pre-made code. And this is going to be our location manager. That's going to be a local variable that we keep track of all of our services that we use to get our services. And then we're going to initialize our services in our view controller. So after view did load we're going to set out UI in the appropriate way. We know right here we need our location manager to be initialized so we'll initialize it before that code. So, we'll set up our location manager here. All right, setting up our location manager includes getting a instantiation of the location manager. We want to set the delegate to ourself, meaning that when we get callbacks from our location manager, we want those callbacks to be handled by our code. Unfortunately, though we haven't actually indicated that our code can do any of those things. So up here we'll say CLLocationManagerDelegate and that'll say that this is a class that is able to be a delegate. So now down here when we set this class equal to the deligate we don't have any errors. We're going to tell the location manager to allow background location updates and that has to be mapped by both the permission and the info.plist. We will allow it to pause location updates automatically and so that's a way of reducing power usage on your device. So if it appears that the user is not moving because other sensors like the accelerometer are very steady, then location updates will be slowed down. You won't get them quite so frequently. In practice, it's just a helpful way of reducing battery life. We'll say that we would like the most accuracy possible. Which means that the device will fire up the GPS if it has it. And that we want to know changes of no more than five meters. Actually, I'm going to shrink this a little bit. So what that means is that, if, all other things being equal. Even given the GO region code that limits some of this. I don't want to be told unless our distance has moved more than three meters. So it's a way of being explicit about how often you want updates. Okay, so that gives us our location manager code, and that now enables, right here, enables us to request authorization. This code won't do anything yet but it does initialize everything that we want in it. That was setting up or location manger and our map. I guess the next thing that we want to do actually is before we say our map is completely set up, is we want to put. If you remember from when we used our map view before we had a variable that indicated whether the map was being moved by the user or not. And if it was and we stop updating things temporarily, so lets add the ability to do that as well. So we're going to grab this property and we're just going to create a local variable for a class that's called map is moving. And up here we will say that in the beginning that map is moving equals no. When the map is moving though, we need to set self.map is moving to yes. We need to implement ourselves as a delegate for the maps. Let me see if I can get this. Mk mapviewDelegate. I think that's right. I think that's right typing. Now we need to go to the storyboard, just like right here on our location manager, we say our location manager delegate equals ourself. That says that this object that we created, the location manager, will send its callbacks to this object. We haven't indicated that we want our map view to send its call backs to this class. Instead of doing it in code though, we do the same thing via the storyboard here. And we're going to expand our according. And we're going to select our map view. And we're going to control drag our map view to our view controller and specify that this class is the delegate. All right. So now, what we'll do is override the two functions that indicate that the map is being moved. So that we can set our map as moving variable. That's down here. So we already did that. Grab these two. All right. So in the first case this is our call back function. If the region is about to change, meaning the user has initiated a change to the map, we will get this callback saying hey, we're about to animate, in which case we'll say the map is moving. And when the map is moving, we'll turn off some of our updates, in particular centering the map on location updates. And then, when the user is done moving, we will set our local variable to that region. Region did change to animated, means we're past the change. Map is moving as no now, and we can do the work that we intended to do. All right, the last thing that we want to do for setting up the map is we want to zoom in automatically. Now, we could do this manually every time we moved in. But when this testing, it's gotta be very convenient to have that done for us. I'm getting the beach ball. That's good, right? So we'll add some code here to set up. After we set up the location manager, we will go ahead and zoom the map in very close so that we can see the effects of what we are doing. [SOUND] All right so to do that, we're going to create a coordinate location. We don't actually use it. It's just a dummy variable, and we'll say we want our map generally to be about 500 meters by 500 meters. We'll adjust that region so that, that desired resolution fits within the aspect ratio of our device. Our map viewed is lower case. So fit it in there. And then we'll go ahead and this is the command here. Set region that actually does the zooming. All right so what we set up now if we run this application we should see that our application starts. We should have a map. The map should be in hybrid mode. We should be able to zoom in and zoom around all of our functionality should be disabled until the point at which we're ask permissions. At which point it should be enabled, but if we do anything with the switch, if we do anything else nothing should happen. because we don't have anything like location updates starting or anything like that. So let's run and just make we're doing okay so far. Build succeeded, we love that. Here's our application. Booting up. Great. It's asking, if we would like it to send us notifications. Eventually, we do, so we're going to say, okay. And can it use our location even when we're not using the app? Yeah. That's okay because see here's my reason that I put in the info.plist file. We'll allow that. We're zoomed in, but we happen to be zoomed in on an area of the world that doesn't have a map resolution at that level. So, it's a little wonky. Our UI is a little crazy right now. Not totally thrilled with that. But let's go ahead and keep moving, because it looks okay, enough for now, we're not done, cleaning up later. Right, to the next thing that we want to do is, we want to get to the point where we use that temper that test GTX file that we created, want to make sure that user tracking works in the simulator. So to do that, once we have permission and the user has activated our switch. What we want to do is, we want to turn on location updates, and then we want to center the map on those location updates. So, let's add that code. So for starters, I'm going to come back here to our story board and our toolbar and our bar button item and our view. And the UR switch, and I'm going to start that as being off when we begin, so we start and it's not operating, and we click it in order to activate it. And let's see, anything else I want to do? No, that's good for now. So go back to our view controller. All right, so what we need to capture, is we need to capture the user activating that switch. So, to do that, we need to connect our switch event from our storyboard onto our code, and so we'll drag and drop that over to where do we want to put that function, we'll put it down here after our map we'll put it here. Now, so, I'm going to drag control drag our switch over to this location here. And I'll say, switch capped and that's going to have when the value changes connect that. And then, we need we're going to grab the code that we're interested in that's coming from down here. All right, so, if it changes, then we're going to do the following. And let's see, let's get a little bit more space here. Go back down to where we were. All right, if the switch field is on after it's been changed, then what we want to do is we want to tell the map view that we're going to start showing the user's location. Great. And we're going to tell the location manager that we want to start updating the location. Great. And we don't have a region yet, so that's going to come later, so for the time being we're not going to monitor our region, that would be where we add our geo fence. But we want to go ahead and enable our check-in button, although we're not going to call it check-in button, we're calling it a status check button. After we start tracking, we want our status check button to be enabled. That's so, that we can check whether we're in or out of our region, and then if we turned our switch field off, then we want to do every thing in the reverse. We want our status check. Button to be enabled disabled, and then we want to stop monitoring the region, but we're not doing that yet. We want to stop updating our location, and we want to tell our map view that we are not showing our location. All right, good. And this is not a switch field, that's why we have an error there, called UI switch. All right, so that's good. We're telling our location manager to start updating locations. What that means is, as new locations come in, we will be told that the location has changed. You can go ahead and do something with it. But what do we want to do? We want to plot the location of the current user. In order to do that, we need to show the user on the screen and so, we're going to need to create a local variable which is the annotation the object that we're going to keep on the map that's going to keep track of the user's locations. So let's come down here and grab that, this is code that we don't need. So here is the code for the annotation that we're going to keep track of locally. Great, that is at least a local variable for it. And now what we're going to do is we're going to create a function that will create it, but that doesn't make sense yet. Let's go back up here. So we have a local variable, current annotation, after we've set up, let's see, what do we do. We set up our user interface, so it is disabled until we get permission, we say the map is not moving, we create our location manager, we zoom the map in, we check for permissions. And let's see, before we check for permissions, I'm going to go ahead and create this annotation that we're going to use to keep track of the user's current location. We are going to call a method on ourselves that we haven't written yet, so we're getting an error because of that. But let's go down and that, and to add our current annotation what we're going to do is we're going to create a new annotation. We're going to expatiate it with ala and a nit. And then, we're going to specific it's coordinate. And initially the coordinate will be 0,0,0,0 so the middle of Africa. And we're going to call it my location. This doesn't come into play, so this is just kind of dummy code. That gives us an annotation, all right, so it's great, doesn't put it on the map yet. What we're waiting for is, we're waiting for our location manager to give us call backs, so that we know where to put the user on the map. We know how to change that annotation, and then send it to the map view. So we need to implement the call back functions that the location manager executes on it's delegate, when there are changes to the location. So let's ge those, we've seen this before. All right. So now our location call backs, when the location has been updated, this function will be called. At that point, we want to change the coordinate of our current annotation, which was our local variable, to be equal to the most recent update that's being passed in this array up here. The most recent one is the last one in the list. This is in case, we batch up several changes at once, we just grab the last one. Then we want to indicate, we want to check to make sure our map is not moving. If the user's not moving the map then we're going to want to center it. We're going to want to center it on the current annotation. So far, so good, however we don't have the code to center the map yet. Fortunately, it's right here, just like a cooking show. We've already done that. So a location callback, so we're going to put it up here, since it's not a location callback. So to center the map, what we need to do, we need to find the map view and we want to center it's coordinates on the center point, which is being passed as a parameter, it's coordinate. And we want to animate that. So down here when we pass the annotation, it'll get centered. So, let's see. If I'm not forgetting anything. What we have now is we have an application that when we hit the activation switch, that is going to cause location updates to start flowing in. When location updates start flowing in, we'll get callbacks, and we'll try and center the map on those locations. So if we run it right now, what we're going to see is that nothing happens, because there's no simulated track being passed to the simulator right now. Let's go ahead and do this, good, so far so good. Hit activate, all right, and now there's no location being passed to that phone, the phone doesn't have any simulator location. Now, in the past, we have come up here, and we have done debug, and we changed location, and we've specified something like freeway drive. And this is the built in GPX file, for example, that drives around Apple somewhere in the Bay Area of California. There we go, so this shows a track of someone driving on the freeway. That's fine, and we could use that if we wanted for our testing, but I want to use the specific track that I already set up. So this is how we do that. If you'll recall, we want to make sure that user tracking works, and so we need to import the track we created, and then simulate and test that. So let's go back to our code and do that. All right, we'll let this run for a second. The place where we go to do that is not within the simulator, surprisingly. We've come down here to this little location arrow, and we select it. And what we can do is we can select any of these locations. If we want our phone to be in London, England, we can select London, England. And then if we go back to our simulator, we see that our Xcode has overrided the location being provided by the simulator and is forcing our phone to think that it's in London, England. That's good if you want to test London, England. It happens to be a single point, it doesn't move. So if we come back here to Xcode, and we select our location icon, we can add a GPX file to the project. And so this, I'm going to add that GPX file that I created during the previous lecture. Stored on my desktop, it's called trace.gpx. It's going to actually bring it in as a resource to my project. I'm going to go ahead and just add it, and right. All right, so now you can see it shows up, up here. I can click on it and use it. And then down here on my arrow, I now have that as an option for the route that I want to take. Now if I was clever, I might call it something more meaningful than trace, but I'm just going to click on trace. And now, when we go back to our simulator, you can see that, there we are, next to the ballpark. And you can see that the simulated location is moving from next to the baseball field, along the path that I indicated, at the rate that's necessary so that it will arrive at each point at the right number of seconds or minutes after the previous point. So we can follow this for a little bit. Let's just follow it until it turns the corner. To turn a corner and start going north after it gets right about here. Let's see. To me, it looks almost like it puts a little bit of artificial error into that point, as if it's shifting around a little bit when it doesn't need to be. And that's good for simulation, because that's how real location data works. And it's not moving very fast, that kind of surprises me. Maybe I have an error in my trace function, let's go take a look at it real quick. There we go. Just a little slower than I expected. All right. So that is making sure that user tracking is working. We imported the track, we simulated and tested it. So the next thing that we need to do is we need to do this Geo-Region stuff that we've been talking about all along, okay? Thank you. [MUSIC]

Explore our Catalog

Join for free and get personalized recommendations, updates and offers.