### Start Snapshot Creation Source: https://maplibre.org/maplibre-native/ios/latest/documentation/maplibre/mlnmapsnapshotter/startwithcompletionhandler%3A Initiates the snapshot process and provides a completion handler to be executed on the main queue. ```objective-c - (void) startWithCompletionHandler:(MLNMapSnapshotCompletionHandler) completionHandler; ``` -------------------------------- ### Start snapshot creation with a completion handler Source: https://maplibre.org/maplibre-native/ios/latest/documentation/maplibre/mlnmapsnapshotter/startwithqueue%3Acompletionhandler%3A Initiates the snapshot process and defines the queue for the completion callback. ```objective-c - (void) startWithQueue:(dispatch_queue_t) queue completionHandler:(MLNMapSnapshotCompletionHandler) completionHandler; ``` -------------------------------- ### Initialize and Add MLNImageSource Source: https://maplibre.org/maplibre-native/ios/latest/documentation/maplibre/mlnimagesource Example showing how to define coordinate bounds and add an image source to the map style. ```swift let coordinates = MLNCoordinateQuad( topLeft: CLLocationCoordinate2D(latitude: 46.437, longitude: -80.425), bottomLeft: CLLocationCoordinate2D(latitude: 37.936, longitude: -80.425), bottomRight: CLLocationCoordinate2D(latitude: 37.936, longitude: -71.516), topRight: CLLocationCoordinate2D(latitude: 46.437, longitude: -71.516)) let source = MLNImageSource(identifier: "radar", coordinateQuad: coordinates, url: URL(string: "https://maplibre.org/maplibre-gl-js-docs/assets/radar.gif")!) mapView.style?.addSource(source) ``` -------------------------------- ### startWithQueue:completionHandler: Source: https://maplibre.org/maplibre-native/ios/latest/documentation/maplibre/mlnmapsnapshotter/startwithqueue%3Acompletionhandler%3A Starts the snapshot creation and executes the specified block with the result on the specified queue. ```APIDOC ## - (void)startWithQueue:(dispatch_queue_t)queue completionHandler:(MLNMapSnapshotCompletionHandler)completionHandler ### Description Starts the snapshot creation and executes the specified block with the result on the specified queue. ### Parameters - **queue** (dispatch_queue_t) - The queue on which to call the block specified in the completionHandler parameter. - **completionHandler** (MLNMapSnapshotCompletionHandler) - The block to call with a finished snapshot. The block is executed on the queue specified in the queue parameter. ``` -------------------------------- ### - (void) startUpdatingLocation Source: https://maplibre.org/maplibre-native/ios/latest/documentation/maplibre/mlnlocationmanager/startupdatinglocation Starts the generation of location updates that reports the user’s current location. ```APIDOC ## - (void) startUpdatingLocation ### Description Starts the generation of location updates that reports the user’s current location. ### Signature `- (void) startUpdatingLocation;` ``` -------------------------------- ### Configure cluster properties dictionary Source: https://maplibre.org/maplibre-native/ios/latest/documentation/maplibre/mlnshapesourceoptionclusterproperties Example showing how to create an expression-based dictionary for cluster aggregation and apply it to source options. ```swift let firstExpression = NSExpression(format: "sum:({$featureAccumulated, sumValue})") let secondExpression = NSExpression(forKeyPath: "magnitude") let clusterPropertiesDictionary = ["sumValue" : [firstExpression, secondExpression]] let options : [MLNShapeSourceOption : Any] = [.clustered : true, .clusterProperties: clusterPropertiesDictionary] ``` -------------------------------- ### Implement Building Light Example with MLNFillExtrusionStyleLayer Source: https://maplibre.org/maplibre-native/ios/latest/documentation/maplibre-native-for-ios/buildinglightexample This class sets up a map view, adds a fill extrusion layer from vector data, and provides a slider to adjust the light position. ```swift class BuildingLightExample: UIViewController, MLNMapViewDelegate { var mapView: MLNMapView! var light: MLNLight! var slider: UISlider! override func viewDidLoad() { super.viewDidLoad() mapView = MLNMapView(frame: view.bounds, styleURL: AMERICANA_STYLE) mapView.autoresizingMask = [.flexibleWidth, .flexibleHeight] mapView.delegate = self // Center the map on the Flatiron Building in New York, NY. mapView.camera = MLNMapCamera(lookingAtCenter: CLLocationCoordinate2D(latitude: 40.7411, longitude: -73.9897), altitude: 1200, pitch: 45, heading: 0) view.addSubview(mapView) addSlider() } // Add a slider to the map view. This will be used to adjust the map's light object. func addSlider() { slider = UISlider() slider.translatesAutoresizingMaskIntoConstraints = false slider.autoresizingMask = [.flexibleTopMargin, .flexibleLeftMargin, .flexibleRightMargin] slider.minimumValue = -180 slider.maximumValue = 180 slider.value = 0 slider.isContinuous = true slider.addTarget(self, action: #selector(shiftLight), for: .valueChanged) view.addSubview(slider) NSLayoutConstraint.activate([ slider.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 40.0), slider.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -40.0), slider.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -75.0), ]) } func mapView(_: MLNMapView, didFinishLoading style: MLNStyle) { // Add a MLNFillExtrusionStyleLayer. addFillExtrusionLayer(style: style) // Create an MLNLight object. light = MLNLight() // Create an MLNSphericalPosition and set the radial, azimuthal, and polar values. // Radial : Distance from the center of the base of an object to its light. Takes a CGFloat. // Azimuthal : Position of the light relative to its anchor. Takes a CLLocationDirection. // Polar : The height of the light. Takes a CLLocationDirection. let position = MLNSphericalPositionMake(5, 180, 80) light.position = NSExpression(forConstantValue: NSValue(mlnSphericalPosition: position)) // Set the light anchor to the map and add the light object to the map view's style. The light anchor can be the viewport (or rotates with the viewport) or the map (rotates with the map). To make the viewport the anchor, replace `map` with `viewport`. light.anchor = NSExpression(forConstantValue: "map") style.light = light } @objc func shiftLight() { // Use the slider's value to change the light's polar value. let position = MLNSphericalPositionMake(5, 180, CLLocationDirection(slider.value)) light.position = NSExpression(forConstantValue: NSValue(mlnSphericalPosition: position)) mapView.style?.light = light } func addFillExtrusionLayer(style: MLNStyle) { // Access the OpenMapTiles source and use it to create a ``MLNFillExtrusionStyleLayer``. The source identifier is `openmaptiles`. Use the `sources` property on a style to verify source identifiers. guard let source = style.source(withIdentifier: "openmaptiles") else { print("Could not find source openmaptiles") return } let layer = MLNFillExtrusionStyleLayer(identifier: "extrusion-layer", source: source) layer.sourceLayerIdentifier = "building" layer.fillExtrusionBase = NSExpression(forKeyPath: "render_min_height") layer.fillExtrusionHeight = NSExpression(forKeyPath: "render_height") layer.fillExtrusionOpacity = NSExpression(forConstantValue: 0.8) layer.fillExtrusionColor = NSExpression(forConstantValue: UIColor.white) // Access the map's layer with the identifier "poi" and insert the fill extrusion layer below it. let symbolLayer = style.layer(withIdentifier: "poi")! style.insertLayer(layer, below: symbolLayer) } } ``` -------------------------------- ### startUpdatingHeading Source: https://maplibre.org/maplibre-native/ios/latest/documentation/maplibre/mlnlocationmanager/startupdatingheading Starts the generation of heading updates that reports the user’s current heading. ```APIDOC ## - (void)startUpdatingHeading ### Description Starts the generation of heading updates that reports the user’s current heading. ### Signature `- (void)startUpdatingHeading;` ``` -------------------------------- ### Manage Offline Regions Example Implementation Source: https://maplibre.org/maplibre-native/ios/latest/documentation/maplibre-native-for-ios/manageofflineregionsexample A UIViewController implementation that manages offline map packs, including UI setup and database reset logic. ```swift class ManageOfflineRegionsExample: UIViewController, MLNMapViewDelegate { let jsonDecoder = JSONDecoder() struct UserData: Codable { var name: String } lazy var mapView: MLNMapView = { let mapView = MLNMapView(frame: CGRect.zero, styleURL: AMERICANA_STYLE) mapView.autoresizingMask = [.flexibleWidth, .flexibleHeight] mapView.tintColor = .gray mapView.delegate = self mapView.translatesAutoresizingMaskIntoConstraints = false return mapView }() lazy var downloadButton: UIButton = { let downloadButton = UIButton(frame: CGRect.zero) downloadButton.backgroundColor = UIColor.systemBlue downloadButton.setTitleColor(UIColor.white, for: .normal) downloadButton.setTitle("Download Region", for: .normal) downloadButton.addTarget(self, action: #selector(startOfflinePackDownload), for: .touchUpInside) downloadButton.layer.cornerRadius = view.bounds.width / 30 downloadButton.translatesAutoresizingMaskIntoConstraints = false return downloadButton }() lazy var tableView: UITableView = { let tableView = UITableView(frame: CGRect.zero) tableView.delegate = self tableView.dataSource = self tableView.translatesAutoresizingMaskIntoConstraints = false return tableView }() override func viewDidLoad() { super.viewDidLoad() view.addSubview(mapView) view.addSubview(tableView) mapView.addSubview(downloadButton) let centerCoordinate = CLLocationCoordinate2D(latitude: 22.27933, longitude: 114.16281) mapView.setCenter(centerCoordinate, zoomLevel: 13, animated: false) // Set up constraints for map view, table view, and download button. installConstraints() } func setupOfflinePackHandler() { NotificationCenter.default.addObserver(self, selector: #selector(offlinePackProgressDidChange), name: NSNotification.Name.MLNOfflinePackProgressChanged, object: nil) } func installConstraints() { NSLayoutConstraint.activate([ mapView.topAnchor.constraint(equalTo: view.topAnchor), mapView.leadingAnchor.constraint(equalTo: view.leadingAnchor), mapView.trailingAnchor.constraint(equalTo: view.trailingAnchor), mapView.heightAnchor.constraint(equalTo: view.heightAnchor, multiplier: 0.5), tableView.topAnchor.constraint(equalTo: mapView.bottomAnchor), tableView.leadingAnchor.constraint(equalTo: view.leadingAnchor), tableView.trailingAnchor.constraint(equalTo: view.trailingAnchor), tableView.bottomAnchor.constraint(equalTo: view.bottomAnchor), downloadButton.topAnchor.constraint(equalTo: view.topAnchor, constant: 100), downloadButton.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 5), downloadButton.widthAnchor.constraint(equalTo: view.widthAnchor, multiplier: 0.45), downloadButton.heightAnchor.constraint(equalTo: downloadButton.widthAnchor, multiplier: 0.2), ]) } /* For the purposes of this example, remove any offline packs that exist before the example is re-loaded. */ override func viewWillAppear(_: Bool) { MLNOfflineStorage.shared.resetDatabase { error in if let error { // Handle the error here if packs can't be removed. print(error) } else { MLNOfflineStorage.shared.reloadPacks() } } } @objc func startOfflinePackDownload(selector _: NSNotification) { // Setup offline pack notification handlers. setupOfflinePackHandler() ``` -------------------------------- ### Verify MapLibre Import Source: https://maplibre.org/maplibre-native/ios/latest/documentation/maplibre-native-for-ios/gettingstarted Verify the installation by importing the module in your Swift file. ```swift import MapLibre ``` -------------------------------- ### Implement Multiple Images Example Source: https://maplibre.org/maplibre-native/ios/latest/documentation/maplibre-native-for-ios/multipleimagesexample Load an MBTiles source and apply a symbol layer with a match expression to display specific icons based on POITYPE attributes. ```swift class MultipleImagesExample: UIViewController, MLNMapViewDelegate { var mapView: MLNMapView! override func viewDidLoad() { super.viewDidLoad() mapView = MLNMapView(frame: view.bounds, styleURL: AMERICANA_STYLE) mapView.autoresizingMask = [.flexibleWidth, .flexibleHeight] mapView.tintColor = .darkGray let glacierPoint = CLLocationCoordinate2D(latitude: 37.72836462778902, longitude: -119.57352616838511) mapView.setCenter(glacierPoint, animated: false) mapView.zoomLevel = 12 mapView.delegate = self view.addSubview(mapView) } // Wait until the style is loaded before modifying the map style. func mapView(_: MLNMapView, didFinishLoading style: MLNStyle) { let source = MLNVectorTileSource(identifier: "pois-nps", configurationURL: URL(string: "mbtiles://\(Bundle.main.bundlePath)/pois-nps.mbtiles")!) style.addSource(source) let imagesToAdd = [ ["nps-restrooms", "restrooms"], ["nps-trailhead", "trailhead"], ["nps-viewpoint", "viewpoint"], ] for imageInfo in imagesToAdd { if let imageName = imageInfo.first, let imageKey = imageInfo.last { if let image = UIImage(named: imageName) { style.setImage(image, forName: imageKey) } else { print("Failed to load \(imageName)") return } } } let imageLayer = MLNSymbolStyleLayer(identifier: "npc-poi-images", source: source) imageLayer.sourceLayerIdentifier = "pois" imageLayer.iconImageName = NSExpression(mglJSONObject: [ "match", ["get", "POITYPE"], "Restroom", "restrooms", "Trailhead", "trailhead", "Viewpoint", "viewpoint", "", ]) style.addLayer(imageLayer) } } ``` -------------------------------- ### Creating an MLNPolyline Source: https://maplibre.org/maplibre-native/ios/latest/documentation/maplibre/mlnpolyline Example of initializing an MLNPolyline with an array of coordinates, including handling for the antimeridian. ```swift let coordinates = [ CLLocationCoordinate2D(latitude: 35.68476, longitude: -220.24257), CLLocationCoordinate2D(latitude: 37.78428, longitude: -122.41310) ] let polyline = MLNPolyline(coordinates: coordinates, count: UInt(coordinates.count)) ``` -------------------------------- ### Start snapshot with overlay handler in Objective-C Source: https://maplibre.org/maplibre-native/ios/latest/documentation/maplibre/mlnmapsnapshotter/startwithoverlayhandler%3Acompletionhandler%3A Initiates the snapshot creation process with a custom overlay handler and a completion handler. ```objective-c - (void) startWithOverlayHandler:(MLNMapSnapshotOverlayHandler) overlayHandler completionHandler:(MLNMapSnapshotCompletionHandler) completionHandler; ``` -------------------------------- ### Start Heading Updates in Objective-C Source: https://maplibre.org/maplibre-native/ios/latest/documentation/maplibre/mlnlocationmanager/startupdatingheading Initiates the reporting of the user's current heading. ```objective-c - (void) startUpdatingHeading; ``` -------------------------------- ### mapViewWillStartRenderingMap: Source: https://maplibre.org/maplibre-native/ios/latest/documentation/maplibre/mlnmapviewdelegate/mapviewwillstartrenderingmap%3A Tells the delegate that the map view is about to start rendering. ```APIDOC ## mapViewWillStartRenderingMap: ### Description Tells the delegate that the map view is about to start rendering. ### Signature `- (void) mapViewWillStartRenderingMap:(MLNMapView *) mapView;` ### Parameters - **mapView** (MLNMapView *) - The map view that is about to start rendering. ``` -------------------------------- ### Implement Offline Pack Download in UIViewController Source: https://maplibre.org/maplibre-native/ios/latest/documentation/maplibre-native-for-ios/offlinepackexample This example shows how to set up a map view, register for offline pack notifications, and initiate a download for a specific region. ```swift class OfflinePackExample: UIViewController, MLNMapViewDelegate { var mapView: MLNMapView! var progressView: UIProgressView! let jsonDecoder = JSONDecoder() struct UserData: Codable { var name: String } override func viewDidLoad() { super.viewDidLoad() mapView = MLNMapView(frame: view.bounds, styleURL: AMERICANA_STYLE) mapView.autoresizingMask = [.flexibleWidth, .flexibleHeight] mapView.tintColor = .gray mapView.delegate = self view.addSubview(mapView) mapView.setCenter(CLLocationCoordinate2D(latitude: 22.27933, longitude: 114.16281), zoomLevel: 13, animated: false) // Setup offline pack notification handlers. NotificationCenter.default.addObserver(self, selector: #selector(offlinePackProgressDidChange), name: NSNotification.Name.MLNOfflinePackProgressChanged, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(offlinePackDidReceiveError), name: NSNotification.Name.MLNOfflinePackError, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(offlinePackDidReceiveMaximumAllowedMapboxTiles), name: NSNotification.Name.MLNOfflinePackMaximumMapboxTilesReached, object: nil) } func mapViewDidFinishLoadingMap(_: MLNMapView) { // Start downloading tiles and resources for z13-14. startOfflinePackDownload() } override func viewDidDisappear(_ animated: Bool) { super.viewDidDisappear(animated) // When leaving this view controller, suspend offline downloads. guard let packs = MLNOfflineStorage.shared.packs else { return } for pack in packs { if let userInfo = try? jsonDecoder.decode(UserData.self, from: pack.context) { print("Suspending download of offline pack: '\(userInfo.name)'") } pack.suspend() } } func startOfflinePackDownload() { // Create a region that includes the current viewport and any tiles needed to view it when zoomed further in. // Because tile count grows exponentially with the maximum zoom level, you should be conservative with your `toZoomLevel` setting. let region = MLNTilePyramidOfflineRegion(styleURL: mapView.styleURL, bounds: mapView.visibleCoordinateBounds, fromZoomLevel: mapView.zoomLevel, toZoomLevel: 14) // Store some data for identification purposes alongside the downloaded resources. let jsonEncoder = JSONEncoder() let userInfo = UserData(name: "My Offline Pack") let encodedUserInfo = try! jsonEncoder.encode(userInfo) print(encodedUserInfo) // Create and register an offline pack with the shared offline storage object. MLNOfflineStorage.shared.addPack(for: region, withContext: encodedUserInfo) { pack, error in guard error == nil else { // The pack couldn’t be created for some reason. print("Error: \(error?.localizedDescription ?? "unknown error")") return } // Start downloading. pack!.resume() } } // MARK: - MLNOfflinePack notification handlers ``` -------------------------------- ### startWithOverlayHandler:completionHandler: Source: https://maplibre.org/maplibre-native/ios/latest/documentation/maplibre/mlnmapsnapshotter/startwithoverlayhandler%3Acompletionhandler%3A Starts the snapshot creation and executes the specified blocks with the result on the specified queue. Use this option if you want to add custom drawing on top of the resulting MLNMapSnapshot. ```APIDOC ## - (void)startWithOverlayHandler:(MLNMapSnapshotOverlayHandler)overlayHandler completionHandler:(MLNMapSnapshotCompletionHandler)completionHandler ### Description Starts the snapshot creation and executes the specified blocks with the result on the specified queue. Use this option if you want to add custom drawing on top of the resulting MLNMapSnapshot. ### Parameters - **overlayHandler** (MLNMapSnapshotOverlayHandler) - The block to call after the base map finishes drawing but before certain built-in overlays draw. The block can use Core Graphics to draw custom content directly over the base map. The block is executed on a background queue. - **completionHandler** (MLNMapSnapshotCompletionHandler) - The block to call with a finished snapshot. The block is executed on the main queue. ``` -------------------------------- ### Implement POI Along Route Example Source: https://maplibre.org/maplibre-native/ios/latest/documentation/maplibre-native-for-ios/poialongrouteexample This class sets up the map view, loads GeoJSON data, and configures line style layers with interpolation expressions for zoom-dependent styling. ```swift class POIAlongRouteExample: UIViewController, MLNMapViewDelegate { var mapView: MLNMapView! override func viewDidLoad() { super.viewDidLoad() mapView = MLNMapView(frame: view.bounds, styleURL: AMERICANA_STYLE) mapView.autoresizingMask = [.flexibleWidth, .flexibleHeight] mapView.setCenter( CLLocationCoordinate2D(latitude: 45.52214, longitude: -122.63748), zoomLevel: 18, animated: false ) view.addSubview(mapView) mapView.delegate = self } // Wait until the map is loaded before adding to the map. func mapView(_: MLNMapView, didFinishLoading _: MLNStyle) { loadGeoJson() restrictPOIVisibleShape() setCamera() } func loadGeoJson() { DispatchQueue.global().async { // Get the path for example.geojson in the app’s bundle. guard let jsonUrl = Bundle.main.url(forResource: "example", withExtension: "geojson") else { preconditionFailure("Failed to load local GeoJSON file") } guard let jsonData = try? Data(contentsOf: jsonUrl) else { preconditionFailure("Failed to parse GeoJSON file") } DispatchQueue.main.async { self.drawPolyline(geoJson: jsonData) } } } func setCamera() { let camera = mapView.camera camera.heading = 249.37706203842038 camera.pitch = 60 camera.centerCoordinate.latitude = 45.52199780570582 camera.centerCoordinate.longitude = -122.6418837958432 mapView.setCamera(camera, animated: false) mapView.setZoomLevel(15.062187320447523, animated: false) } func drawPolyline(geoJson: Data) { // Add our GeoJSON data to the map as an MLNGeoJSONSource. // We can then reference this data from an MLNStyleLayer. // MLNMapView.style is optional, so you must guard against it not being set. guard let style = mapView.style else { return } guard let shapeFromGeoJSON = try? MLNShape(data: geoJson, encoding: String.Encoding.utf8.rawValue) else { fatalError("Could not generate MLNShape") } let source = MLNShapeSource(identifier: "polyline", shape: shapeFromGeoJSON, options: nil) style.addSource(source) // Create new layer for the line. let layer = MLNLineStyleLayer(identifier: "polyline", source: source) // Set the line join and cap to a rounded end. layer.lineJoin = NSExpression(forConstantValue: "round") layer.lineCap = NSExpression(forConstantValue: "round") // Set the line color to a constant blue color. layer.lineColor = NSExpression(forConstantValue: UIColor(red: 59 / 255, green: 178 / 255, blue: 208 / 255, alpha: 1)) // Use expression to smoothly adjust the line width from 2pt to 20pt between zoom levels 14 and 18. layer.lineWidth = NSExpression(mglJSONObject: ["interpolate", ["linear"], ["zoom"], 14, 2, 18, 20]) // We can also add a second layer that will draw a stroke around the original line. let casingLayer = MLNLineStyleLayer(identifier: "polyline-case", source: source) // Copy these attributes from the main line layer. casingLayer.lineJoin = layer.lineJoin casingLayer.lineCap = layer.lineCap // Line gap width represents the space before the outline begins, so should match the main line’s line width exactly. casingLayer.lineGapWidth = layer.lineWidth // Stroke color slightly darker than the line color. casingLayer.lineColor = NSExpression(forConstantValue: UIColor(red: 41 / 255, green: 145 / 255, blue: 171 / 255, alpha: 1)) // Use expression to gradually increase the stroke width between zoom levels 14 and 18. casingLayer.lineWidth = NSExpression(mglJSONObject: ["interpolate", ["linear"], ["zoom"], 14, 1, 18, 4]) ``` -------------------------------- ### Start location updates in Objective-C Source: https://maplibre.org/maplibre-native/ios/latest/documentation/maplibre/mlnlocationmanager/startupdatinglocation Call this method to begin receiving location updates from the location manager. ```objective-c - (void) startUpdatingLocation; ``` -------------------------------- ### Example usage of MLNShape with GeoJSON Source: https://maplibre.org/maplibre-native/ios/latest/documentation/maplibre/mlnshape/shapewithdata%3Aencoding%3Aerror%3A Demonstrates loading a GeoJSON file from the bundle and initializing an MLNShapeCollectionFeature. ```swift let url = mainBundle.url(forResource: "amsterdam", withExtension: "geojson")! let data = try! Data(contentsOf: url) let feature = try! MLNShape(data: data, encoding: String.Encoding.utf8.rawValue) as! MLNShapeCollectionFeature ``` -------------------------------- ### Add Marker Symbol Example Source: https://maplibre.org/maplibre-native/ios/latest/documentation/maplibre-native-for-ios/addmarkersymbolexample Demonstrates how to initialize a map view and add a symbol layer with a custom icon image once the map style has finished loading. ```swift class AddMarkerSymbolExampleUIKit: UIViewController, MLNMapViewDelegate { override func viewDidLoad() { super.viewDidLoad() let mapView = MLNMapView(frame: view.bounds) mapView.autoresizingMask = [.flexibleWidth, .flexibleHeight] mapView.delegate = self // Set the map’s center coordinate and zoom level. mapView.setCenter(CLLocationCoordinate2D(latitude: 41.8864, longitude: -87.7135), zoomLevel: 13, animated: false) view.addSubview(mapView) } func mapView(_ mapView: MLNMapView, didFinishLoading style: MLNStyle) { // Create point to represent where the symbol should be placed let point = MLNPointAnnotation() point.coordinate = mapView.centerCoordinate // Create a data source to hold the point data let shapeSource = MLNShapeSource(identifier: "marker-source", shape: point, options: nil) // Create a style layer for the symbol let shapeLayer = MLNSymbolStyleLayer(identifier: "marker-style", source: shapeSource) // Add the image to the style's sprite if let image = UIImage(named: "house-icon") { style.setImage(image, forName: "home-symbol") } // Tell the layer to use the image in the sprite shapeLayer.iconImageName = NSExpression(forConstantValue: "home-symbol") // Add the source and style layer to the map style.addSource(shapeSource) style.addLayer(shapeLayer) } } ``` -------------------------------- ### Check for Cluster Conformance Source: https://maplibre.org/maplibre-native/ios/latest/documentation/maplibre/mlncluster Example demonstrating how to verify if a feature conforms to the MLNCluster protocol and is an instance of MLNPointFeatureCluster. ```swift let shape = try! MLNShape(data: clusterShapeData, encoding: String.Encoding.utf8.rawValue) guard let pointFeature = shape as? MLNPointFeature else { throw ExampleError.unexpectedFeatureType } // Check for cluster conformance guard let cluster = pointFeature as? MLNCluster else { throw ExampleError.featureIsNotACluster } // Currently the only supported class that conforms to ``MLNCluster`` is // ``MLNPointFeatureCluster`` guard cluster is MLNPointFeatureCluster else { throw ExampleError.unexpectedFeatureType } ``` -------------------------------- ### Load a local PMTiles file in a MapLibre view Source: https://maplibre.org/maplibre-native/ios/latest/documentation/maplibre-native-for-ios/pmtiles This example demonstrates how to access a bundled .pmtiles file and add it as a vector tile source to an MLNMapView. ```swift class PMTilesLocalFile: UIViewController, MLNMapViewDelegate { var mapView: MLNMapView! override func viewDidLoad() { super.viewDidLoad() mapView = MLNMapView(frame: view.bounds) mapView.autoresizingMask = [.flexibleWidth, .flexibleHeight] mapView.delegate = self view.addSubview(mapView) } func mapView(_: MLNMapView, didFinishLoading style: MLNStyle) { guard let fileURL = Bundle.main.url(forResource: "world", withExtension: "pmtiles") else { return } let url = URL(string: "pmtiles://\(fileURL.absoluteString)")! let source = MLNVectorTileSource(identifier: "world", configurationURL: url) style.addSource(source) let layer = MLNFillStyleLayer(identifier: "countries", source: source) layer.sourceLayerIdentifier = "countries" layer.fillColor = NSExpression(forConstantValue: UIColor(red: 0.67, green: 0.83, blue: 0.87, alpha: 1)) style.addLayer(layer) } } ``` -------------------------------- ### - (void)startWithCompletionHandler:(MLNMapSnapshotCompletionHandler)completionHandler Source: https://maplibre.org/maplibre-native/ios/latest/documentation/maplibre/mlnmapsnapshotter/startwithcompletionhandler%3A Starts the snapshot creation process and executes the specified completion block on the main queue once the snapshot is finished. ```APIDOC ## - (void)startWithCompletionHandler:(MLNMapSnapshotCompletionHandler)completionHandler ### Description Starts the snapshot creation and executes the specified block with the result. ### Parameters - **completionHandler** (MLNMapSnapshotCompletionHandler) - Required - The block to call with a finished snapshot. The block is executed on the main queue. ``` -------------------------------- ### initWithStyleURL:camera:size: Source: https://maplibre.org/maplibre-native/ios/latest/documentation/maplibre/mlnmapsnapshotoptions/initwithstyleurl%3Acamera%3Asize%3A Creates a set of options with the minimum required information for a map snapshot. ```APIDOC ## initWithStyleURL:camera:size: ### Description Creates a set of options with the minimum required information. ### Signature `- (instancetype) initWithStyleURL:(NSURL *) styleURL camera:(MLNMapCamera *) camera size:(CGSize) size;` ### Parameters - **styleURL** (NSURL *) - Required - URL of the map style to snapshot. The URL may be a full HTTP, HTTPS URL, canonical URL or a path to a local file relative to the application’s resource path. Specify nil for the default style. - **camera** (MLNMapCamera *) - Required - The camera representing the viewport visible in the snapshot. - **size** (CGSize) - Required - The image size. ``` -------------------------------- ### Implement a Custom Style Layer with Metal Source: https://maplibre.org/maplibre-native/ios/latest/documentation/maplibre-native-for-ios/customstylelayerexample This example demonstrates wrapping an MLNMapView in a SwiftUI view and implementing a custom MLNCustomStyleLayer that compiles Metal shaders and configures a render pipeline. ```swift struct CustomStyleLayerExample: UIViewRepresentable { func makeCoordinator() -> CustomStyleLayerExample.Coordinator { Coordinator(self) } final class Coordinator: NSObject, MLNMapViewDelegate { var control: CustomStyleLayerExample init(_ control: CustomStyleLayerExample) { self.control = control } func mapViewDidFinishLoadingMap(_ mapView: MLNMapView) { let mapOverlay = CustomStyleLayer(identifier: "test-overlay") let style = mapView.style! style.layers.append(mapOverlay) } } func makeUIView(context: Context) -> MLNMapView { let mapView = MLNMapView() mapView.delegate = context.coordinator return mapView } func updateUIView(_: MLNMapView, context _: Context) {} } class CustomStyleLayer: MLNCustomStyleLayer { private var pipelineState: MTLRenderPipelineState? private var depthStencilStateWithoutStencil: MTLDepthStencilState? override func didMove(to mapView: MLNMapView) { #if MLN_RENDER_BACKEND_METAL let resource = mapView.backendResource() let shaderSource = """ #include using namespace metal; typedef struct { vector_float2 position; vector_float4 color; } Vertex; struct RasterizerData { float4 position [[position]]; float4 color; }; struct Uniforms { float4x4 matrix; }; vertex RasterizerData vertexShader(uint vertexID [[vertex_id]], constant Vertex *vertices [[buffer(0)]], constant Uniforms &uniforms [[buffer(1)]]) { RasterizerData out; const float4 position = uniforms.matrix * float4(float2(vertices[vertexID].position.xy), 1, 1); out.position = position; out.color = vertices[vertexID].color; return out; } fragment float4 fragmentShader(RasterizerData in [[stage_in]]) { return in.color; } """ let device = resource.device var library: MTLLibrary? = nil var shaderError: Error? = nil do { library = try device?.makeLibrary(source: shaderSource, options: nil) } catch { shaderError = error } assert(library != nil, "Error compiling shaders: \(String(describing: shaderError))") let vertexFunction = library?.makeFunction(name: "vertexShader") let fragmentFunction = library?.makeFunction(name: "fragmentShader") // Configure a pipeline descriptor that is used to create a pipeline state. let pipelineStateDescriptor = MTLRenderPipelineDescriptor() pipelineStateDescriptor.label = "Simple Pipeline" pipelineStateDescriptor.vertexFunction = vertexFunction pipelineStateDescriptor.fragmentFunction = fragmentFunction pipelineStateDescriptor.colorAttachments[0].pixelFormat = resource.mtkView.colorPixelFormat pipelineStateDescriptor.depthAttachmentPixelFormat = .depth32Float_stencil8 pipelineStateDescriptor.stencilAttachmentPixelFormat = .depth32Float_stencil8 ``` -------------------------------- ### - initWithIdentifier:configurationURL: Source: https://maplibre.org/maplibre-native/ios/latest/documentation/maplibre/mlnvectortilesource/initwithidentifier%3Aconfigurationurl%3A Initializes a vector tile source with a unique identifier and a configuration URL pointing to a TileJSON file. ```APIDOC ## - initWithIdentifier:configurationURL: ### Description Returns a vector tile source initialized with an identifier and configuration URL. After initialization, the source can be added to a map view's style. ### Signature `- (instancetype)initWithIdentifier:(NSString *)identifier configurationURL:(NSURL *)configurationURL;` ### Parameters - **identifier** (NSString *) - Required - A string that uniquely identifies the source in the style to which it is added. - **configurationURL** (NSURL *) - Required - A URL to a TileJSON configuration file describing the source’s contents and other metadata. The URL may be a full HTTP/HTTPS URL or a canonical URL. ### Return Value - **instancetype** - An initialized vector tile source. ``` -------------------------------- ### Get activityType property Source: https://maplibre.org/maplibre-native/ios/latest/documentation/maplibre/mlnlocationmanager/activitytype Retrieves the CLActivityType associated with the location manager. ```objective-c - (CLActivityType) activityType; ``` -------------------------------- ### MLNTransition.delay Source: https://maplibre.org/maplibre-native/ios/latest/documentation/maplibre/mlntransition/delay The delay property defines the time interval in seconds before an animation starts. ```APIDOC ## MLNTransition.delay ### Description The amount of time in seconds to wait before beginning the animation. ### Property Signature `NSTimeInterval delay;` ``` -------------------------------- ### calloutViewWillAppear: Source: https://maplibre.org/maplibre-native/ios/latest/documentation/maplibre/mlncalloutviewdelegate/calloutviewwillappear%3A Called before the callout view appears on screen, or before the appearance animation will start. ```APIDOC ## - (void)calloutViewWillAppear:(UIView *)calloutView ### Description Called before the callout view appears on screen, or before the appearance animation will start. ### Parameters - **calloutView** (UIView *) - The callout view that is about to appear. ``` -------------------------------- ### + (void) useWellKnownTileServer:(MLNWellKnownTileServer) tileServer; Source: https://maplibre.org/maplibre-native/ios/latest/documentation/maplibre/mlnsettings/usewellknowntileserver%3A Instructs the SDK to use the given well-known tile server. ```APIDOC ## + (void) useWellKnownTileServer:(MLNWellKnownTileServer) tileServer; ### Description Instructs the SDK to use the given well-known tile server. ### Method Objective-C Class Method ### Parameters - **tileServer** (MLNWellKnownTileServer) - Required - The well-known tile server configuration to be used by the SDK. ``` -------------------------------- ### Shader Compilation Events Source: https://maplibre.org/maplibre-native/ios/latest/documentation/maplibre-native-for-ios/observerexample Methods to observe the start and completion of shader compilation. ```APIDOC ## mapView(_:shaderWillCompile:backend:defines:) ## mapView(_:shaderDidCompile:backend:defines:) ### Description These methods are triggered when a shader is about to be compiled or has finished compiling, respectively. ### Signatures `func mapView(_: MLNMapView, shaderWillCompile id: Int, backend: Int, defines: String)` `func mapView(_: MLNMapView, shaderDidCompile id: Int, backend: Int, defines: String)` ``` -------------------------------- ### Initialize and Add MLNRasterDEMSource Source: https://maplibre.org/maplibre-native/ios/latest/documentation/maplibre/mlnrasterdemsource Create a source instance using a configuration URL and add it to the map style. ```swift let terrainRGBURL = URL(string: "maptiler://sources/terrain-rgb")! let source = MLNRasterDEMSource(identifier: "hills", configurationURL: terrainRGBURL) mapView.style?.addSource(source) ``` -------------------------------- ### Create Combined Camera Change Reason Constants Source: https://maplibre.org/maplibre-native/ios/latest/documentation/maplibre/mlncamerachangereason Example of grouping multiple bitmask values into custom constants for easier checking of zoom or rotation events. ```Objective-C static const MLNCameraChangeReason anyZoom = MLNCameraChangeReasonGesturePinch | MLNCameraChangeReasonGestureZoomIn | MLNCameraChangeReasonGestureZoomOut | MLNCameraChangeReasonGestureOneFingerZoom; static const MLNCameraChangeReason anyRotation = MLNCameraChangeReasonResetNorth | MLNCameraChangeReasonGestureRotate; ``` -------------------------------- ### Get desiredAccuracy Source: https://maplibre.org/maplibre-native/ios/latest/documentation/maplibre/mlnlocationmanager/desiredaccuracy Retrieves the current location accuracy setting for the location manager. ```objective-c - (CLLocationAccuracy) desiredAccuracy; ``` -------------------------------- ### locationManager Source: https://maplibre.org/maplibre-native/ios/latest/documentation/maplibre/mlnmapview/locationmanager The object that this map view uses to start and stop the delivery of location-related updates. ```APIDOC ## @property locationManager ### Description The object that this map view uses to start and stop the delivery of location-related updates. If set to nil or if no custom manager is provided, the map view uses the default location manager. ### Signature `@property (nonatomic) id locationManager;` ### Usage To substitute your own location manager, set this property before setting `showsUserLocation` to `YES`. To restore the default location manager, set this property to `nil`. ### Implementation Notes To receive the current user location, implement the `mapView:didUpdateUserLocation:` and `mapView:didFailToLocateUserWithError:` methods. ``` -------------------------------- ### initWithTitle:URL: Source: https://maplibre.org/maplibre-native/ios/latest/documentation/maplibre/mlnattributioninfo/initwithtitle%3Aurl%3A Initializes an MLNAttributionInfo object with the provided title and URL. ```APIDOC ## initWithTitle:URL: ### Description Returns an initialized attribution info object with the given title and URL. ### Signature `- (instancetype) initWithTitle:(NSAttributedString *) title URL:(NSURL *) URL;` ### Parameters - **title** (NSAttributedString *) - The attribution statement’s title. - **URL** (NSURL *) - A URL to more information about the entity named in the attribution. ### Return Value - **instancetype** - An initialized attribution info object. ``` -------------------------------- ### Get distanceFilter property Source: https://maplibre.org/maplibre-native/ios/latest/documentation/maplibre/mlnlocationmanager/distancefilter Retrieves the current minimum distance filter value in meters. ```objective-c - (CLLocationDistance) distanceFilter; ``` -------------------------------- ### initWithIdentifier:configurationURLString: Source: https://maplibre.org/maplibre-native/ios/latest/documentation/maplibre/mlnvectortilesource/initwithidentifier%3Aconfigurationurlstring%3A Initializes a vector tile source with a unique identifier and a configuration URL string. ```APIDOC ## initWithIdentifier:configurationURLString: ### Description Returns a vector tile source initialized with an identifier and a string-based configuration URL. This constructor is useful for URLs that may cause issues with standard NSURL parsing, such as custom protocol schemes. ### Signature `- (instancetype)initWithIdentifier:(NSString *)identifier configurationURLString:(NSString *)configurationURLString;` ### Parameters - **identifier** (NSString *) - Required - A string that uniquely identifies the source in the style to which it is added. - **configurationURLString** (NSString *) - Required - A string to a TileJSON configuration file describing the source’s contents and other metadata. ### Return Value - **instancetype** - An initialized vector tile source. ### Discussion After initializing and configuring the source, add it to a map view’s style using the `addSource:` method. The string should point to a JSON file that conforms to the TileJSON specification. ``` -------------------------------- ### Adding a Polyline to a Map Source: https://maplibre.org/maplibre-native/ios/latest/documentation/maplibre/mlnshapesource Example of creating an MLNPolylineFeature and adding it to the map using an MLNShapeSource. ```swift var coordinates: [CLLocationCoordinate2D] = [ CLLocationCoordinate2D(latitude: 37.77, longitude: -122.42), CLLocationCoordinate2D(latitude: 38.91, longitude: -77.04), ] let polyline = MLNPolylineFeature(coordinates: &coordinates, count: UInt(coordinates.count)) let source = MLNShapeSource(identifier: "lines", features: [polyline], options: nil) mapView.style?.addSource(source) ``` -------------------------------- ### initWithIdentifier:URL:options: Source: https://maplibre.org/maplibre-native/ios/latest/documentation/maplibre/mlnshapesource/initwithidentifier%3Aurl%3Aoptions%3A Initializes a shape source with an identifier, URL, and dictionary of options for the source. ```APIDOC ## - (instancetype)initWithIdentifier:(NSString *)identifier URL:(NSURL *)url options:(NSDictionary *)options ### Description Returns a shape source with an identifier, URL, and dictionary of options for the source. ### Parameters - **identifier** (NSString *) - A string that uniquely identifies the source. - **url** (NSURL *) - An HTTP(S) URL, absolute file URL, or local file URL relative to the current application’s resource bundle. - **options** (NSDictionary *) - An NSDictionary of options for this source. ### Return Value An initialized shape source. ### Discussion This class supports the following options: MLNShapeSourceOptionClustered, MLNShapeSourceOptionClusterRadius, MLNShapeSourceOptionMaximumZoomLevelForClustering, MLNShapeSourceOptionMinimumZoomLevel, MLNShapeSourceOptionBuffer, and MLNShapeSourceOptionSimplificationTolerance. Shapes provided by a shape source are not clipped or wrapped automatically. ``` -------------------------------- ### - (instancetype) initWithIdentifier:(NSString *) identifier; Source: https://maplibre.org/maplibre-native/ios/latest/documentation/maplibre/mlnsource/initwithidentifier%3A Initializes a source with a unique identifier string. ```APIDOC ## - (instancetype) initWithIdentifier:(NSString *) identifier; ### Description Returns a source initialized with a unique identifier. After initialization, the source should be added to a map view's style using the `addSource:` method. ### Parameters - **identifier** (NSString *) - Required - A string that uniquely identifies the source in the style to which it is added. ### Return Value - **instancetype** - An initialized source object. ``` -------------------------------- ### initWithIdentifier:source: Source: https://maplibre.org/maplibre-native/ios/latest/documentation/maplibre/mlncolorreliefstylelayer Initializes a new color-relief style layer with a specific identifier and source. ```APIDOC ## - initWithIdentifier:source: ### Description Returns a color-relief style layer initialized with an identifier and source. ### Signature `- (instancetype)initWithIdentifier:(NSString *)identifier source:(MLNSource *)source;` ``` -------------------------------- ### - (instancetype) initWithFrame:(CGRect) frame options:(MLNMapOptions *) options; Source: https://maplibre.org/maplibre-native/ios/latest/documentation/maplibre/mlnmapview/initwithframe%3Aoptions%3A Initializes and returns a newly allocated map view with the specified frame and the default style. ```APIDOC ## - (instancetype) initWithFrame:(CGRect) frame options:(MLNMapOptions *) options; ### Description Initializes and returns a newly allocated map view with the specified frame and the default style. ### Parameters - **frame** (CGRect) - The frame for the view, measured in points. - **options** (MLNMapOptions *) - The map instance options. ### Return Value - **instancetype** - An initialized map view. ``` -------------------------------- ### initWithIdentifier:configurationURL: Source: https://maplibre.org/maplibre-native/ios/latest/documentation/maplibre/mlnrastertilesource/initwithidentifier%3Aconfigurationurl%3A Initializes a raster tile source with the specified identifier and configuration URL. ```APIDOC ## initWithIdentifier:configurationURL: ### Description Returns a raster tile source initialized with an identifier and configuration URL. After initialization, the source can be added to a map view's style using the `addSource:` method. ### Signature `- (instancetype)initWithIdentifier:(NSString *)identifier configurationURL:(NSURL *)configurationURL;` ### Parameters - **identifier** (NSString *) - Required - A string that uniquely identifies the source in the style to which it is added. - **configurationURL** (NSURL *) - Required - A URL to a TileJSON configuration file describing the source’s contents and other metadata. ### Return Value - **instancetype** - An initialized raster tile source. ### Discussion The URL may be a full HTTP or HTTPS URL or a canonical URL. If a Mapbox URL is specified, this source uses a tile size of 256; otherwise, the default is 512. ``` -------------------------------- ### maximumZoomLevel Source: https://maplibre.org/maplibre-native/ios/latest/documentation/maplibre/mlnstylelayer/maximumzoomlevel The maximum zoom level at which the layer gets parsed and appears. This value is a floating-point number. ```APIDOC ## maximumZoomLevel ### Description The maximum zoom level at which the layer gets parsed and appears. This value is a floating-point number. ### Signature `@property (nonatomic, assign) float maximumZoomLevel;` ``` -------------------------------- ### minimumZoomLevel Source: https://maplibre.org/maplibre-native/ios/latest/documentation/maplibre/mlnstylelayer/minimumzoomlevel The minimum zoom level at which the layer gets parsed and appears. This value is a floating-point number. ```APIDOC ## minimumZoomLevel ### Description The minimum zoom level at which the layer gets parsed and appears. This value is a floating-point number. ### Signature @property (nonatomic, assign) float minimumZoomLevel; ``` -------------------------------- ### - (instancetype) initWithFrame:(CGRect) frame; Source: https://maplibre.org/maplibre-native/ios/latest/documentation/maplibre/mlnmapview/initwithframe%3A Initializes and returns a newly allocated map view with the specified frame and the default style. ```APIDOC ## - (instancetype) initWithFrame:(CGRect) frame; ### Description Initializes and returns a newly allocated map view with the specified frame and the default style. ### Parameters - **frame** (CGRect) - The frame for the view, measured in points. ### Return Value An initialized map view. ``` -------------------------------- ### Get string representation of coordinate quad Source: https://maplibre.org/maplibre-native/ios/latest/documentation/maplibre/mlnstringfromcoordinatequad Returns a formatted string for the given coordinate quad. ```objective-c static NSString *MLNStringFromCoordinateQuad(MLNCoordinateQuad quad); ``` -------------------------------- ### initWithOptions: Source: https://maplibre.org/maplibre-native/ios/latest/documentation/maplibre/mlnmapsnapshotter/initwithoptions%3A Initializes and returns a map snapshotter object that produces snapshots according to the given options. ```APIDOC ## initWithOptions: ### Description Initializes and returns a map snapshotter object that produces snapshots according to the given options. ### Signature `- (instancetype) initWithOptions:(MLNMapSnapshotOptions *) options;` ### Parameters - **options** (MLNMapSnapshotOptions *) - Required - The options to use when generating a map snapshot. ### Return Value - **instancetype** - An initialized map snapshotter. ``` -------------------------------- ### Configure tile server using useWellKnownTileServer Source: https://maplibre.org/maplibre-native/ios/latest/documentation/maplibre/mlnsettings/usewellknowntileserver%3A Instructs the SDK to use the given tile server. ```objective-c + (void) useWellKnownTileServer:(MLNWellKnownTileServer) tileServer; ``` -------------------------------- ### initWithIdentifier: Source: https://maplibre.org/maplibre-native/ios/latest/documentation/maplibre/mlnbackgroundstylelayer/initwithidentifier%3A Initializes a background style layer with a unique identifier. ```APIDOC ## initWithIdentifier: ### Description Returns a background style layer initialized with a unique identifier. ### Signature `- (instancetype)initWithIdentifier:(NSString *)identifier;` ### Parameters - **identifier** (NSString *) - Required - A string that uniquely identifies the source in the style to which it is added. ### Discussion After initializing and configuring the style layer, add it to a map view’s style using the `addLayer:` or `insertLayer:belowLayer:` method. ``` -------------------------------- ### initWithIdentifier:configurationURL:tileSize: Source: https://maplibre.org/maplibre-native/ios/latest/documentation/maplibre/mlnrastertilesource/initwithidentifier%3Aconfigurationurl%3Atilesize%3A Initializes a new raster tile source instance with the provided identifier, configuration URL, and tile size. ```APIDOC ## initWithIdentifier:configurationURL:tileSize: ### Description Returns a raster tile source initialized with an identifier, configuration URL, and tile size. After initialization, the source can be added to a map view's style. ### Signature `- (instancetype) initWithIdentifier:(NSString *) identifier configurationURL:(NSURL *) configurationURL tileSize:(CGFloat) tileSize;` ### Parameters - **identifier** (NSString *) - A string that uniquely identifies the source in the style to which it is added. - **configurationURL** (NSURL *) - A URL to a TileJSON configuration file describing the source’s contents and other metadata. - **tileSize** (CGFloat) - The width and height (measured in points) of each tiled image in the raster tile source. ### Return Value - **instancetype** - An initialized raster tile source. ``` -------------------------------- ### Get GeoJSON Data from MLNShape Source: https://maplibre.org/maplibre-native/ios/latest/documentation/maplibre/mlnshape/geojsondatausingencoding%3A Returns the GeoJSON string representation of the shape encapsulated in a data object. ```objective-c - (NSData *) geoJSONDataUsingEncoding:(NSStringEncoding) encoding; ```