Swift 2 examples – #6 Take a Snapshot of a MKMapView

Published by

on

This post is part of my collection: Swift 2 – For Beginners.

This is an example that shows how to take a snapshot of a MKMapView using MKMapSnapshotter. The annotations are not included.

First, we write a generic method that takes a snapshot and execute a callback, it allows us to do what we want with the generated UIImage:

    // Takes a snapshot and calls back with the generated UIImage
    static func takeSnapshot(mapView: MKMapView, withCallback: (UIImage?, NSError?) -> ()) {
        let options = MKMapSnapshotOptions()
        options.region = mapView.region
        options.size = mapView.frame.size
        options.scale = UIScreen.mainScreen().scale
        
        let snapshotter = MKMapSnapshotter(options: options)
        snapshotter.startWithCompletionHandler() { snapshot, error in
            guard snapshot != nil else {
                withCallback(nil, error)
                return
            }
            
            withCallback(snapshot!.image, nil)
        }
    }

We can use the previous method to write a method that directly saves the map snapshot as a png.

    // Takes a snapshot and saves the image locally in the DocumentDirectory
    static func takeSnapshot(mapView: MKMapView, filename: String) {
        
        MapHelper.takeSnapshot(mapView) { (image, error) -> () in
            guard image != nil else {
                print(error)
                return
            }
            
            // Save file in DocumentDirectory
            if let data = UIImagePNGRepresentation(image!) {
                let filename = getDocumentsDirectory().stringByAppendingPathComponent("\(filename).png")
                data.writeToFile(filename, atomically: true)
            }
        }
    }

To get the path to the documents directory we can use this method:

    // Gets the path to the current directory
    static func getDocumentsDirectory() -> NSString {
        let paths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)
        let documentsDirectory = paths[0]
        return documentsDirectory
    }

4 responses to “Swift 2 examples – #6 Take a Snapshot of a MKMapView”

  1. David Avatar

    Hi Juan, very useful tutorial thanks. However MapHelper doesn’t seem to have been defined and Xcode is throwing up “use of unresolved identifier”. Also, how would you take this a step further and save the image to the camera roll once you have the snapshot? Thanks!

    Like

  2. ginjawhinja Avatar
    ginjawhinja

    Hi Juan Carlos, useful stuff, thanks! MapHelper doesn’t seem to have been defined though and is returning “use of unresolved identifier”? Also, how would we take this a step further and save the snapshot as a picture to the camera roll? Thanks very much….

    Like

  3. Juan Carlos Sánchez Avatar

    Hi, first of all thank you for reading the tutorial and thank you for your comment!

    I had both methods in a class called MapHelper, both methods are static so you can add the class name to the method call (and I like to do that so I know that it is a static method of that class).

    If you remove MapHelper it should work, the method that should be called is “takeSnapshot(mapView: MKMapView, withCallback)”

    It is defined on the first step of the tutorial.

    About your second question “save to camera roll”: you can use UIImageWriteToSavedPhotosAlbum

    https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIKitFunctionReference/#//apple_ref/c/func/UIImageWriteToSavedPhotosAlbum

    Have fun with swift!

    Like

  4. Florian Tonnelier Avatar

    I got this error : “Cannot convert value of type ‘(_, _) ->()’ to expected argument type ‘String’ when I remove MapHelper (Line 4)
    Any idea ? 🙂

    Like

Your feedback is important…

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Blog at WordPress.com.