iOS

This tutorial will walk you through the specifics of the iOS SDK beyond what is covered in Getting Started.

Connecting and Authentication

There are two steps in the Pathfinder connection process: establishing the web socket and authenticating the connection. If you are using Pathfinder hosted authentication, the SDK provides a convenience method that encapsulates the two steps together.

import thepathfinder

let applicationIdentifier = "b14d0ce3-981c-48bc-ae9f-c600647b48fa"

let pf = Pathfinder(applicationIdentifier: applicationIdentifier)
pf.connect() { (connectionId: String) -> Void in
  // send connectionId to your backend server in preparation for auth request
  pf.authenticate() { (success: Bool) -> Void in
    if (success) {
      // continue to use Pathfinder
    }
  }
}
import thepathfinder

// Acquire Google ID token from Google Sign-In
let userGoogleIDToken = ...

let applicationIdentifier = "b14d0ce3-981c-48bc-ae9f-c600647b48fa"

let pf = Pathfinder(applicationIdentifier: applicationIdentifier)
pf.connectAndAuthenticateWithPathfinderAuth(userGoogleIDToken) { (success: Boolean) -> Void in
  if (success) {
  	// Continue to use Pathfinder
  }
}

Delegates

Pathfinder is a real-time service and all updates are exposed via three delegate protocols. To listen to your clusters, transports and commodities simply extend the delegate protocol and implement the functions that you need.

The following code blocks depict the three common use cases for Pathfinder in mobile applications and describe the delegate methods that are available.

import Foundation
import thepathfinder

class EmployeeViewController : UIViewController {
	var idToken: String!
  let metadata: [String:Int] = ["mpg": 20, "person": 4]
  let appId = "b14d0ce3-981c-48bc-ae9f-c600647b48fa"

  override func viewDidLoad() {
  	super.viewDidLoad()
    
    let pf = Pathfinder(applicationIdentifier: appId)
    pf.connectAndAuthenticateWithPathfinderAuth(idToken) { (success: Bool) -> Void in
    	if (success) {
      	let transport = pf.cluster().createTransport(Transport.Status.Offline, metadata: metadata)
        transport.delegate = self
        transport.connect()
      }
    }
  }
}

extension EmployeeViewController : TransportDelegate {

  func connected(transport: Transport) {
  	// Executed after `transport.connect()` and the web socket is established.
    transport.subscribe()
  }

  func wasRouted(route: Route, transport: Transport) {
  	// Executed when the transport is assigned a route by the Pathfinder service.
  }

  func performedRouteAction(action: RouteAction, transport: Transport) {
  	// Executed after the transport in question picked up or dropped off a commodity.
  }

  func didGoOnline(transport: Transport) {
  	// Executed after Pathfinder acknowledges the transport as ONLINE.
  }

  func didGoOffline(transport: Transport) {
  	// Executed after Pathfinder acknowledges the transport as OFFLINE.
  }
}
import Foundation
import thepathfinder

class CustomerViewController : UIViewController {
	var idToken: String!
  let metadata: [String:Int] = ["person": 1]
  let appId = "b14d0ce3-981c-48bc-ae9f-c600647b48fa"
  
  let startLocation = CLLocationCoordinate2D(latitude: 40.71, longitude: 74.00)
	let endLocation = CLLocationCoordinate2D(latitude: 41.34, longitude: 74.39)

  override func viewDidLoad() {
  	super.viewDidLoad()
    
    let pf = Pathfinder(applicationIdentifier: appId)
    pf.connectAndAuthenticateWithPathfinderAuth(idToken) { (success: Bool) -> Void in
    	if (success) {
      	let commodity = pf.cluster().createCommodity(start: startLocation, destination: endLocation, metadata: metadata)
        commodity.delegate = self
        commodity.connect()
      }
    }
  }
}

extension CustomerViewController : CommodityDelegate {

  func connected(commodity: Commodity) {
  	// Executed after `commodity.connect()` and the web socket is established
    commodity.subscribe()
  }

  func wasPickedUpAt(location: CLLocationCoordinate2D, commodity: Commodity, byTransport: Transport) {
  	// Executed after a Transport performs the pickup route action for this commodity
  }

  func wasDroppedOffAt(location: CLLocationCoordinate2D, commodity: Commodity) {
  	// Executed after a Transport performs the dropoff route action for this commodity
  }

  func wasCancelled(commodity: Commodity) {
  	// Executed after the commodity's status is set to cancelled
  }

  func wasRouted(commodity: Commodity, byTransport: Transport, onRoute: Route) {
  	// Executed after a transport is assigned a route that includes this commodity
  }
}
import Foundation
import thepathfinder

class ClusterViewController : UIViewController {
  var idToken: String!
  let appId = "b14d0ce3-981c-48bc-ae9f-c600647b48fa"
  let path = "/root/eastcoast/nyc"
  
  let startLocation = CLLocationCoordinate2D(latitude: 40.71, longitude: 74.00)
  let endLocation = CLLocationCoordinate2D(latitude: 41.34, longitude: 74.39)

  override func viewDidLoad() {
    super.viewDidLoad()
    
    let pf = Pathfinder(applicationIdentifier: appId)
    pf.connectAndAuthenticateWithPathfinderAuth(idToken) { (success: Bool) -> Void in
      if (success) {
      	let cluster = pf.cluster(path)
        cluster.delegate = self
        cluster.connect()
      }
    }
  }
}

extension ClusterViewController : ClusterDelegate {

  func connected(cluster: Cluster) {
  	// Executed after `cluster.connect()` and the cluster is verified to exist
  	cluster.subscribe()
  }

  func transportDidComeOnline(transport: Transport) {
  	// Executed when a transport status is set to Transport.Status.Online
  }

  func transportDidGoOffline(transport: Transport) {
  	// Executed when a transport status is set to Transport.Status.Offline
  }

  func commodityWasRequested(commodity: Commodity) {
  	// Executed when a commodity is created
  }

  func commodityWasPickuped(commodity: Commodity) {
		// Executed when a transport picks up a commodity  
  }

  func commodityWasDroppedOff(commodity: Commodity) {
  	// Executed when a transport drops off a commodity
  }

  func commodityWasCancelled(commodity: Commodity) {
  	// Executed when a commodity request is cancelled
  }

  func clusterWasRouted(routes: [Route]) {
  	// Executed when the Pathfinder service calculates a new set of routes for the cluster
  }
}