Hey hey hey everybody this is Caleb with Dev's Loeb's dot com.
And in this awesome video we're going to request location services and I'm going to show you what is
new in Iowa 11 forgetting the user's location.
There are some things that have changed.
Some things you need to know about that are really important to ensure that your app gets approved on
the App Store.
If you're using these skills for an app that you're going to release this one as well we're going to
teach you best practices to make sure that you know what is new and what is up.
So open your X called Project and let's get started requesting location services.
So to do this we're going to need to go into map B.c.
And of course to get location we're going to need to import the Core Location frameworks so go ahead
and type import Core Location and that looks great.
And now what we need to do is we need to create an instance of a C-L location manager.
OK that's what we're going to use to manage locations of course see a location manager makes sense that
it manages locations.
So above view did load go Hedden type var location manager whoops capital M and we're going to set it
to be equal to see location manager and we're going to instantiate it from the get go.
All right.
Now similarly to our map view we need to also set the delegate of our location manager.
So go ahead and type location manager dot delegate equals self OK.
And if you build and run this you'll notice it says cannot assign value of map b c to see location manager
or delegate.
The reason for that is because we have not conformed to it like we have MKM that you delegate.
So go ahead and do that by creating another extension called extension Matthysse.
And it's going to conform to C-L location manager delegate and give it some curly braces.
So as soon as you do that you'll notice that the error goes away.
This also means that there are no required methods to conform to cel location manager delegate.
Unlike you I table view or collection view there are some required methods that you conform to but there
are none foresee allocation managers delegate.
We're going to add some though so that we can actually have an app that works because you know that's
important or whatever.
Now it's totally important anyway.
So in our extension we're going to use one of the given functions but we're also going to create one
of our own.
So we're going to go ahead and we're going to basically write a function of our own first called configure
location services.
And inside this function might give us some space here so we can see stuff awesome inside this function
we're basically going to check to see is our app authorized to grab our location.
If not it's going to go ahead and request those services.
If it is it's just going to return.
OK so it's a way to check to see if we are authorized to use our location.
But you know what we need to actually create a variable that's going to keep track of our authorization
status.
So to do that.
Go ahead.
It's actually going to be a constant.
So go ahead untyped let off rise zation status equals a location manager dot wups authorization.
Okay.
Sorry I can't type C-L location manager.
Authorization status if you option click on that you'll see.
This is a function from the location manager that returns C-L location authorization status.
Okay and if you pull that up in the help docs you'll notice that it is of type in 32 the number but
basically these are constants that indicate whether the app is authorized to use location services.
OK.
So authorization status is there and it's going to be checking to see if we're authorized or not.
So what we're going to do is we're first going to check to see if our authorization status is not determined.
That's the name of one of the authorization statuses.
So go ahead and type if authorization status is not determined.
Meaning if the app doesn't know if it's approved or denied.
We're going to go ahead and we're going to call location manager.
That request always authorization.
This is going to request authorization so that our location is used always whether the app is open or
not.
OK then we're going to say else meaning if it is determined maybe it's denied maybe it's approved for
when in use authorization we're going to go ahead and just return right because if we already are approved
or already are denied there's no need to do anything else.
We can just return.
So that's how we're going to configure location services.
All right.
Very very cool.
And now what we need to do is we need to call this function to run as soon as the view loads.
So it's going to check to see if if we're good to go.
So call it from view did load configure location services.
And let's go ahead and build and run it to see if it works.
Very cool.
Where did we go.
There it is.
OK.
And it looks like it's not working but check out the terminal here.
It says the apps info up the list must contain both and s location always.
And when in use usage description and as location when in use usage description keys with string values
explaining to the user how the app uses this data Apple is huge on privacy.
So we've got to make sure we explain to the user exactly how we're using their data.
So to do this go ahead and go to info's up the list and down at the bottom if you hover over the bottom
and you see the plus and minus that pop up click on the plus and type privacy and then scroll down to
find location.
And we're going to go ahead and we need to use location always usage description which I'll pull this
open so you can see that location always usage description and do another one here click.
Plus privacy location.
When in use usage description and then furthermore we need another one and I actually copy it from here
and that's location always and when in use the usage description that's a mouthful.
I'm going to copy that and paste that in here because in X code beta it's not yet working.
So you actually need to paste in this long name.
It doesn't look nice and pretty like this.
Now the thing is for all three of these we can use the same description but we need to use all three
of them because in iOS 11 Apple has changed location services work instead of only showing when in use
or always use or do not allow it forever it's basically been you can show one or the other or at different
times.
It's been a mess.
But Apple is basically wanting their apps to be more user centric.
The user is completely in control of how their data is used.
Like it says.
So when this pops up it's going to give the user three options when in use.
Always in use or disallow instead of one or the other at different times based on the context so we're
going to give the user the choice to decide which is kind of cool.
So in order to do this we're going to say this app requires your location to pull photos from flicker
which we are using.
We should put a period at the end because that's a sentence we are going to use that so go ahead and
copy this.
Paste it here and then paste it here for all three of these keys and values.
OK we're going to just save it like that.
And now that that's done we should be able to request authorization.
So go ahead and build and run this one more time.
Pull open your simulator and let's see if it requests our location suite.
All right so it pulls it up.
This is great.
And it gives us the choice only while using the app always allow or don't allow the click always allow.
And as soon as you do that you'll notice my location pops up right there on the map.
That's exactly what we wanted.
But we're a little bit too far out here we can't really see anything that's going on on the map.
So we need to actually write a function now that's going to zoom us in.
OK we're going to call it Center map on user location and basically what it's going to do is we're going
to set a region that is about 1000 meters around where the user is and we're going to zoom the map in
to show that whole region.
Pretty cool.
So to do that we're going to actually write this function in M-K map view delegates.
It has to do with the map view and so let's do that.
Let's write phunk center map on user location give it some curly brackets there.
That looks awesome.
And now we're going to do in order to center this on the user's location is we're going to need to create
a constant for the coordinate.
Right.
So on our map view there's a coordinate here where this pin has been dropped.
The only issue is that sometimes the location manager might be a little bit slower or faster when the
app opens.
So we're actually going to safely create a constant using a guard.
Let k this make sure that there is a value of the coordinates.
Otherwise it just returns.
So if it doesn't work the first time it's going to just return.
And then as soon as the map view starts updating the location we can call it the center which is pretty
cool.
So go ahead and type guard let cord in it and this is going to be equal to location manager and the
location manager we can get the location right.
So that's where the blue dot is where it's showing up.
And then we can get the coordinates from that.
OK.
Very cool.
Now for a guard let.
We need to put.
Else at the end meaning if there is no value here what we're going to do happens inside these brackets.
And we're just going to return.
Meaning we're going to exit out of this function until it can be called later when there definitely
is a value.
OK so this is basically a guard lead and this is a constant that we can use.
So assuming there's a value assuming coordinate comes back something other than nyl we're going to create
a coordinate region.
So go ahead and type let coord in that region.
And this is going to be equal to M-K coordinate region which you can see right here.
Now if I put a parentheses here you can see that a co-ordinate region has a center which hint hint it's
going to be the blue dot and it has a span.
So the center of course is going to be the coordinate as you would expect.
And the M.K. coordinates span.
If I press enter here and then option click you can see that this comes from map kit geometry and basically
the span is where we're going to set how wide we want our region to be how big.
And in order to keep track of that we're actually going to just set a constant of the radius that we
want this region to be.
And so what I'm going to do is actually up here at the tippy top.
I'm going to go ahead and create a constant called region radius.
Now bear in mind this needs to be of type double and we're going to set that to be equal to 1000 meaning
1000 meters.
That way we can set a region that is 1000 meters wide 1000 meters tall.
We're basically creating a circle around our user.
So with our region radius in place go ahead and scroll back down to M-K coordinates span and the M.K.
coordinates span is going to basically allow us to set how far of a radius we want our map view to be.
So go ahead.
At the end of M-K coordinates spand type dot net.
And you'll notice that there is.
It's asking for a latitude Delta and a longitude Delta.
OK.
So let's go ahead and delete that.
And now the latitude Delta is going to be the amount of change over the map.
So we're going to have it basically go from one point plus a thousand k so we can just go ahead and
type region radius OK and then we're going to do longit to delta of region radius as well.
OK so that's cool our coordinate coordinate region is set.
And now what we need to do is we need to basically just ask the map view to set that region type map
do you set region passen coordinate region.
And we want it to be animated.
OK.
Easy is that.
So our co-ordinate region is now done.
We're setting this region on our map view and this way it should be able to go ahead and zoom in nicely
right to where the user is with about 1000 meter radius around the user.
So now we just need to know where to call this to center the map on the user's location.
And that's actually going to be a part of C-L location manager delegate.
So in order to do that we're going to call one of the built in functions called did change.
Oh whoops.
I probably should call location manager and then let's type authorization did change.
OK.
So this function here did change authorization status is called any time the map view changes authorization.
So with that in mind if suddenly our map view gets approved right if we approve when in use location
services we want to center the map it's not the action center map on user location whenever we approve
it.
It's going to center on the user.
And that's actually why we use the guard let when we press the authorization.
If the map for some reason was not yet loaded it would try to zoom in and it would crash because it
doesn't have a coordinate.
But we use the guard left to return just in case we're being very safe programmers and that's one of
the wonderful things about Swift is that you can do that.
So let's build and run.
Let's see if this actually does center properly like we want credit we go it built.
And let's take a look.
How are we going to crash was that it says Invalid region center.
OK that's good.
And the span is a thousand.
Let's take a look why.
Interesting.
We have an M-K coordinate region and the span is good.
OK let's you know what let's Oh I think I know what's wrong.
OK.
M-K coordinate region.
There's another one called with make with distance.
Yes.
OK.
This is exactly right.
Sorry guys I should have shown you this from the get go.
M-K coordinate region make with distance allows you to use a distance length instead of a circular region.
That's what I'm trying to do is to set a distance meaning a thousand meters in all directions longitudinally
and latitude.
I think those are real words anyway.
So go ahead and pass in that coordinate coordinate.
Sorry guys coordinate not to coordinate region.
Now the latitudinal meters is going to be region radius.
But remember this is just one way.
So we actually need to multiply it by two in order to get 1000 thousand meters on the left and the right
side of us and then let's do that again for the distance the other way.
Region radius times 2.0.
Now we have a region radius going 1000 this way and that way and this way in that way north east south
and west and all around.
Let's try this one more time.
Let's go ahead and build and run this.
And let's check to see if it can properly set our region and zoom in.
All right look at that.
It centered us right on our little dot and we have about 1000 meters on either side top to bottom.
That's our little radius here that we're paying attention to.
Super super cool.
Looks like it's zooming in perfectly.
The only thing is we now need to set it so that this button when we click the center button it should
center our location back down to the middle.
OK.
That is the only thing.
And to do that we're going to actually go into our action we created centerman button was pressed and
we're going to check against the authorization status just like we did before.
So go ahead and type if author status is equal to authorized always Or you can use the two straight
straight slashes.
I don't know what else to call them or authorization status is equal to when in use.
So if it's authorized in any way we're going to go ahead and center the map on the user location.
OK.
Now let's try and build and run this and let's double check to make sure that that works.
And then we're going to go ahead and move on to the next video.
OK so we zoom in.
That's lovely.
Looks good.
Let's go ahead and move the map and if I clicked this it should zoom.
Yeah there we go.
It works.
It zooms in centers us.
You might be noticing this looks a little messed up and I think that's just because I'm using the iPhone
6 or iPhone 7 plus and I'm a little bit zoomed out if I zoom in.
It looks a lot better.
So when I click it it animates and it zooms right to the center that's super super cool.
All right.
So this works this is wonderful.
In this video we have set it up so that we can get location services.
We've given the user the power to choose always when in use or disallow.
And we've also centered the map on the user's location using both a delegate method and the center map
button.
So very awesome.
In the next video we're going to add a UI tap gesture recognizer so we can drop a pin exactly where
we want on our map you see over there.