{"_id":"571be82bbdf08c0e003f4595","githubsync":"","parentDoc":null,"user":"56a975c12d8fd90d0036eed0","category":{"_id":"571d5ae118b3c10e003e55cd","version":"56a83b989ec7660d002e07c1","__v":0,"project":"56a83b979ec7660d002e07be","sync":{"url":"","isSync":false},"reference":false,"createdAt":"2016-04-24T23:46:41.975Z","from_sync":false,"order":0,"slug":"tutorials","title":"Tutorials"},"project":"56a83b979ec7660d002e07be","__v":86,"version":{"_id":"56a83b989ec7660d002e07c1","project":"56a83b979ec7660d002e07be","__v":9,"createdAt":"2016-01-27T03:38:00.333Z","releaseDate":"2016-01-27T03:38:00.333Z","categories":["56a83b989ec7660d002e07c2","56a83c282036420d002d21e1","56a96de8f834950d0037b35a","56a9706013a69a0d00a778c3","56a970ec2d8fd90d0036eec7","56a971a62bb3910d000ee934","56a973372d8fd90d0036eece","56a978dc2bb3910d000ee93f","571d5ae118b3c10e003e55cd"],"is_deprecated":false,"is_hidden":false,"is_beta":false,"is_stable":true,"codename":"Beta","version_clean":"1.0.0","version":"1.0"},"updates":[],"next":{"pages":[],"description":""},"createdAt":"2016-04-23T21:24:59.523Z","link_external":false,"link_url":"","sync_unique":"","hidden":false,"api":{"results":{"codes":[]},"settings":"","auth":"required","params":[],"url":""},"isReference":false,"order":2,"body":"<div class=\"corner-ribbon top-left sticky blue\"><a style=\"color: white;\" href=\"https://pathfinder.readme.io/blog/pathfinder-now-in-public-beta\">Public Beta!</a></div>\n\nThis tutorial will walk you through the specifics of the iOS SDK beyond what is covered in [Getting Started](doc:getting-started).\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"Connecting and Authentication\"\n}\n[/block]\nThere 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.\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"import thepathfinder\\n\\nlet applicationIdentifier = \\\"b14d0ce3-981c-48bc-ae9f-c600647b48fa\\\"\\n\\nlet pf = Pathfinder(applicationIdentifier: applicationIdentifier)\\npf.connect() { (connectionId: String) -> Void in\\n  // send connectionId to your backend server in preparation for auth request\\n  pf.authenticate() { (success: Bool) -> Void in\\n    if (success) {\\n      // continue to use Pathfinder\\n    }\\n  }\\n}\",\n      \"language\": \"swift\",\n      \"name\": \"Custom Auth\"\n    },\n    {\n      \"code\": \"import thepathfinder\\n\\n// Acquire Google ID token from Google Sign-In\\nlet userGoogleIDToken = ...\\n\\nlet applicationIdentifier = \\\"b14d0ce3-981c-48bc-ae9f-c600647b48fa\\\"\\n\\nlet pf = Pathfinder(applicationIdentifier: applicationIdentifier)\\npf.connectAndAuthenticateWithPathfinderAuth(userGoogleIDToken) { (success: Boolean) -> Void in\\n  if (success) {\\n  \\t// Continue to use Pathfinder\\n  }\\n}\",\n      \"language\": \"swift\",\n      \"name\": \"Pathfinder Auth\"\n    }\n  ]\n}\n[/block]\n\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"Delegates\"\n}\n[/block]\nPathfinder 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.\n\nThe following code blocks depict the three common use cases for Pathfinder in mobile applications and describe the delegate methods that are available.\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"import Foundation\\nimport thepathfinder\\n\\nclass EmployeeViewController : UIViewController {\\n\\tvar idToken: String!\\n  let metadata: [String:Int] = [\\\"mpg\\\": 20, \\\"person\\\": 4]\\n  let appId = \\\"b14d0ce3-981c-48bc-ae9f-c600647b48fa\\\"\\n\\n  override func viewDidLoad() {\\n  \\tsuper.viewDidLoad()\\n    \\n    let pf = Pathfinder(applicationIdentifier: appId)\\n    pf.connectAndAuthenticateWithPathfinderAuth(idToken) { (success: Bool) -> Void in\\n    \\tif (success) {\\n      \\tlet transport = pf.cluster().createTransport(Transport.Status.Offline, metadata: metadata)\\n        transport.delegate = self\\n        transport.connect()\\n      }\\n    }\\n  }\\n}\\n\\nextension EmployeeViewController : TransportDelegate {\\n\\n  func connected(transport: Transport) {\\n  \\t// Executed after `transport.connect()` and the web socket is established.\\n    transport.subscribe()\\n  }\\n\\n  func wasRouted(route: Route, transport: Transport) {\\n  \\t// Executed when the transport is assigned a route by the Pathfinder service.\\n  }\\n\\n  func performedRouteAction(action: RouteAction, transport: Transport) {\\n  \\t// Executed after the transport in question picked up or dropped off a commodity.\\n  }\\n\\n  func didGoOnline(transport: Transport) {\\n  \\t// Executed after Pathfinder acknowledges the transport as ONLINE.\\n  }\\n\\n  func didGoOffline(transport: Transport) {\\n  \\t// Executed after Pathfinder acknowledges the transport as OFFLINE.\\n  }\\n}\",\n      \"language\": \"swift\",\n      \"name\": \"Transport Delegate\"\n    },\n    {\n      \"code\": \"import Foundation\\nimport thepathfinder\\n\\nclass CustomerViewController : UIViewController {\\n\\tvar idToken: String!\\n  let metadata: [String:Int] = [\\\"person\\\": 1]\\n  let appId = \\\"b14d0ce3-981c-48bc-ae9f-c600647b48fa\\\"\\n  \\n  let startLocation = CLLocationCoordinate2D(latitude: 40.71, longitude: 74.00)\\n\\tlet endLocation = CLLocationCoordinate2D(latitude: 41.34, longitude: 74.39)\\n\\n  override func viewDidLoad() {\\n  \\tsuper.viewDidLoad()\\n    \\n    let pf = Pathfinder(applicationIdentifier: appId)\\n    pf.connectAndAuthenticateWithPathfinderAuth(idToken) { (success: Bool) -> Void in\\n    \\tif (success) {\\n      \\tlet commodity = pf.cluster().createCommodity(start: startLocation, destination: endLocation, metadata: metadata)\\n        commodity.delegate = self\\n        commodity.connect()\\n      }\\n    }\\n  }\\n}\\n\\nextension CustomerViewController : CommodityDelegate {\\n\\n  func connected(commodity: Commodity) {\\n  \\t// Executed after `commodity.connect()` and the web socket is established\\n    commodity.subscribe()\\n  }\\n\\n  func wasPickedUpAt(location: CLLocationCoordinate2D, commodity: Commodity, byTransport: Transport) {\\n  \\t// Executed after a Transport performs the pickup route action for this commodity\\n  }\\n\\n  func wasDroppedOffAt(location: CLLocationCoordinate2D, commodity: Commodity) {\\n  \\t// Executed after a Transport performs the dropoff route action for this commodity\\n  }\\n\\n  func wasCancelled(commodity: Commodity) {\\n  \\t// Executed after the commodity's status is set to cancelled\\n  }\\n\\n  func wasRouted(commodity: Commodity, byTransport: Transport, onRoute: Route) {\\n  \\t// Executed after a transport is assigned a route that includes this commodity\\n  }\\n}\",\n      \"language\": \"swift\",\n      \"name\": \"Commodity Delegate\"\n    },\n    {\n      \"code\": \"import Foundation\\nimport thepathfinder\\n\\nclass ClusterViewController : UIViewController {\\n  var idToken: String!\\n  let appId = \\\"b14d0ce3-981c-48bc-ae9f-c600647b48fa\\\"\\n  let path = \\\"/root/eastcoast/nyc\\\"\\n  \\n  let startLocation = CLLocationCoordinate2D(latitude: 40.71, longitude: 74.00)\\n  let endLocation = CLLocationCoordinate2D(latitude: 41.34, longitude: 74.39)\\n\\n  override func viewDidLoad() {\\n    super.viewDidLoad()\\n    \\n    let pf = Pathfinder(applicationIdentifier: appId)\\n    pf.connectAndAuthenticateWithPathfinderAuth(idToken) { (success: Bool) -> Void in\\n      if (success) {\\n      \\tlet cluster = pf.cluster(path)\\n        cluster.delegate = self\\n        cluster.connect()\\n      }\\n    }\\n  }\\n}\\n\\nextension ClusterViewController : ClusterDelegate {\\n\\n  func connected(cluster: Cluster) {\\n  \\t// Executed after `cluster.connect()` and the cluster is verified to exist\\n  \\tcluster.subscribe()\\n  }\\n\\n  func transportDidComeOnline(transport: Transport) {\\n  \\t// Executed when a transport status is set to Transport.Status.Online\\n  }\\n\\n  func transportDidGoOffline(transport: Transport) {\\n  \\t// Executed when a transport status is set to Transport.Status.Offline\\n  }\\n\\n  func commodityWasRequested(commodity: Commodity) {\\n  \\t// Executed when a commodity is created\\n  }\\n\\n  func commodityWasPickuped(commodity: Commodity) {\\n\\t\\t// Executed when a transport picks up a commodity  \\n  }\\n\\n  func commodityWasDroppedOff(commodity: Commodity) {\\n  \\t// Executed when a transport drops off a commodity\\n  }\\n\\n  func commodityWasCancelled(commodity: Commodity) {\\n  \\t// Executed when a commodity request is cancelled\\n  }\\n\\n  func clusterWasRouted(routes: [Route]) {\\n  \\t// Executed when the Pathfinder service calculates a new set of routes for the cluster\\n  }\\n}\",\n      \"language\": \"swift\",\n      \"name\": \"Cluster Delegate\"\n    }\n  ]\n}\n[/block]","excerpt":"","slug":"ios-delegates","type":"basic","title":"iOS"}
<div class="corner-ribbon top-left sticky blue"><a style="color: white;" href="https://pathfinder.readme.io/blog/pathfinder-now-in-public-beta">Public Beta!</a></div> This tutorial will walk you through the specifics of the iOS SDK beyond what is covered in [Getting Started](doc:getting-started). [block:api-header] { "type": "basic", "title": "Connecting and Authentication" } [/block] 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. [block:code] { "codes": [ { "code": "import thepathfinder\n\nlet applicationIdentifier = \"b14d0ce3-981c-48bc-ae9f-c600647b48fa\"\n\nlet pf = Pathfinder(applicationIdentifier: applicationIdentifier)\npf.connect() { (connectionId: String) -> Void in\n // send connectionId to your backend server in preparation for auth request\n pf.authenticate() { (success: Bool) -> Void in\n if (success) {\n // continue to use Pathfinder\n }\n }\n}", "language": "swift", "name": "Custom Auth" }, { "code": "import thepathfinder\n\n// Acquire Google ID token from Google Sign-In\nlet userGoogleIDToken = ...\n\nlet applicationIdentifier = \"b14d0ce3-981c-48bc-ae9f-c600647b48fa\"\n\nlet pf = Pathfinder(applicationIdentifier: applicationIdentifier)\npf.connectAndAuthenticateWithPathfinderAuth(userGoogleIDToken) { (success: Boolean) -> Void in\n if (success) {\n \t// Continue to use Pathfinder\n }\n}", "language": "swift", "name": "Pathfinder Auth" } ] } [/block] [block:api-header] { "type": "basic", "title": "Delegates" } [/block] 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. [block:code] { "codes": [ { "code": "import Foundation\nimport thepathfinder\n\nclass EmployeeViewController : UIViewController {\n\tvar idToken: String!\n let metadata: [String:Int] = [\"mpg\": 20, \"person\": 4]\n let appId = \"b14d0ce3-981c-48bc-ae9f-c600647b48fa\"\n\n override func viewDidLoad() {\n \tsuper.viewDidLoad()\n \n let pf = Pathfinder(applicationIdentifier: appId)\n pf.connectAndAuthenticateWithPathfinderAuth(idToken) { (success: Bool) -> Void in\n \tif (success) {\n \tlet transport = pf.cluster().createTransport(Transport.Status.Offline, metadata: metadata)\n transport.delegate = self\n transport.connect()\n }\n }\n }\n}\n\nextension EmployeeViewController : TransportDelegate {\n\n func connected(transport: Transport) {\n \t// Executed after `transport.connect()` and the web socket is established.\n transport.subscribe()\n }\n\n func wasRouted(route: Route, transport: Transport) {\n \t// Executed when the transport is assigned a route by the Pathfinder service.\n }\n\n func performedRouteAction(action: RouteAction, transport: Transport) {\n \t// Executed after the transport in question picked up or dropped off a commodity.\n }\n\n func didGoOnline(transport: Transport) {\n \t// Executed after Pathfinder acknowledges the transport as ONLINE.\n }\n\n func didGoOffline(transport: Transport) {\n \t// Executed after Pathfinder acknowledges the transport as OFFLINE.\n }\n}", "language": "swift", "name": "Transport Delegate" }, { "code": "import Foundation\nimport thepathfinder\n\nclass CustomerViewController : UIViewController {\n\tvar idToken: String!\n let metadata: [String:Int] = [\"person\": 1]\n let appId = \"b14d0ce3-981c-48bc-ae9f-c600647b48fa\"\n \n let startLocation = CLLocationCoordinate2D(latitude: 40.71, longitude: 74.00)\n\tlet endLocation = CLLocationCoordinate2D(latitude: 41.34, longitude: 74.39)\n\n override func viewDidLoad() {\n \tsuper.viewDidLoad()\n \n let pf = Pathfinder(applicationIdentifier: appId)\n pf.connectAndAuthenticateWithPathfinderAuth(idToken) { (success: Bool) -> Void in\n \tif (success) {\n \tlet commodity = pf.cluster().createCommodity(start: startLocation, destination: endLocation, metadata: metadata)\n commodity.delegate = self\n commodity.connect()\n }\n }\n }\n}\n\nextension CustomerViewController : CommodityDelegate {\n\n func connected(commodity: Commodity) {\n \t// Executed after `commodity.connect()` and the web socket is established\n commodity.subscribe()\n }\n\n func wasPickedUpAt(location: CLLocationCoordinate2D, commodity: Commodity, byTransport: Transport) {\n \t// Executed after a Transport performs the pickup route action for this commodity\n }\n\n func wasDroppedOffAt(location: CLLocationCoordinate2D, commodity: Commodity) {\n \t// Executed after a Transport performs the dropoff route action for this commodity\n }\n\n func wasCancelled(commodity: Commodity) {\n \t// Executed after the commodity's status is set to cancelled\n }\n\n func wasRouted(commodity: Commodity, byTransport: Transport, onRoute: Route) {\n \t// Executed after a transport is assigned a route that includes this commodity\n }\n}", "language": "swift", "name": "Commodity Delegate" }, { "code": "import Foundation\nimport thepathfinder\n\nclass ClusterViewController : UIViewController {\n var idToken: String!\n let appId = \"b14d0ce3-981c-48bc-ae9f-c600647b48fa\"\n let path = \"/root/eastcoast/nyc\"\n \n let startLocation = CLLocationCoordinate2D(latitude: 40.71, longitude: 74.00)\n let endLocation = CLLocationCoordinate2D(latitude: 41.34, longitude: 74.39)\n\n override func viewDidLoad() {\n super.viewDidLoad()\n \n let pf = Pathfinder(applicationIdentifier: appId)\n pf.connectAndAuthenticateWithPathfinderAuth(idToken) { (success: Bool) -> Void in\n if (success) {\n \tlet cluster = pf.cluster(path)\n cluster.delegate = self\n cluster.connect()\n }\n }\n }\n}\n\nextension ClusterViewController : ClusterDelegate {\n\n func connected(cluster: Cluster) {\n \t// Executed after `cluster.connect()` and the cluster is verified to exist\n \tcluster.subscribe()\n }\n\n func transportDidComeOnline(transport: Transport) {\n \t// Executed when a transport status is set to Transport.Status.Online\n }\n\n func transportDidGoOffline(transport: Transport) {\n \t// Executed when a transport status is set to Transport.Status.Offline\n }\n\n func commodityWasRequested(commodity: Commodity) {\n \t// Executed when a commodity is created\n }\n\n func commodityWasPickuped(commodity: Commodity) {\n\t\t// Executed when a transport picks up a commodity \n }\n\n func commodityWasDroppedOff(commodity: Commodity) {\n \t// Executed when a transport drops off a commodity\n }\n\n func commodityWasCancelled(commodity: Commodity) {\n \t// Executed when a commodity request is cancelled\n }\n\n func clusterWasRouted(routes: [Route]) {\n \t// Executed when the Pathfinder service calculates a new set of routes for the cluster\n }\n}", "language": "swift", "name": "Cluster Delegate" } ] } [/block]