Below we’ll talk about the major components used when building a map-based iOS app with our SDK. We’re assuming you have a general familiarity with Apple’s developer tools, the Cocoa framework, and the Objective-C language and conventions.
Full API documentation is available right in Xcode, either inline or Xcode's documentation viewer.
The map view is the basic view that you’ll work with to display a map that pans and zooms in response to gestures. You can instantiate a map view in code or you can embed one in an Interface Builder (
.xib) file, just like any other
UIView subclass. By default, if not configured with a tile source (see Installation above), the map view will display a watermarked example Mapbox map, automatically detecting whether a retina or normal version should be used. There are options to control the map style (with tile sources), markers and shapes on the map, offline caching policy, zooming limits, retina display behavior, starting coordinate, and map view dragging deceleration, among other parameters.
Following Objective-C’s customary delegation design pattern, a map view can have an optional delegate object in order to help make interaction decisions. Some of these decisions include:
Tile sources are a concept similar to changing between standard, satellite, and hybrid styles in MapKit, but with much more customizability. With tile sources, the map style can be changed by providing one or more online or offline tile-based layers to display on the map from a variety of providers. In addition, the Mapbox iOS SDK supports client-side compositing of tile layers for increased performance and responsiveness.
The tile sources that support Mapbox’s core technology include
RMMapboxSource for online layers from Mapbox Hosting or a TileStream server, and the
RMMBTilesSource for use of offline-capable MBTiles layers.
Markers and other visual additions above the map tile layers are managed with
RMMapLayer and its subclasses:
RMMarker- points and images
RMShape- vector lines and other custom shapes
RMCircle- perfect vector circles
In addition, any
RMMapLayer, as a
CALayer subclass, can have its
contents property set to a
CGImage and the layer will be panned with the map automatically. You may wish to use the map view’s delegate callbacks to respond to map zooms, however, in order to redraw the image according to zoom level in order to preserve the best visual appearance.
Markers and shapes are added in a manner similar to MapKit, where annotation data objects (
RMAnnotation) are added to the map view, then the map view delegate answers requests for the actual layers to be displayed when they are first needed, providing better performance.
There is also an easier, automatic way to add markers in iOS to maps that you have made for the web in our hosted tools using simplestyle. This may be ideal for certain situations, such as easy parity between web and native versions of a project’s map. You can read more in the announcement blog post or in the sample iOS project.
Embedded interactivity (based on the UTFGrid specification) is a way to embed arbitrary point and region data with a tile map layer for fast and convenient recall when needed. See this map for an example. The primary advantage to this technology is fast interactivity in web browsers, but the Mapbox iOS SDK also features easy support for it for cross-platform use of the same maps.
In order to make use of UTFGrid interactivity on iOS, any
RMMapboxSource (online) or
RMMBTilesSource (offline) tile sources will have category methods added to them allowing querying of interactivity for a given map view and
CGPoint, suitable for use when the map is tapped or other gestures are applied. For example, tapping a given map point within a country’s borders might return the HTML-formatted content necessary to display the country’s name and flag image in a popup.
Mapbox offers unrestricted control for caching our maps such as Mapbox Streets on mobile devices with the Mapbox iOS SDK, supporting both app developers who want fine-grained control of app storage size and performance, as well as for users who want the optimum use of bandwidth and the best performance for the maps in an app.
In addition, background download of tiles directly into cache, without requiring a visible map view, can be performed in order to prepare for offline use. See the
RMTileCache class and the
RMTileCacheBackgroundDelegate protocol in the API for more information, including device- and processor architecture-based options for configuration.
How tiles are loaded
When a map view is shown and the user starts panning and zooming around to explore an area, the SDK requests the necessary tiles. The
RMMapboxSource tile source checks its local cache of tiles before ever trying to request data over the network, so if a tile has been downloaded recently, it is instantly recalled and used to load the map.
How the tile cache works
By default, the Route-Me rendering engine (upon which the SDK is based) stores the 1,000 most recently downloaded tile images. Once more room is needed, the oldest tiles are deleted from cache. You can also remove all tiles whenever desired with the
removeAllCachedImages method on
You can also manage cache deletion based on the age of tiles in the cache. For example, creating the
RMTileCache with an
604,800 (60 seconds
x 60 minutes
x 24 hours
x 7 days) will cause tiles to stay in the cache no longer than a week, without regard to the number of tiles, before the SDK will automatically delete the older tiles to keep things tidy. Setting an
expiryPeriod overrides any capacity-based configuration for the tile cache.
File-based cache configuration
Carried over from the Route-Me engine is the ability to configure cache behavior with a property list file included as a resource in your project. Below is a sample
routeme.plist file structure with inline comments. See the source to
RMTileCache.m for more information.
<?xml version='1.0' encoding='UTF-8'?> <!DOCTYPE plist PUBLIC '-//Apple//DTD PLIST 1.0//EN' 'http://www.apple.com/DTDs/PropertyList-1.0.dtd'> <plist version='1.0'> <dict> <key>caches</key> <array> <dict> <key>type</key> <string>db-cache</string> <!--(indicate that we"re configuring the database cache)--> <key>capacity</key> <integer>10000</integer> <!--(maximum tiles to store; defaults to 1,000)--> <key>expiryPeriod</key> <integer>86400</integer> <!--(maximum seconds to store tiles; overrides capacity; 0 = unlimited; defaults to unset)--> <key>minimalPurge</key> <integer>10</integer> <!--(minimum number to purge at a time when clearing; defaults to 10% of capacity)--> <key>strategy</key> <string>FIFO</string> <!--(FIFO = first in, first out; LRU = least recently used; defaults to FIFO)--> <key>useCachesDirectory</key> <true/> <!--(use the app Caches folder instead of Documents; defaults to false)--> </dict> <dict> <key>type</key> <string>memory-cache</string> <!--(indicate that we"re configuring the memory cache)--> <key>capacity</key> <integer>32</integer> <!--(maximum number of tiles to store in memory; defaults to 32)--> </dict> </array> </dict> </plist>
You must comply with the licensing terms of any map data in your application, including Mapbox Streets or other Mapbox maps if used. A small attribution control will be displayed on the map view automatically if attribution info is available from the tile source.
Mapbox Streets has retina tile support that can be utilized by the Mapbox iOS SDK. This brings high-DPI display support for devices such as the iPhone 4 and newer and the retina iPads.
Retina tiles use an enhanced look including wider streets and enlarged labels. The resulting image on retina-capable devices is incredibly sharp. Here’s a side-by-side comparison up close:
You don’t need to do anything special to support retina devices. Mapbox automatically adds the
@2x suffix to map tile requests and the platform automatically adjusts the tile content as necessary.