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

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
    }