SUMIT LONKAR: Good afternoon, everyone.
Welcome to Session 206.
This is What's New In the MapKit.
My name is Sumit Lonkar.
I am a software engineer on the Maps team.
So, we have got a jam-packed session for you this afternoon.
So without further ado, let's get started.
Before we begin, first take a look
at today's session's agenda.
Our first topic of today is going to be improvements
to existing MapKit API.
Here, I will mainly talk about new features --
sorry, here, I'll mainly talk about our new APIs that we added
to support our existing features.
After that, I'll talk about Transit and we'll mainly focus
on Transit in MapKit's perspective.
And finally we will have a Flyover.
Flyover is a brand new MapType to MapKit.
It's been available to iOS applications since iOS 6,
and now we are bringing it to you guys.
And along with this topic we will have various demos for you.
So you can see all these newly added API in action.
So with that outline, let's jump right
into our first topic today, Improvements to Existing API.
Based on comments and requests from developers like you,
this year we have taken some serious effort to make sure
that you and your application get best out of MapKit.
These newly added API will help you
to customize your MapKit experience in your application
as well as enable great user experience, and for developers
like you, it means way less code on your side.
So, let's look at these API one by one.
To start with, Pin Color Customization.
So, MapKit pins, are also known as MKAnnotationView,
has been an integral part of MapKit since the very beginning.
They provide very concrete behavior
to denote any singular point on a map.
And when it comes to customization,
there is not much you can do about with them.
So, you can make them red or you can make them green.
And that's it.
That's all you get, all you get is only three choices.
And it's been like that since iOS 3.
And now we are bringing you a new API
that lets you customize this.
So we are introducing it as a property
on MKPinAnnotationView, called pinTintColor.
On iOS it takes UIColor and on OS X it takes NSColor.
Now, as underneath, it's UIColor and NSColor,
that means you have millions of different colors
that you can put on your Map.
I would like to take this opportunity to point
out that we are deprecating our old API called pinColor.
So, if your application is using this API,
make sure that you update it to the new API
that we are providing.
That's all about Pin Color Customization.
Let's move on to go to Callout Customization.
And before we dive into callouts, I'll first take
up some time to talk about callout.
For those who have been using it for a long time,
it is just going to be a refresher course.
So, what is this callout, the callout is the white bubble
that pops up when you tap on an annotation.
Primarily it has four different components.
One, the title.
Second, you get a subtitle that goes right below the title,
and you have a right accessory view and a left accessory view.
Normally, these four components are good enough
to provide us enough, good enough to give a little bit
of information about the point
or the coordinate they are representing,
but the problem arises when the content size increases.
For example, in this callout, all right,
in this callout you can see the subtitle is getting clipped
at one point.
So what do you have to do to customize these callouts
to fit your application needs?
Well, it turns out, there are a couple of work-arounds
that developers have been trying.
Sometimes they run into issues, like, to start with,
we have something like this in a map view
where you tap -- a maps application.
So, when you tap on annotations you get a POI
and a callout with a Yelp review.
And in order to implement a similar kind
of behavior we have seen developers do something
like this, where they put Emojis in their subtitle.
I mean, it's fine for something like this.
But what happens when you go implement something complex
Well, it turns out it is not a good solution.
And in order to solve this problem we are introducing a new
way, in terms of a property that will help you
to customize the callout.
The property we are introducing is called
On iOS it takes a UIView, and on OS X it takes NSView.
Again, it's a UIView and NSView.
That means you can customize it to a greater length.
So, even if you want to use, like, a --
you can do it and it will open up the endless possibilities
of customizing these callouts.
Again, these callouts support auto layout,
right to left languages.
That means everything is in there for you,
and all you need is one single line of code.
Let's quickly take a look at a sample code
and how one would use it in their application.
So, here, I have a callback method that gets fired
when you tap on an annotation.
I'll start off with just setting
up detailCalloutAccessory property,
detailCalloutAccessoryView property to be a UIImageView.
As you can see I'm just placing an image of the Taj Mahal
in that callout, and that's it, that's all you need to do
to customize this callout.
Isn't that great?
As I mentioned earlier, it is just a UIView and NSView.
We are really excited to give it out to you guys
and see what you guys can achieve with this thing.
Hopefully we will see those results coming soon.
So that's all about Callout Customization.
Let's move on to Map Customizations.
In this particular topic we will be talking about new handy APIs
that will let you control what goes on your Map View.
Like, you have a map unit inside your application,
how can you control the content of this Map View?
These APIs have been available to maps applications
for a couple of years now
and now we are bringing it to you guys.
Let's start off with traffic.
Now you have an ability to show any high traffic
on your Map View and all you have to do is put a flag, like,
set a flag on the Map View called showsTraffic.
Similar to the traffic, we're also providing a way
to show or hide a scale.
So you can either show or hide a scale
in your left top corner of your Map View.
And similar to a scale, you can also show and hide compass.
You might have noticed that these APIs are very similar
to our existing APIs
like showsPointsOfInterest or showsBuildings.
We believe with the use of these APIs, you will be able
to customize Map View inside your application
and provide a great user experience.
So that's Map Customization.
Other than maps, other than these APIs we talked about,
we have various other improvements to MapKit as well.
First of all, a time zone support.
We have added a time zones property on our MK map item.
You can use that property to get the associated time zone.
You can use it with CLGeocoder.
So you can find out a time zone associated
with a particular coordinate.
Or you can also use it with MKLocalSearch, so,
you can search an area for a point of interest or anything
that you would like to search.
And you can find out a time zone associated with that.
Besides that, we have also done various improvements to MapKit
for better Swift compatibility,
and we also added a WatchKit support
to launch maps applications on your watch
from your own application.
So that's it, so that's all the improvements that we have done
to existing features in MapKit.
Let's move on to the next topic
and personal favorite of mine, Transit.
We were pretty excited about yesterday's keynote,
with the moment we announced the new feature
for maps application Transit.
And today we will mainly focus on what it means to MapKit.
We have worked really hard on this feature.
And while designing this feature we kept our user at the center
of the development process.
And in order to provide a similar kind of experience
in your application, we would like you
to leverage maps application to provide a similar experience.
And the way we are going to do that is
by providing you a distinct entry point
to a Maps Transit feature.
Let's look at this point one by one.
First one, ability to request a Transit ETA.
If you use MKDirections protocol, MKDirections class
and related APIs before, then you know, you might be aware
of these two TransportType that we already support,
automobile and walking.
You can request directions and ETAs
for these two transport types.
And this year we are adding a new TransportType,
With this TransportType, you will be able to request ETAs.
And I would like to point it out, you will only,
as of now you will only request ETAs for Transit.
You won't get a Transit direction.
So, let's see how you can --
before we move on to a sample code, let's see how you can,
what you get besides ETA.
Well, you get expected arrival timing
and expected departure timing.
Given the frequency, given the nature of the frequency
of our transit varies based on the time of the day and a place,
it is really important that we provide this information.
We believe with this information, you will be able
to give out a great user experience
to your application user base.
Let's take a look at a sample code,
how can we request these Transit ETAs.
Here, I have a helper function called getTransitETA.
So, I'll start off with creating an MKDirectionsRequest.
After that I'll set a source and a destination on it,
and once I have that, I'll set our transport type to be Transit
because we are interested in getting our Transit ETA.
Once, after that I will create MKDirections object using the
request that we just created, and I'll call it calculate ETA
With Completion Handler on that direction object,
and in CompletionHandler I will handle the response
that is coming back from the server.
So, that's a Transit ETA.
Now, once we have the Transit ETA,
in order to provide a complete experience we are giving you a
way to launch maps applications into a Transit mode.
As of now you can launch maps using various different launch
options on a map, along with a map item,
and the MKLaunchOptionsDirectionsModeKey
helps you to point out which maps application mode you would
like to launch in.
So as of now, we are supporting a Driving mode
and a Walking mode, and now
with iOS 9 we are also introducing a Transit mode.
By using this mode, you will be able to launch maps application
from your application.
Let's quickly take a look at a sample code here.
So, here, I have a helper function called
openInMapsTransit, which takes a coordinate.
And I will just basically start off with creating an MK map item
with that parsing coordinate.
After that I'll create a dictionary launch options
with the mode set to be Transit.
And once I have that, all I have
to do is call openInMapsWithLaunchOptions
on that map item.
It will basically launch our maps application in Transit mode
with the mapped item to be a destination.
So that is enough of our talking.
Let's see all these APIs in action.
So for this demo purpose I have created a city tour application
for San Francisco.
It is basically just a simple map view
with various different annotations in it.
I'm just going to quickly run it
so you can see what I have so far.
So, as you can see, we have a map of San Francisco
and I plotted various different annotations with the landmarks,
like we have Sutro Tower over here,
we have Golden Gate bridge, and all that,
and I have also taken the liberty
to set the pin colors on these.
So if I scroll down to the viewForAnnotation callback,
you can see I have set in a pin tint color property
to customize these pin colors.
This is okay.
As the demo progresses we will try
to customize this more and more.
To begin with, what I'm going to do is I'm going
to add a Transit ETA into a subtitle.
So in order to do so I have created a simple
I am going to drag and drop that in here.
So I have this helper function
that basically takes our annotation,
which is a landmark class for local object.
And then I will create a MKDirectionsRequest in there.
So you can see I have created an MKDirectionsRequest.
After that I'm just setting a source
and a destination on that request.
And finally I'm setting a transport type to be Transit
because we are interested in a Transit ETA.
Once I have that, I'm going to go
and create an MKDirections object.
So in here I have created an MKDirections object using the
request and in CompletionHandler I'm just setting an
annotation.subtitle to be our estimated time of arrival.
And I am quickly going to call this function before I drop my
annotation on a map view.
So let's call that function here LandMarkPin.
So, all right, let's run it.
There we go, so city hall is about 22 minutes
from Moscone West by using a public transport.
Let's check out some other pins.
Ferry Building, it's 17 minutes.
So this is nice.
I mean, this gives initial information to your user
like how long will it take to go
to this destination using Transit, but in order
to provide a complete Transit experience we have to find
out a way to bring them to a maps application.
And for this demo purpose, what I am going to do is,
I'm going to put a right callout accessory view on my callout,
and when I tap it, I will take the user to a maps application.
So we quickly stop it, and let's go back to our callback method.
And in here I am going to set a rightCalloutAccessoryView
on my AnnotationView.
I added my rightCalloutAccessoryView.
Let's run it.
So you can see a right callout accessory view.
We have added a bus icon here.
Nothing is happening because we haven't implemented the callback
method that gets called every single time a callout accessory
control is tapped.
So let's quickly go and add that method down here.
So this is the callback method
that gets called every time a callout control accessory
Once I have this, I am going to add my code
to launch a given map item into a maps application.
So here I start off with creating a dictionary object
with the mode Key, and the mode key set to be Transit.
After that by getting a coordinate
from the past annotation I'm going to create an MKMapItem.
And once I have that, I am going to use open in launch options
on mapItem to launch this map item into a Transit mode.
Let's quickly go ahead and run our application again.
Let's see, Ferry Building.
Tap on it and there we go.
We have a maps application into a Transit mode
and you can see it takes 18 minutes by bus number 40.
And let's go back to our sample app again
and try something else.
Let's see if we got a response for Sutro.
Yeah, there we go.
That's our response.
Again 45 minutes by Transit.
That's fairly long.
Oh, I see.
It is something wrong.
Oh, bus stops moved, so probably that's the reason, long time.
Anyway, that's a Transit experience in a MapKit.
Now I would like to talk about how we previously talked
about the callout customization.
Now let's go and see how can we use those callouts
in this, our sample app.
So, again, we are going to go back to our callback method
that gets called every single time the annotation is tapped.
And down here I'm just going
to set a detailed callout accessory property on this view.
For the data that I'm getting
for these landmarks I have some of the images.
So let's set a UIImageView in a detailCallout
and see how they look in our annotation.
So, here I'm just reading my image data,
I'm reading my image name from a plist that I'm parsing,
and then I'm creating a UIImage,
and after that I'm creating a UIImageView and setting it
on a detailCalloutAccessoryView.
So let's run this thing.
Okay. All right.
So I think I have an image for Golden Gate Bridge.
So let's go and take a look at it.
So there we go.
That's a nice image of the Golden Gate Bridge.
Let's see what else I have.
I have the Ferry Building as well.
Okay, that's current location.
Okay. So, Transamerica Pyramid doesn't have a,
Transamerica Pyramid doesn't have an image.
So you can see when we set a detail callout accessory view
on a callout, a detail callout accessory,
we will always get precedence or a subtitle.
For Golden Gate Bridge we did add a detail,
we did have a subtitle,
but as soon as we set a detail callout accessory view on it,
it got a precedence or a subtitle.
So, for some of these other landmarks, I don't have images.
So, let's add text in there.
So, I have also created a text view that will --
so here I have a custom text view
that basically I just have set some height and weight on it.
And that will allow me to show the content
in our detail callout accessory view.
Similar to the images, I'm reading data from my plist
that I have been using to plot these landmarks.
I just set it that detailTextView
to be a detailCalloutAccessoryView.
So I'm quickly going to run it again.
Okay. All right.
So let's see.
As you can see now we have a nice text view down here
in Sutro Tower callout.
Let's check on something else.
Same thing, for City Hall we also have a nice text.
So here I have like a one callout with a subtitle,
one callout with a UIImageView and one callout with a TextView.
That's all the beauty of this API.
We are really excited to offer it to you and I am damn sure
that you guys will come up with something amazing.
So what we learn from this demo,
we learn how we can customize our pin colors,
we learn how we can customize our callouts.
We also learn how to request Transit ETAs
and we also learn how to bring users to a maps application
to provide a rich transit experience.
That's all from my end.
To talk about Flyover, I would like to call upon Elisabeth.
ELISABETH LINDKVIST: Okay.
Right, let's talk about Flyover.
My name is Elisabeth Lindkvist,
and I'm also an engineer on the maps team.
And these are the things
that I will be talking to you about today.
So, first of all, what is Flyover?
How will it work in your application?
How do you set the right region and handle the camera
when you are using Flyover?
And I will also discuss how Flyover will work together
with some of our existing MapKit API.
But to start with, what do we actually mean by Flyover?
For example, this is Flyover.
It's photo-realistic 3D models of various cities and landmarks.
They are available in many different places all
around the world.
And they have been available
in the maps application since iOS 6.
And we are now giving you the opportunity
to show these interactive 3D views to your users.
As you might have noticed in the maps application
where satellite imagery is not available you will instead see
flat satellite imagery being displayed on top
of a 3D height map which represents the terrain.
And this will also be the case in your apps.
Another important aspect of Flyover is this:
it is being displayed on a globe rather than being projected
into 2D like our other map types are.
This one has some implications
for how you handle your region setting.
And this is something that I will be returning to shortly.
So, what do you need to do
to get a Flyover view in your application?
If you used MapKit before, I'm sure you are familiar
with MK map type, which is the property you set
on an MK map view, in order to choose which type
of data you will be displaying.
We have standard, which is a regular map.
We have satellite, which is a top-down satellite view.
And we have hybrid, which adds things like roads and labels
and points of interest to the satellite view.
And we are now introducing two new map types,
Satellite Flyover and Hybrid Flyover.
So in order to display something like this in your app,
what you would do is just set the map type
of your map view to Satellite Flyover.
If you want to add things such as labels, points of interest,
roads, and borders, you would instead use the Hybrid Flyover
Now, as I mentioned, there are some things you really need
to consider when using Flyover.
One of the most important ones is how you set the visible
region of your map.
You might be familiar with the several methods in MapKit
that use rectangles such as MKCoordinateRegion and MKMapRect
in order to set and get the visible region of your map.
However, the visible area
of your map view is not always a rectangle.
In iOS 7 we introduced the possibility
to view a pitched map view
where you are viewing the map at an angle.
And when you do that,
the visible area will not actually be a perfect rectangle,
and this will also be the case in Flyover
as you can view pitched map views there as well.
Now, if we take a look at this region and zoom
out a bit we can see the actual shape of the visible area.
And what we do in this case is
that we define the visible region of this map
as the rectangle which is enclosing what you are actually
seeing on screen.
So it will be the blue rectangle in this case.
And this will work exactly in the same way in Flyover.
The visible region will be defined as the rectangle
that is enclosing whatever you see on screen.
Now, in Flyover, a view does not necessarily have to be pitched
in order to not be rectangular.
If you have a region such as this, which is fairly large,
and you try to set the visible region to the blue rectangle
in this case you end up with something like this.
And the point here is
that a rectangular representation will always be an
approximation since Flyover is being shown on a globe.
And, also, if you have a very large region there will be some
areas that are not actually displayed.
So, in this case, parts
of the visible region are actually behind the globe.
So, the recommended way, even though there are some cases
where rectangular region setting works just fine in Flyover
and with pitched map views, for example,
if you have a top-down view where if you're very zoomed in,
the recommended way to make sure
that you are really displaying exactly the part
of the world you want to is to use MKMapCamera.
MKMapCamera was also introduced in iOS 7 in 2013.
And for more detailed information about MKMapCamera,
and also about region setting in general, I really recommend
that you check out Putting MapKit in Perspective,
which is a talk from 2013.
But I will briefly recap a bit about MKMapCamera.
It has four basic properties.
The center coordinate, which is the position in the world
that you want to be shown in the middle of your screen.
The heading which is the direction the camera will be
The pitch, how tilted the view is,
at what angle you are looking at the map, and the altitude,
which is the height in meters above the map
where you want your camera to be positioned.
There is also a convenience initializer for MKMapCamera,
which takes the center coordinates
and the eye coordinates, where you want the camera
to be positioned, and the eye altitude,
how high up you want the camera to be,
and gives you back the camera which is looking
at that center coordinate from the eye coordinate.
So, however, in Flyover there is terrain and buildings
and all other sorts of interesting things.
And that means that the altitude is actually not
as straightforward as you might think.
For example, is it the height above the buildings?
The height above the terrain?
Or some sort of sea level?
So instead the distance between the center coordinates
and the camera is actually a much better measure
for this case.
And this is where we're adding a new initializer to MKMapCamera.
And let me go through quickly what this does.
You will start with the center coordinates,
the position you want to be in the middle of the screen.
And you will then specify a distance in meters, how far away
from the center coordinate you want the camera
to be positioned.
And notice how this differs from the altitude.
You will also specify the pitch, how angled you want the camera
to be, and the heading,
the direction you want to be looking in.
And using this initializer you can get a camera
which is looking precisely where you want to without having
to worry about what sort of terrain or buildings happens
to be beneath your camera.
And I will now give a short demo to show some
of the cool things you can do with Flyover.
Okay. So Sumit was showing you a tour application earlier.
And I have a similar application here running on my Mac.
You can see the landmarks here.
For example here, Cliff House.
And as you might remember there were some of these locations
that we did not actually have any images for.
And I thought we could use Flyover
in order to correct that.
So what I will be doing is,
that I will be adding a detail callout accessory views
to my callouts here.
And I will use the MKMap snapshot in order
to generate images from Flyover, to set as the image
of the detail callout accessory view.
The MKMap snapshot is very useful
when you only really need a static image of a map,
when you don't need it to be interactive.
So I'm going to add a few options for the snapshotter,
and the most important one here being
that I'm setting the mapType to Satellite Flyover.
I will then create an MKMapCamera using our new
initializer to look at the coordinates of the annotation.
And I will then use these options
to create an MKMap snapshotter.
I'll start the snapshotter and if it completes
without any error, I will use the resulting image as the image
on my detail callout accessory view.
Let's of course, call this function.
Okay. Let's take a look at what it looks like now.
So if I recall correctly, Cliff House was one of those
that we didn't have an image for.
And look at that, now we do.
ELISABETH LINDKVIST: And yeah,
I think we have a few other ones here.
Like City Hall, for example.
Now, that's was pretty cool, but Flyover views are
of course also interactive,
so I'm thinking we can add a little animation to this view.
And I created a new ViewController
which doesn't really do much yet but it has an MKMapView.
And I will add some constants that I think will be useful.
And then I will set up the map view.
And so as we can note here I'm also setting my map type
to Satellite Flyover.
I'm hiding the compass and the zoom controls
that are visible in OS X.
I'm also creating an MKMapCamera which initially looks
at the coordinates of the landmark.
And that's about all the setup I need.
Then I'm going to create a couple
of additionally MKMapCameras.
First of all I have one which is a bit tilted down,
my pitched camera.
And I'm also adding a rotation here.
So it will do a little spin around.
And as MKMapCamera is an animatable property
in MKMapView, I will do a little animation in order
to switch between these.
So here I am adding first a little short animation
which will set the camera to my pitched camera,
and we will tilt the view down a bit,
and I am then adding a little longer animation
which will do a little spin around.
In my main View Controller I have added a little right
callout accessory view here
which will open my new View Controller.
So let's add that button as well.
Okay. Let's take another look at Cliff House.
There we go.
And I have my little button here, and we are tilting down.
And spinning around.
This was fun.
We'll just look at this one, too,
because I think it looks really cool.
There we go.
Transamerica Pyramid, too.
Okay. So now we have seen some of the things
that you can do with Flyover.
So let's get back to the presentation.
As I said at the beginning there are also some parts
of the existing MapKit API that I would like to talk about,
how they would work together with Flyover.
And I'll start with MK annotations.
MK annotations are used to annotate a single coordinate
of the map and the most common use case is the pins
that we have been working with today.
If you are showing buildings on the standard map type,
annotations will be placed on top of those.
And this will also be the case
when you are using the Flyover map types.
Annotations will be placed on top of any buildings, trees,
large boats, statues, whatever you may find
when you are exploring Flyover.
And next, MKOverlays.
Overlays are used to highlight areas of the map rather
than just a single coordinate.
And if you are showing buildings on a 3D map
in the standard map type, you will notice
that overlays are being occluded by the buildings.
This will work precisely in the same way in Flyover.
Any overlays you have will be occluded
by Flyover buildings and trees.
Something like that.
However, overlays will be drawn on top of the terrain
so that they will follow the ground.
Something like that.
So I think that's about everything you need to know
in order to get started with using Flyover in your apps
and I can't wait to see what you will be doing with it.
To summarize a bit what we have been talking about today,
we have added some new ways for you to customize your pins,
your callouts, and the way you display your map with traffic,
and compass, and scale.
We've added Transit ETA requests and ways for you to launch
into the maps apps to show Transit directions.
And we've also added the Satellite Flyover
and Hybrid Flyover map types
so that you can show photo-realistic 3D models
and satellite imagery on terrain in your apps.
For more information, please take a look
at the MapKit documentation and the Developer Forums.
Thank you so much for coming.
Looking for something specific? Enter a topic above and jump straight to the good stuff.
An error occurred when submitting your query. Please check your Internet connection and try again.