Chaim Friedman
Chaim Friedman

Reputation: 720

Swift Here API Examples

I'm incorporating the HERE SDK into my app. Aside from one simple map setup, all the examples on the HERE website are shown in objective-C, and I'm trying my best to translate them into Swift but it's not working 100% yet. I'm trying to put a route between 2 coordinates onto a map view as per their routing example shown at:

https://developer.here.com/mobile-sdks/documentation/ios/topics/routing.html

The interesting thing is that if I just call for the map everything works, but if I add the routing part I get the following error: NMAKit FATAL: License Key, App ID, or App Code not set. error on launch which is odd because the credentials are fine! So I think the bug is entirely in my Swift translation.

The instructions in objective-C are very clear:

1. Adopt NMARouteManagerDelegate protocol and create a NMARouteManager:

@interface ClassName : NSObject <NMARouteManagerDelegate>
{
  // Setup your class
}

(void)setup
{
Create a NMARouteManager.**

  NMARouteManager* routeManager = [NMARouteManager sharedRouteManager];

  // Setup delegate
  [routeManager setDelegate:self];
}

2. Create an NSMutableArray and add two NMAGeoCoordinates stops:

NSMutableArray* stops = [[NSMutableArray alloc] initWithCapacity:4];
NMAGeoCoordinates* geoCoord1 = [[NMAGeoCoordinates alloc]
initWithLatitude:49.1966286 longitude:-123.0053635];
NMAGeoCoordinates* geoCoord2 = [[NMAGeoCoordinates alloc]
initWithLatitude:49.1947289 longitude:-123.1762924];
[stops addObject:geoCoord1];
[stops addObject:geoCoord2];

3. Create an NMARoutingMode and set its NMATransportMode, NMARoutingType and NMARoutingOption values:

NMARoutingMode* routingMode = [[NMARoutingMode alloc]
initWithRoutingType:NMARoutingTypeFastest
transportMode:NMATransportModeCar
routingOptions:0];

4. Calculate the route:

[routeManager calculateRouteWithStops:stops routingMode:routingMode];

5. To receive the results of the route calculation, implement the NMARouteManagerDelegate protocol method routeManager:didCalculateRoutes:withError:violatedOptions: in your delegate class.

Note: Routes are returned even if you receive the NMARouteManagerErrorViolatesOptions error. It is up to you to handle these route results that violate routing options.

-(void) routeManager: (NMARouteManager*)routeManager
  didCalculateRoutes:(NSArray*)routes
  withError:(NMARouteManagerError)error
  violatedOptions:(NSArray*)violatedOptions
{
  // If the route was calculated successfully
  if (!error && routes && routes.count > 0)
  {
    NMARoute* route = [routes objectAtIndex:0];
    // Render the route on the map
    mapRoute = [NMAMapRoute mapRouteWithRoute:route];
    [mapView addMapObject:mapRoute];
  }
  else if (error)
  {
    // Display a message indicating route calculation failure
  }
}

And this is what I'm trying to do in Swift:

import UIKit



//I changed  the NMARouteManagerDelegate to my original class here
//and couldnt allow NSObject in the class delegation because it conflicts with UIViewController
class TestViewController: UIViewController, NMARouteManagerDelegate {
var mapCircle:NMAMapCircle?




@IBOutlet weak var mapView: NMAMapView!


@IBAction func get_route_action(sender: AnyObject) {


doRouting()

}

let routeManager = NMARouteManager.sharedRouteManager()



 func doRouting() {

 let geoCoord1 = NMAGeoCoordinates(latitude:41.350949, longitude:-74.182097)
 let geoCoord2 = NMAGeoCoordinates(latitude:41.3437502, longitude:-74.1624284)
 let stops = [geoCoord1, geoCoord2]
 routeManager.calculateRouteWithStops(stops)
 }




 func routeManager(routeManager: NMARouteManager!, didCalculateRoutes routes: [AnyObject]!, withError error: NMARouteManagerError, violatedOptions: [AnyObject]!) {
 print(routes)
 print(error)
 print(violatedOptions)
 guard error == NMARouteManagerError.None else {
 print("Route calculation error: \(error)")
 return
 }
 guard let routes = routes, route = routes[0] as? NMARoute else {
 print("Route calculation error: no routes")
 return
 }

 let mapRoute = NMAMapRoute(route: route)
 // Render the route on the map
 mapView.addMapObject(mapRoute)
 }




override func viewWillAppear(animated: Bool) {
    super.viewWillAppear(animated)
    //mapView.useHighResolutionMap = true
    var coordinates: NMAGeoCoordinates
    coordinates = NMAGeoCoordinates(latitude: 41.350949, longitude: -74.182097)
    mapView.zoomLevel = 13.2
    mapView.setGeoCenter(coordinates, withAnimation: NMAMapAnimation.Linear)
    mapView.copyrightLogoPosition = NMALayoutPosition.BottomCenter
    addMapCircle()
}

func addMapCircle() {
    if mapCircle == nil {
        let coordinates: NMAGeoCoordinates =
            NMAGeoCoordinates(latitude: 41.350949, longitude: -74.182097)
        mapCircle = NMAMapCircle(geoCoordinates: coordinates, radius: 50)
        mapView.addMapObject(mapCircle)
    }
}
override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}



}

Upvotes: 1

Views: 661

Answers (1)

Marco
Marco

Reputation: 2190

I tried your code, and worked basically for me quite fine.

But I additionally added the credentials in AppDelegate.swift:

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
        NMAApplicationContext.setAppId(YourAppID, appCode: YourToken, licenseKey: YourKey);
        return true;
    }

This is critical, since if it's missing, it's throwing exactly the error you get.

Upvotes: 1

Related Questions