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.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.