Getting Started: iOS

Minumum Operating System

8.0+

Get API keys

If you do not have a Foursquare API key whitelisted for Pilgrim access, read our guide on Foursquare API Access.

Set up your Foursquare App

In order for Pilgrim SDK to authenticate with our server, you’ll need to add your iOS Bundle ID to your Foursquare app’s configuration. This can be found in your project’s General tab:

Navigate to your Foursquare app settings page here: foursquare.com/developers/app/CLIENT_ID

  1. Near the bottom of the page, under Install options, paste your iOS Bundle ID in the iOS Bundle IDs field.
  2. Click Save changes.


Set Up

  1. Add the following to your Cartfile:
  1. Navigate to Carthage/Build/iOS and drag the Pilgrim.framework file into Xcode in the Link Binary With Libraries section.
  2. Add a run script with the following script:

Set the Input Files to:

  1. Load the Pilgrim library into any necessary files by adding import Pilgrim.
  2. Build your project.
  1. If you don’t already have CocoaPods initated in your project, enter the following command into the terminal: pod init
  2. Add the following to your Podfile:
  1. Enter the following command into the terminal: pod install (If you experience errors, try pod update. You can read about the difference here.)
  2. Load the Pilgrim library into any necessary files by adding import Pilgrim.
  3. Build your project.
  1. Download and unzip the latest release.
  2. Embed the framework. Drag Pilgrim.framework into your project’s Embedded Binaries section in the project editor. In the sheet that appears, make sure “Copy items if needed” is checked, then click Finish.
  3. Load the Pilgrim library into any necessary files by adding import Pilgrim.
  4. Under the Build Phases tab, add this run script (for manual installs only):
  1. Build your project.

Permissions

Make sure to turn Background Modes to On in your project’s Capabilities tab and enable the Location updates checkbox:

Add the following to your iOS permission strings in your project’s Info.plist file:

  • Privacy - Location Always Usage Description
  • Privacy - Location Always and When In Use Usage Description
  • Privacy - Location When In Use Usage Description

For example:


Configure and Start Pilgrim

1. Configure Pilgrim in your AppDelegate

Configure Pilgrim by pasting the following code in the didFinishLaunchingWithOptions method of your AppDelegate. Be sure to replace CLIENT_ID and CLIENT_SECRET with your real API credentials.

PilgrimManager.shared().configure(withConsumerKey: "CLIENT_ID", secret: "CLIENT_SECRET", delegate: self, completion: nil)

2. Conform to Pilgrim Delegate

Have your AppDelegate conform PilgrimManagerDelegate by pasting the following code just below your AppDelegate class:

extension AppDelegate : PilgrimManagerDelegate {
  // Primary visit handler:
  func pilgrimManager(_ pilgrimManager: PilgrimManager, handle visit: Visit) {
    // Process the visit however you'd like:
    print("\(visit.hasDeparted ? "Departure from" : "Arrival at") \(visit.venue != nil ? visit.venue!.name : "Unknown venue."). Added a Pilgrim visit at: \(visit.displayName)")
  }

  // Optional: If visit occurred without network connectivity
  func pilgrimManager(_ pilgrimManager: PilgrimManager, handleBackfill visit: Pilgrim.Visit) {
    // Process the visit however you'd like:
    print("Backfill \(visit.hasDeparted ? "departure from" : "arrival at") \(visit.venue != nil ? visit.venue!.name : "Unknown venue."). Added a Pilgrim backfill visit at: \(visit.displayName)")
  }

  // Optional: If visit occurred by triggering a geofence
  func pilgrimManager(_ pilgrimManager: PilgrimManager, handle geofenceEvents: [GeofenceEvent]) {
    // Process the geofence events however you'd like:
    geofenceEvents.forEach { geofenceEvent in
      print(geofenceEvent)
    }
  }
}

Note the three delegate callbacks you may receive:

  • handle visit: The primary visit callback that receives arrival and departure events.
  • handleBackfill visit: This callback receives visits that occurred historically when there was no network connectivity or for failed visits that have been retried.
  • handle geofenceEvents: This callback receives any genfence events configured in the Pilgrim console.

3. Start Pilgrim

Once Pilgrim is configured, you can start running it by calling start after the configuration method in your AppDelegate:

PilgrimManager.shared().start()

Note: You must make sure the user has accepted background location permissions before starting the SDK. We provide a convenience method for requesting the ‘Always On’ location permission. However, you are not required to use this method.

PilgrimManager.shared().requestAlwaysAuthorization { (authorized) in
    if authorized {
        PilgrimManager.shared().start()
    } else {
        // user rejected location permissions
    }
}

4. Handle Visits

With Pilgrim properly configured, the delegate method(s) should be hit whenever you arrive or depart at one of our 105M+ places around the world. In order to test your visit callback without physically walking around, we provide a testing class visitTester. This class can be used to simulate visits with different confidence levels and location types.

For example, the following code will simulate a visit at a given lat/lng:

PilgrimManager.shared().visitTester.fireTestVisit(location: CLLocation(latitude: 37.7904311, longitude: -122.4066613))

The following code will trigger a medium confidence arrival at a venue:

PilgrimManager.shared().visitTester.fireTestVisit(confidence: .medium, type: .venue, departure: false)

Tips

Get Current Location

By default, Pilgrim SDK runs in the background and pushes you visits when it detects a stop. You can also actively request the current location manually when the app is in use by calling the below method as a workaround to satisfy our SDK’s ‘Always On’ location permission requirement.

PilgrimManager.shared().getCurrentLocation { (currentLocation, error) in
   // Example: currentLocation.currentPlace.venue.name
}
[[FSQPPilgrimManager sharedManager] getCurrentLocationWithCompletion:^(FSQPCurrentLocation * _Nullable currentLocation, NSError * _Nullable error) {
   // Example: currentLocation.currentPlace.venue.name
}];

This will return the current venue the device is most likely at (in the currentLocation object), as well as any geofences that the device is in (if configured). Note that this foregoes any “stop detection” so it shouldn’t be used as a proxy for visits. For example, this method could return a high confidence result for Starbucks if called while someone is walking by the entrance.

Reasons for a nil or error response

There are a couple reasons why calling getCurrentLocation would return an error or a nil value:

  1. Lack of network connectivity: The most likely reason the SDK cannot retrieve the device’s current location would be because the API request has failed to make a proper connection to the Foursquare server.
  2. Lack of location permissions: If the LocationSubscriber is not allowed to get location info. This means that the proper location permissions have not been properly set or granted by the user. For foreground usage, the When In Use permissions are required. And if being used in the background, it will require the Location Always permission.
  3. CLLocation timeout: If CLLocation doesn’t return a location to us within the timeout value we specify and fails to resolve a location.

Next Steps

Configuration