Versions prior to 2.7.1 will not work after the 27th of August 2020
Add the CCLocation pod to your Podfile
platform :ios, '9.0'
use_frameworks!
target 'YourAppTarget' do
pod 'CCLocation'
end
Add CCLocation modules to your Cartfile
github "crowdconnected/colocator-ios" "2.7.5"
github "ReSwift/ReSwift" "5.0.0"
github "antitypical/Result" "5.0.0"
github "apple/swift-protobuf" "1.12.0"
github "facebook/SocketRocket" "0.4.2"
github "instacart/TrueTime.swift" "5.0.3"
Add the Background Modes
<key>UIBackgroundModes</key>
<array>
<string>location</string>
<string>fetch</string>
<string>remote-notification</string>
</array>
Add Permission Descriptors
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>YOUR_TEXT_GOES_HERE</string>
<key>NSLocationAlwaysUsageDescription</key>
<string>YOUR_TEXT_GOES_HERE</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>YOUR_TEXT_GOES_HERE</string>
<key>NSBluetoothPeripheralUsageDescription</key>
<string>YOUR_TEXT_GOES_HERE</string>
<key>NSMotionUsageDescription</key>
<string>YOUR_TEXT_GOES_HERE</string>
Colocator requires “Always” Location Permission to operate.
Request “Always” Location Permission from the user. From iOS 13 onwards this will display a pop-up with 3 options: “Only Once”, “Only While Using” and “Never”. Here we want the user to select “Only While Using”.
Once the library has attempted to get a location in the background and the user unlocks their phone they will be present with another pop-up with 2 options: “Always”, “Only While Using”. Here we need the user to select “Always”
let locationManager = CLLocationManager()
locationManager.requestAlwaysAuthorization()
The library must be started within the func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?)
method of the AppDelegate
. It may additionally be started elsewhere to fit in with your onboarding flow but the start(apiKey:)
method has to be called on the DispatchQueue.main
thread.
import CCLocation
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
CCLocation.sharedInstance.start(apiKey: YOUR_APP_KEY)
return true
}
We use background refresh to periodically check whether we should enable location tracking. Please enable this by registering for Background Refresh events:
UIApplication.shared.setMinimumBackgroundFetchInterval(UIMinimumKeepAliveTimeout)
and calling the library when one occurs:
func application(_ application: UIApplication, performFetchWithCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
// At background refresh, the CCLocation library should be notified to update its state
CCLocation.sharedInstance.updateLibraryBasedOnClientStatus(clientKey: YOUR_APP_KEY) { success in
if success {
completionHandler(.newData)
} else {
completionHandler(.noData)
}
}
}
We use Silent Push Notifications to enable location tracking at a given time. Please enable this by:
UIApplication.shared.registerForRemoteNotifications()
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
// For CCLocation messaging feature, send device token to the library as an alias
let tokenString = deviceToken.map { String(format: "%02.2hhx", $0) }.joined()
CCLocation.sharedInstance.addAlias(key: "apns_user_id", value: tokenString)
}
if userInfo["source"] as? String == "colocator" {
CCLocation.sharedInstance.receivedSilentNotification(userInfo: userInfo, clientKey: YOUR_APP_KEY) { isNewData in
if isNewData {
completionHandler(.newData)
} else {
completionHandler(.noData)
}
}
}
If required you can stop the library
CCLocation.sharedInstance.stop()
Aliases are key-value pairs. They are primarily used to send alternative IDs for a device, for example a unique Push Notification identifier. Go to the Push Notification Integrations page for more details
CCLocation.sharedInstance.addAlias(key: "YOUR_KEY", value: "YOUR_VALUE")
For indoor location and positioning, a few more steps need to be implemented
<key>UIBackgroundModes</key>
<array>
<string>bluetooth-peripheral</string>
<string>bluetooth-central</string>
</array>
<key>NSBluetoothAlwaysUsageDescription</key>
<string>YOUR_TEXT_GOES_HERE</string>
<key>NSMotionUsageDescription</key>
<string>YOUR_TEXT_GOES_HERE</string>
The permission pop-up will be displayed automatically when the app starts using Bluetooth, but it can also be triggered in code to fit in with your application's flow.
CCLocation.sharedInstance.triggerBluetoothPermissionPopUp()
The permission pop-up will be displayed automatically when the app starts using Motion, but it can also be triggered in code to fit in with your application's flow.
CCLocation.sharedInstance.triggerMotionPermissionPopUp()
CCLocation.sharedInstance.delegate = self
didReceiveCCLocation(_ location: LocationResponse) {
// Your code here
}
The latest location can be sent back to the device either as a one-off or a stream of updates. This is primarily used for displaying the location of the device on a map.
Request one location:
CCLocation.sharedInstance.requestLocation()
Request a stream of location updates:
CCLocation.sharedInstance.registerLocationListener()
Please make sure you unregister from location callbacks when the user is not using the indoor map screen or navigation.
This is important for battery and performance optimization.
Stop the stream of updates:
CCLocation.sharedInstance.unregisterLocationListener()
After doing all the required steps to integrate Colocator into your iOS app, check the main aspects and the status of the library
let integrationStatus = CCLocation.sharedInstance.testLibraryIntegration()
print(integrationStatus)