Getting started with MapKit for iOS
This tutorial explains how install and setup MapKit library and create a map with a placemark for a specific location.
Step 1. Get the MapKit API key
Before you can use MapKit SDK in your application, you need the API key.
Go to the Mappable Account and register a new account or log in to an existing. The main page will display a key that is suitable for any Mappable service.
Step 2. Add the MapKit library to your project
Use CocoaPods to add the library to the project.
-
Go to the directory with the Xcode project.
-
Create the Podfile to list dependencies from other libraries:
pod init
-
Open the Podfile in a text editor and add a dependency for your target:
use_frameworks! # The lite library only contains the map, traffic layer, # LocationManager, and UserLocationLayer # and lets you download offline maps (in the paid version only). pod 'MappableMobile', '1.1.0-lite' # The full library supplements lite version features with car routing, # bike routing, pedestrian routing, and public transport routing, # search, suggest, geocoding, and panorama display. # pod 'MappableMobile', '1.1.0-full'
-
Run the following command in the project directory:
pod install
To open the project file, run the following command:
open *.xcworkspace
Step 3. Provide the API key to MapKit
The MapKit SDK requires you to set up the API key in the MMKMapKit(Factory).setApiKey method.
Set your API key in the application(_:didFinishLaunchingWithOptions:)
method of the application delegate and instantiate the MMKMapKit
object:
func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?
) -> Bool {
MMKMapKit.setApiKey("Your API key")
MMKMapKit.sharedInstance()
}
Note
If you're using a multi-module application and want to initialize MapKit in a method different from application(_:didFinishLaunchingWithOptions:)
, call the onStart()
method after creating the MapKit object:
MMKMapKit.setApiKey("MAPKIT_API_KEY")
MMKMapKit.sharedInstance().onStart()
Step 4. Add the map
Initialize the map in the needed view controller:
override func viewDidLoad() {
super.viewDidLoad()
mapView.mapWindow.map!.move(
with: MMKCameraPosition(
target: MMKPoint(latitude: 25.1982, longitude: 55.272758),
zoom: 15,
azimuth: 0,
tilt: 0
),
animation: MMKAnimation(type: MMKAnimationType.smooth, duration: 5),
cameraCallback: nil
)
}
Build and run your application. There's an example of the Activity with the tappable map:
Maps support multiple actions by default: move, rotate, change the zoom, and tilt.
Without additional setup, the map will be shown with the smallest possible zoom for the user's screen.
To change a map's position or zoom, use the MMKMap.move(with:animation:cameraCallback:) method:
private func move(_ map: MMKMap) {
let cameraPosition = MMKCameraPosition(
target: MMKPoint(latitude: 25.1982, longitude: 55.272758,
zoom: 17.0,
azimuth: 150.0,
tilt: 30.0
)
map.move(with: cameraPosition, animation: MMKAnimation(type: .smooth, duration: 1.0))
}
The MMKMap.move(with:animation:cameraCallback:) call accepts the MMKCameraPosition argument, which fully defines the map's position, zoom, tilt, and azimuth.
There's an example of the Activity after applying the move to the map:
Step 5. Note the following
MapKit stores weak references to the Listener objects passed to it. You need to store references to them in memory yourself:
Note
All Listener objects must be inherited from the NSObject
class.
internal class CameraListener: NSObject, MMKMapCameraListener {
func onCameraPositionChanged(
with map: MMKMap?,
cameraPosition: MMKCameraPosition,
cameraUpdateReason: MMKCameraUpdateReason,
finished: Bool
) {
// Do something
}
}
let cameraListener = CameraListener()
override func viewDidLoad() {
super.viewDidLoad()
mapView.mapWindow.map!.addCameraListener(with: cameraListener)
}
Note
By default, the methods of any Listener objects and platform interfaces are called on the main thread unless the method documentation specifies otherwise.
-
The minimum supported version for the M1 emulator is iOS 13.
-
The M1 emulator doesn't support OpenGL, so make sure to pass
vulkanPreferred: true
to theMMKMapView
andMMKPanoView
constructors. This setting is only required for the emulator build. -
Recommended linking flag:
-ObjC
.
Step 6. Display a placemark on the map
Let's modify the application such that you can show a tappable placemark on the map.
-
Add a
png
resource for the placemark image to the project.For example, we have the image named
placemark_icon.png
in ourAssets
directory. -
Add the placemark for the MMKMap.mapObjects collection to the specific location.
Obtain the image for our placemark using
UIImage(named:)
constructor. Add the placemark for the MMKMap.mapObjects collection to the specific location using MMKMapObjectCollection.addPlacemark(with:image:) method:private func addPlacemark(_ map: MMKMap) { let image = UIImage(named: "placemark_icon") ?? UIImage() let placemark = map.mapObjects.addPlacemark() placemark.geometry = MMKPoint(latitude: 25.1982, longitude: 55.272758 placemark.setIconWith(image) }
You can also add text to the placemark and customize it's style using MMKPlacemarkMapObject.setTextWithText(_:style:) method:
placemark.setTextWithText( "Sample placemark", style: MMKTextStyle( size: 10.0, color: .black, outlineColor: .white, placement: .top, offset: 0.0, offsetFromIcon: true, textOptional: false ) )
-
To subscribe to created placemark's taps use MMKMapObject.addTapListener(with:) method.
Firstly, we need to create a listener class, that implements the MMKMapObjectTapListener.onMapObjectTap(with:point:) method:
final private class MapObjectTapListener: NSObject, MMKMapObjectTapListener { init(controller: UIViewController) { self.controller = controller } func onMapObjectTap(with mapObject: MMKMapObject, point: MMKPoint) -> Bool { AlertPresenter.present( with: "Tapped point", message: "\((point.latitude, point.longitude))", from: controller ) return true } private let controller: UIViewController }
Then we can create a listener object and assign it to the placemark:
private lazy var mapObjectTapListener: MMKMapObjectTapListener = MapObjectTapListener(controller: self) private func addPlacemark(_ map: MMKMap) { placemark.addTapListener(with: mapObjectTapListener) }
Build and run your application. There's a placemark with your custom image on the map. Tap the placemark, and the message toast will show up: