Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Version 3.1.1 and newer

 

Mapping SDK 3.0 Integration Guide (iOS)

 

Mapping Setup and Prerequisites

iOS Managed Provider Setup

  • Phunware recommends using CocoaPods to integrate the framework. Simply add pod 'PWMapKit' to your podfile.
  • Alternatively, all of the following frameworks can be added to the Vendor/Phunware directory of your project:
    • PWMapKit.framework
    • PWCore.framework
    • PWLocation.framework
  1. Initialize Cocoapods if your project does not already use it. If your environment does not already have Cocoapods installed, enter "sudo gem install cocoapods" in Terminal. After Cocoapods is installed, navigate to your project's root directory in the Terminal. Enter "pod init" in Terminal.
  2. In the Podfile file that is generated, modify the text in Xcode or your preferred text editor. Add the line "pod 'PWMapKit'" after the "target" line and before the "end" line. Save the file.
  3. Enter "pod install" in Terminal while in the directory that contains the Podfile.
  4. Use the .xcworkspace file that was generated by the pod install from now on.
  5. In your project's Info.plist file, add a row with key: "Privacy - Location When In Use Usage Description" (Xcode should autocomplete this) and for value, add what you want your users to see when prompted for Location use by the device.

 

Additional Documentation

Attribution

PWMapKit uses the following third-party components. All components are prefixed so you don't have to worry about namespace collisions.

ComponentDescriptionLicense
SVPulsingAnnotationViewA customizable MKUserLocationView replica for your iOS app.MIT

 

Sample Application

The framework comes with a ready-to-use sample application. In order to use this application you will need to update the configuration with your MaaS credentials and location provider information.

  1. Update your MaaS credentials and set up the building identifier in SampleConfiguration-Map.plist.

 

Usage

The primary use of the components of PWMapKit revolve around creating a map view, displaying points of interest, showing the user's location and indoor routing.

Here is an The example of shows how to instantiate a PWMapView and then load a building from the sample application, where "mapView" is a PWMapView property of calling class.

 

Code Block
themeMidnight
titleLoad Building
linenumberstrue
self.mapView = [[PWMapView alloc] initWithFrame:CGRectZero];
self.mapView.delegate = self; // self must conform to <PWMapViewDelegate> protocol
 
__weak typeof(self) weakself = self;
[PWBuilding buildingWithIdentifier:<#buildingIdentifier#> completion:^(PWBuilding *building, NSError *error) {
    if (building) {
        [weakself.mapView setBuilding:building];
    }
}];

 

Register Location Provider

PWMapView uses a specific PWMapViewLocationType to determine location, and most indoor location providers require a specific configuration to be passed in. Check with the location providers to see what specific configuration is required for each provider; the only location type that does not require a configuration is GPS, which will not be able to determine which floor the user is on. The location type may be set with the following call: <Old Description>

 

The PWMapView can display a user location on the map if a location provider is registered with the PWMapView.

The location providers are in the PWLocation framework, and each different provider requires different steps to set up (see readme here .

(See Readme at  https://github.com/phunware/maas-location-ios-sdk to view setup examples of all different provider options).

Once the location provider is initialized, the following call may be used to register the provider with the PWMapView.

Code Block
themeMidnight
titleSet Map Location Type
linenumberstrue
[mapView registerLocationManager:<managerObject>];

 

Indoor Location

The indoor location is provided by the PWLocation framework and can be accessed via the "userLocation" property of PWMapView.

Code Block
themeMidnight
titleIndoor Location
linenumberstrue
PWCustomLocation *userLocation = self.mapView.userLocation;

Routing for iOS Mapping

Calculate Route

Simply feed the PWRoute class method two points of interest and whether or not accessibility should be considered when calculating the route.

accessibility:YES will not use access points marked as "inaccessible" in the portal, e.g. stairs between floors.

Calculate then show route.

Code Block
themeMidnight
titleCalculate then show route
linenumberstrue
__weak typeof(self) weakSelf = self;
[PWRoute initRouteFrom:<#(PWPointOfInterest *)#> to:<#(PWPointOfInterest *)#> accessibility:<#(BOOL)#> completion:^(PWRoute *route, NSError *error) {
    [weakSelf.mapView navigateWithRoute:route]; // will begin routing in PWMapView
}];

 

Current Route Updates

As a user traverses a route, PWMapKit will post notifications to tell the developer when the next routing instruction was is reached.

Code Block
themeMidnight
titleRouting Updates
linenumberstrue
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(myInstructionUpdatedMethod:) name:PWRouteInstructionChangedNotificationKey object:nil];

 

Managed Provider

Displaying your Map

Step 1

In your AppDelegate.m implementation, add the following line to your "- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions" function, replacing the parameters with your App values, found on the MaaS portal.

Leave "encryptionKey" as an empty string.


Code Block
languagetext
[PWCore setApplicationID:@"YOUR_APP_ID" accessKey:@"YOUR_ACCESS_KEY" signatureKey:@"YOUR_SIGNATURE_KEY" encryptionKey:@""];

Image Added

Step 2: 

In the view controller that you wish to add the map view, add the following the top of the file.


Code Block
languagetext
#import <PWMapKit/PWMapKit.h>

Step 3: 

Add a PWMapView as a property of your view controller's "@interface":


Code Block
languagetext
@property (nonatomic, strong) PWMapView *mapView;

Step 4:

Add the PWMapViewDelegate protocol to your view controller:

Code Block
languagetext
@interface ViewController () <PWMapViewDelegate>

Step 5: 

The PWMapView will stretch to fit the entire superview for this example.

In your view controller's `-(void)viewDidLoad` function, add the following:this code.

Code Block
languagetext
self.mapView = [PWMapView new];
self.mapView.delegate = self;
self.mapView.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:self.mapView];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.mapView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeTop multiplier:1.0 constant:0.0]];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.mapView attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeBottom multiplier:1.0 constant:0.0]];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.mapView attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeLeading multiplier:1.0 constant:0.0]];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.mapView attribute:NSLayoutAttributeTrailing relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeTrailing multiplier:1.0 constant:0.0]];

Step 6:

To load your building, add the following below the code snippet shown above, using your building identifier found on the MaaS portal:.

 

Note
NOTE: The "dispatch_async" is currently required because of an internal SDK bug that will be fixed in the next release of PWMapKit/PWLocation.
Code Block
languagetext
__weak typeof(self) weakSelf = self;
[PWBuilding buildingWithIdentifier:YOUR_BUILDING_IDENTIFIER completion:^(PWBuilding *building, NSError *error) {
    dispatch_async(dispatch_get_main_queue(), ^{
        [weakSelf.mapView setBuilding:building];
    });
}];

 

Showing Current Location on the Map 

This will display your current location on your building map if the MaaS and hardware were also done configured properly. If you run into encounter issues, it is recommended to create the PWManagedLocationManager as a property and assign its delegate to your view controller rather than call calling registerLocationManager on the PWMapView. The error may then be captured with the PWLocationManagerDelegate callback function "- (void)locationManager:(id<PWLocationManager>)manager failedWithError:(NSError *)error;"

 

Step 1:

At the top of your view controller , add this code.

Code Block
languagetext
#import <PWLocation/PWLocation.h>

Step 2:

Modify the building load completion block so that it looks like the following:this.

Insert your building identifier in the denoted locations. If your building is configured to use Senion, delete the line that sets the "virtualBeaconToken" and insert your Senion map identifier and Senion customer identifier. If your building instead uses a virtual beacon technology such as Mist or Beacon Point, delete the "senionMapID" and "senionCustomerID" setting lines and insert your virtual beacon token, found on the Mist or Beacon Point portal.

Note
NOTE: The dispatch_async use is to workaround internal SDK issues which will be fixed in the next release of PWMapKit/PWLocation.
Code Block
languagetext
__weak typeof(self) weakSelf = self;
[PWBuilding buildingWithIdentifier:YOUR_BUILDING_IDENTIFIER completion:^(PWBuilding *building, NSError *error) {
    dispatch_async(dispatch_get_main_queue(), ^{
        [weakSelf.mapView setBuilding:building];
            
        PWManagedLocationManager *managedLocationManager = [[PWManagedLocationManager alloc] initWithBuildingId:YOUR_BUILDING_IDENTIFIER];
        managedLocationManager.senionMapID = @"YOUR_SENION_MAP_IDENTIFIER";
        managedLocationManager.senionCustomerID = @"YOUR_SENION_CUSTOMER_IDENTIFIER";
        managedLocationManager.virtualBeaconToken = @"YOUR_VIRTUAL_BEACON_TOKEN";
            
        dispatch_async(dispatch_get_main_queue(), ^{
            [weakSelf.mapView registerLocationManager:managedLocationManager];
        });
    });
}];

Step 3: 

Add a property to your view controller:.

Code Block
languagetext
@property (nonatomic, assign) BOOL isFirstLocationUpdate;

And in "- (void)viewDidLoad", set isFirstLocationUpdate to YES:.

Code Block
languagetext
self.isFirstLocationUpdate = YES;

Step 4:

Add the following delegate callback to your view controller that the PWMapView's delegate is set to:.

 

Note
NOTE: This workaround will be unnecessary in the next release of PWMapKit/PWLocation (3.1.2 and newer). Any mechanism you would like to use to only set the tracking mode once is fine.
Code Block
languagetext
- (void)mapView:(PWMapView *)mapView locationManager:(id<PWLocationManager>)locationManager didUpdateIndoorUserLocation:(PWIndoorLocation *)userLocation {
    if (self.isFirstLocationUpdate) {
        self.mapView.trackingMode = PWTrackingModeFollow;
        self.isFirstLocationUpdate = NO;
    }
}