MappedIn iOS SDK Example

This repo contains a simple example to get you started with the MappedIn iOS SDK. Before you can do anything, make sure you have an API key from MappedIn. Talk to your representative to get one.

Getting Started:

Before you can get started you need to get API keys and a customized Venue listing From your Mappedin rep. They will need to be added to your project.

From there you will start by accessing your map data via the Service API.

To view the data you can download from the Service API, see the MapView.

Changes:

v1.11.0 (May 11th, 2020)

  • Added Coordinate method to convert coordinate to CLLocationCoordinate2D.
  • Added tap delegate that provides the CLLocationCoordinate2D of a tap on the map.

v1.10.0 (April 8th, 2020)

  • Added ExitConnection action type for instructions and adjusted logic so that ExitConnection would be after every TakeConnection Action

v1.9.1 (March 30th, 2020)

  • Fixed bug where instruction for exiting connection isn’t appended to instruction list.

v1.9.0 (February 12th, 2020)

  • Added optional languageCode parameter to getVenue to request loading a venue for a specific language if available
  • Can access a list of all supported languages for Venue with venue.languageCodes, and the default language with venue.defaultLanguage

v1.8.0 (December 12th, 2019)

  • Added support to set the position of ImageOverlays and animate their movement.

v1.7.2 (December 4th, 2019)

  • Added support to change background color of mapView
  • Fixed multifloor directions logic to better handle escalators and better match behavior on our other platforms

v1.7.1 (November 21st, 2019)

  • Cleanup of unused project libraries

v1.7.0 (November 8th, 2019)

  • Upgrade to Swift 5.1.2
  • Adds support for multi-waypoint routing

v1.6.1 (October 25th, 2019)

  • Fixed Mappedin Search duplicates

v1.6.0 (September 24th, 2019)

  • Upgrade to Swift 5.1 and iOS 13

v1.6.0-beta (September 20th, 2019)

  • Upgrading to Swift 5.1 and iOS 13

v1.5.0 (September 12th, 2019)

  • Adds Mappedin Search capabilities

v1.4.4 (August 1st, 2019)

  • Fixed artifact appearing when drawing Overlays
  • Fixed PhoneNumber class to make it available publicly

v1.4.3 (July 9th, 2019)

  • Fixed an issue with accesible directions

v1.4.2 (June 28th, 2019)

  • Adds PhoneNumber class

v1.4.1 (May 15th, 2019)

  • Access to more properties for categories and venues

v1.4.0 (April 16th, 2019)

  • Migrate to using Swift 5

v1.3.0 (February 21st, 2019)

  • Added new APIs to get all polygons, or all locations in view of the camera and look up if a specific polygon or location is in view of the camera. “`swift // Returns a set of polygons currently in view of the camera mapview.polygonsInView()

// Returns a set of locations that have polygons currently in view of the camera mapView.locationsInView()

// Returns true if polygon is currently in view of the camera mapView.isInView(polygon: polygon)

// Returns true if location has polygons currently in view of the camera mapView.isInView(location: location)


*v1.2.1 (Febuary 8th, 2019)*
 - Bug Fix: Fixed a memory leak caused by a `Path` pulse animation.

*v1.2.0 (January 29th, 2019)*
 - Added support for a path pulse to the `Path` object.
   The `Path` pulse can be accessed as a set of options when you create the `Path`
   object. A `Path` pulse is a highlight that moves down the direction of the path
   to direct the user to the correct direction that the Path is leading them.
   This is identical to what is found in the Mappedin web SDK.

   ```swift
   /// we can enable the Path pulse
   let path = Path(
      points: directions.path,
      width: 2,
      height: 2,
      color: .blue,
      pulseEnabled: true
    )
  • Fixed bug in the Coordinate.meters(from: [Coordinate]) that would report the incorrect distance if a single point was given.

v1.1.1 (October 17th, 2018)

  • Fixed issue where adding overlays to the MapView could cause Z-fighting
  • Fixed Memory Leaks

v1.1.0 (September 18th, 2018)

  • Migrate to using Swift 4.2

v1.0.0 (September 14th, 2018)

  • Initial release of SDK for iOS 12

v0.21.0-beta (August 1st, 2018)

  • Added experimental ARKit support.

Requires

Requires iOS 10.

v0.20.0 (May 9th, 2018)

  • Performance for the Overlays has been improved for the Metal rendering path. Should render smoothly a 100+ overlays.

Bug

Bug Fix: Directions was not taking into account the weight of floor connections resulting in navigation taking shortcuts though other floors. This is now correctly handled.
  • Mappedin SDK requires iOS 9 to function

v0.19.0 (April 17th, 2018)

  • Fixed regression introduced in 0.18.0 that caused the Search API to not return any results
  • Added offline support for Service.getVenues, on first run of the API the list of venues will get saved to the device’s file system so that it can be restored in the case of an poor/no Internet connection. No changes are required by the SDK users to get this functionality.
  • The directions flag now has an accessible option that will choose the best path that is accessible for a person with limited mobility.

v0.18.0 (April 10th, 2018) Changes

  • Updated SDK to Swift 4.1.
  • Added support for cameraBounds to the MapView to prevent the users from scrolling away from the current map.

v0.17.0 (March 22nd, 2018) Changes

  • Added ability to specify touch target size minimumTouchSize of an overlay and the size of the overlay itself.

v0.16.0 (March 21st, 2018) Changes

  • Added a optional padding parameter to the MapView.frame API. This is to provide some visual space around the focused object
  • Added the ability for overlays to fetch vector map and coordinate if they were set when the element was created.

v0.15.0 (February 21st, 2018) Changes:

  • Fixes rendering bug that was caused by zFighting of the polygons
  • Fixes bug that causes store labels to not render when navigating back
  • Fixes render problems on iPhone 6’s running iOS 10.x
  • Fixed build issue that caused archived builds for iOS 10 targets to fail
  • Added support for arbitrary touch event routing to any Element in the MapView and restored support for the manipulatedCamera delegate function that indicates if a user’s touch has moved the Camera.

    • The MapViewDelegate has two new methods added to the protocol

      /// When a user taps on the `MapView` and one or more `Polygon` models are
      /// below it, this function will be called for each polygon.
      ///
      /// - parameter mapView:  which mapview the user tapped on
      /// - parameter polygon:  A polygon that was tapped
      ///
      /// - returns: if the delegate accepted he tapped event, returning
      ///            true will stop the `MapView` from searching for any
      ///            other element which could have been tapped and calling
      ///            a delegate function for them.
      ///
      /// Note: The `tapped` api always sends the event to the object that
      ///       closerst (ontop) of the camera view first.
      func tapped(_ mapView: MapView, polygon: Polygon) -> Bool
      
      /// When a user taps on the `MapView` and one or more `Element` models are
      /// below it, this function will be called for each `Element`
      ///
      /// - parameter mapView:  which mapview the user tapped on
      /// - parameter element: A `Element` that was tapped
      ///
      /// - returns: if the delegate accepted he tapped event, returning
      ///            true will stop the `MapView` from searching for any
      ///            other element which could have been tapped and calling
      ///            a delegate function for them.
      ///
      /// Note: The `tapped` api always sends the event to the object that
      ///       closerst (ontop) of the camera view first.
      func tapped(_ mapView: MapView, element: Element) -> Bool
      
      /// When a user moves the camera on the `MapView`, this function will be called.
      func manipulatedCamera()
      

v0.14.3 (February 13th, 2018)

  • Change the build settings to include bitcode for targets

v0.14.2 (February 1st, 2018)

  • Added the constructor Coordinate(vector: Vector3, map: Map)
  • Added a new API that allows for setting of store label text color ”`swift // The default color of a store labels may be changed to suit your color // scheme. mapview.storeLablesDefaultColor = .gray

// If one or more polygon’s store label’s text needs to be modified there // is a simple api for this. mapview.set(color: .blue, of: polygon)

// this can be cleared if you wish it to default to the default color mapview.resetColor(of: polygon)


*v0.14.1 (January 30th, 2018)*
 - Added a optional `minimumSize` parameter to the `MapView.frame` API. This
   is used to avoid zooming to to tightly to a single point.
 - Made public the `Location.type` field
 - Exported some missing methods for `Vector2` and `Vector3`
  - `Vector2.angle`
  - `Vector3` - `Vector3`
  - `Vecotr3` + `Vector3`
 - `Vector3`, `Location` now both implement the `Equatable` protocol
 - `Vector3` and `Coordinate` both implement the `Focusable` protocol

*v0.14.0 (January 26th, 2018)*
 - Added the Search and the Suggestion APIs. These allow the Apps to find
   locations inside a Venue.
   ```swift
   // The `search` field as been added to each and every Venue. It is a
   // protocol that implements the full `Search` functionality. This allows for
   // searching for locations in a venue. See the updated documentation for
   // full information on how this protocol works.

   // Before you can call any of the search APIS, you must create a SearchDelegate.
   struct MySearch: SearchDelegate {
      // Results returned from the suggestions API.
      func search(query: String, suggestions: [String]) {
      }

      // Results returned from the search call.
      func search(query: String, pagination: SearchPagination, results: [SearchResult]) {
        for result in results {
          // Currently the results can only be a location, but this may
          // be expanded in the future.
          switch result {
          case .location(let location):
            print("\(location.name)")
          }
        }
      }

      // Report any error that are encountered in any of the search APIs.
      func search(error: SearchError) {
          print(error)
      }
   }

   venue.search.delegate = MySearch()

   // This API is asynchronous, meaning it does not return here but will call
   // the delegate when the search is completed.
   venue.search.search(query: "some string", page: 1, timeout: 1)

Bug

Bug fix that fixes crash when routing between multiple levels of a Venue.

v0.13.0 (December 14th, 2017)

  • The HttpError code including, HttpError.httpErrorCode and HttpError.deserializableError. These indicate to the developer if the data downloaded is corrupted or if the API keys they have used are invalid.

Example of the new error codes

   myService.geVenue(venueListing)
      .onError({error in
          switch error {
          case .httpErrorCode(let code):
              print("Error code: \(code)")
          case .deserializableError(let deserializableError)
              print("Deserilization error: \(deserializableError)")
          default:
              print("Unhandled error: \(error)")
          }
      })
  • Added Store Label APIs to the MapView.

The MapView now has two properties storeLabelsEnable and storeLabelsDefaultFont. When storeLabelsEnable is set to true the MapView will render text labels over each store in the MapView. If a store already has a image assigned to it, the text will not be rendered and the image will be used instead.

Example of the new store labels API

   let mapView = MapView()

   // Enable the store labels
   mapView.storeLabelsEnable = true

   // Set the font, this will default to iOS's body font if you do not
   // manually set this parameter.
   //
   // Note: The size parameter is overrides by the sizing logic
   mapView.storeLabelsDefaultFont = UIFontDescriptor(name: "Symbol", size: 12)
  • Removed broken method from BinaryDecoder.

    There was an overload form ofpullValue that would return an optional value. This was removed because Swift never would overload to this function, instead it would select the pullValue with a none-optional value which was not does not have the desired behavior.

  • Removed the MapView.orbing method as it was not currently implemented

  • Deprecated the following functions, as they did not conform the the naming conventions used by Apple and were redundant.

    • Cylinder.setPosition
    • Cylinder.setDiameter
    • Cylinder.setHeight
    • Cylinder.setColor
    • Prism.setPosition
    • Prism.setDiameter
    • Prism.setHeight
    • Prism.setColor

v0.12.0 (November 3rd, 2017)

  • Initial release of the 0.12 SDK
  • Major API rework, this break backward comparability with 0.11

v0.11.0

  • Upgrade to Swift 3.

v0.10.0

  • Improved georeferencing accuracy.
  • New methods on Coordinate let you get the meters from another Coordinate, Path, or Polygon and check whether a Coordinate is inside a Polygon.
  • Renamed a number of method signatures to align with Swift 3.0’s naming conventions.

v0.9.0

  • Can now wayfind to/from Coordinates generated from arbitrary lat/longs. The path will connect directly to the closest real walkable node.
  • Markers can now be positioned and rotated dynamically. Just change their rotation property, or give them a new Coordinate

v0.8.0

  • Added iOS8 support to MapView (required custom OBJ file loader)
  • Improvements to MapView loading time
  • Added written directions for turns
  • Added analytics
  • Call Analytics.selectedLocation(location) and Analytics.selectedCategory(category) when the user selects locations and categories in your application (taps on a polygon, picks a category/location out of a list, selects a location/category during search, etc). It is up to your discretion what should count for your application.
  • Implemented MappedIn.Delegate for SDK configuration and lifecycle handling
  • The Direction class has been changed to the Directions.Instruction class
  • The Directions.directions property has been renamed to Directions.instructions
  • The Directions.Instruction.instruction property has been renamed to Directions.Instruction.description
  • You must add a property called “mappedInDelegate” to your AppDelegate with an instance of MappedIn.Delegate
  • In Swift: swift class AppDelegate: UIApplicationDelegate { let mappedInDelegate = MappedIn.Delegate(AppDelegate)
  • In Objective-C: objective-c - (id)init { MIDelegate *mappedInDelegate = [[MIDelegate alloc] init:AppDelegate.self]
  • The locationGenerator argument on getVenue() is being replaced by the Delegate.generateLocation method
  • To use a custom generateLocation method, create your own Delegate class inheriting from MappedIn.Delegate and override the Delegate.generateLocation method. Set your AppDelegate.mappedInDelegate property to an instance of your custom class instead of the default MappedIn.Delegate class

v0.7.0

  • You can check if a MapViewMarker is already part of a MapView with mapview.hasMarker(marker), and adding a marker that’s true of will no longer cause a crash.

v0.6.0

  • Added focusOn for arrays of Polygons
  • Camera panning tracks fingers in orthographic and perspective mode
  • focusScaleZoom = 1.0 should be the tightest zoom possible

v0.5.0

  • Implemented animated paths
  • The elevation property on the MapView.Path class has been removed. The Path will now stick to z=0
  • The MapView.Path class has gained a height property specifying the height of the path when rendered
  • Changed maxCameraPitch property to maxPitch

v0.4.0:

  • Added orthographic camera support
  • Fixed animation bug
  • Fixed polygon logos blocking taps

v0.3.0

  • Implemented Custom Location Types

v0.2.0:

  • Update to Swift 2.2
  • Rename Node to Coordinate
  • Replace MapAnchor with Coordinates
  • Coordinates gain the ability to be created from a Polygon (for MapAnchor support) and CLLocationCoordinate2D (latitude/longitude)
  • Exposed the SCNView on the MapView
  • A lot of under the hood work on georeferencing Map’s

Roadmap

Short Term:

  • Map loading time improvements
  • MapView refactor and API cleanup
  • Venue loading time improvements
  • Mappedin Events API
  • Directions improvements

Long Term:

  • Offline data caching
  • Geolocation based Venue prefetching
  • Indoor Positioning

Setup

  1. Start by cloning this repo (or downloading the zip if you don’t like git).
  2. Use Cocoa Pods to install the latest version of the MappedIn.framework
    • The sample repo contains an example .podfile configured to install the framework.
  3. Open the included Workspace in XCode.
  4. Build the Example project
  5. Open info.plist and input your MappedInUsername and MappedInPassword. If you don’t know what those are, talk to your MappedIn representative.
  6. Run!

API Quick Start

You can view all the documentation in this project’s GitHub Page, but here’s a quick start guide to just displaying a Map.

Let’s go through the key classes provided by the SDK and when you would use them.

MappedIn

This is the class to start with. It controls all communication with the MappedIn API. Make sure you have your API key and Secret set in your .plist file, and then call

MappedIn.getVenues(callBack: (venue: [Venue]) -> Void)

This will query the MappedIn servers and execute the callBack function you provided with a list of Venues your key has access to. Each Venue will have basic details like the name and logo populated, but not the larger fields like maps and locations.

To get all of the data for a specific venue, call

MappedIn.getVenue(venue: Venue, callBack: (Venue) -> Void)

Similar to getVenues, this function will interface with the MappedIn API for you, sending the fully populated Venue to your callback when it’s done.

Venue

The Venue object will contain all information associated with a given venue (once it’s been filled in with getVenue).

MapView

The MapView class will display your your map for you/ Once you have a populated venue, set the .venue property on your MapView and call yourMapView.loadScene()

That’s the basics. Directions, Markers and other features will be covered in a future tutorial, but you can see them in action right now in the Single Venue project.