MotusSDK 6.1.2

MotusSDK 6.1.2

License Commercial
ReleasedLast Release Jan 2025

Maintained by Antonio Pagano, Ezequiel, Edwin Polo, KOBY_VILLALOBOS.



MotusSDK 6.1.2

Motus SDK

Build Status

MotusSDK provides access to some of the core functionalities of the Motus iOS application, those include mileage tracking with the phone/tablet GPS, SDK is distributed over Cocoapods for applications that want to add Trip tracking functionallity.

Installing

Cocoapods

Create a Podfile on your XCode project

On your XCode project directory create a text file named Podfile or open a terminal window, and into your project directory use $ pod init command to create the Podfile.

Add MotusSDK dependency to your Podfile

It should look something like this:

target 'MyApp' do
  pod 'MotusSDK'
end

Install MotusSDK Pod

Open a terminal window and run command pod install in your Xcode project directory:

$ pod install

After running pod install, open the MyApp.xcworkspace file that was created on your XCode project directory.

Configure application permissions for the SDK

Motus SDK needs Location Updates background modes, in order to set this up go into XCode project settings and under the Capabilities tab, inside the Background Modes check the Location updates checkboxes.

Configure info.plist

In order to get location and logging working correctly set the following keys on your info.plist:

  • NSLocationAlwaysUsageDescription

Add some description here on what your app uses location for.

To do so, go into your XCode project settings, under the Info tab and inside the Custom iOS Target Properties add the above keys with its respective values.

SDK Usage

Configure your AppDelegate

Your application will need to do a few things to have Motus work correctly, please follow these instructions to have your AppDelegate all set to use Motus SDK:

  • Import MotusSDK at the top of your AppDelegate
import MotusSDK
  • Add an instance of the MotusSDK object to your AppDelegate
var motus : MotusSDK = MotusSDK.withCredentials("[appId]", secret: "[motus provided secret]")
  • Initialize it in your func application(_ application: UIApplication, didFinishLaunchingWithOptions... method
let config = MotusConfiguration(username: "[username]", groupId: "[userGroupID]")
config.delegate = YourApplicationMotusDelegate()
self.motus.setup(config)

Setup will initialize the SDK based on the MotusConfiguration passed to it, (See MotusConfiguration).

IMPORTANT: In case your app passes empty states for any reason (like you don't have access to encrypted settings while the app is in background) the SDK will remember your last passed settings and use them, otherwise will use default values.

With this your application should be all-set to start using the Motus SDK, from the AppDelegate you can get the Motus SDK instance you just set up by using AppDelegate from the UIApplication's singleton sharedApplication() method like this:

let delegate : AppDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
delegate.motus.mileage.trips(responseHandler: { trips, error in
  if error != nil {
    logw("| Sample: \(error!)")
    return
  }

  logw("| Trips from motus -> \(trips)")
})

In the above example we're calling the trips for the current day, this method will gets your trips and pass it to the responseHandler we passed as a parameter.

SDK Configuration

SDk allows host app to configure settings depenging on the needs of itself, things like the time used to determine a Stop are configurable values inside the MotusConfiguration object that the SDK receives as attributes when running the setup.

MotusConfiguration holds the following properties that are important for the user experience:

username (defaults "")

identifier for the current user.

groupId (defaults "")

groupId for the current user.

trackingMode (defaults .Manual)

SDK supports 3 tracking modes (.Manual, .BusinessHours, .Off) this property allows the host app to define the tracking mode.

.Manual mode will track trips only when the host app calls motus.mileage.startTracking and until the host all calls motus.mileage.stopTracking.

.BusinessHours will track trips within a set of business hours defined by MotusConfiguration.businessConfiguration.

.Off well, wont track any trips at all and is intended for cases where trip tracking is optional in your app, and you don't want to request permissions needed to track trips unless the user is actually tracking.

autoStopThreshold (defaults 300s)

This is the time the app will use to determine if the user has stopped.

By default the SDK uses 5 minutes (300seconds) as the stop threshold, but in case needed it provides a way to configure this when calling the configuration function like:

//Inside your application AppDelegate
var config = MotusConfiguration(username: "FINAL_USERNAME", groupId: "[PROVIDED_GROUP_ID]")
config.autoStopThreshold = 600.0
self.motus.setup(config)

businessConfiguration (defaults everyday 9:00 - 17:00)

When using .BusinessHours tracking mode this is the time the SDK will capture trips within, outside that time trips will not be auto-captured but instead user will need to start trips manually (if your app provides the UX for it).

To use Motus Business hours you have to call the setup function the following way:

//Setting a configuration for a user that works:
//Monday 9:00 A.M. - 12:00 M
//Wednesday 8:00 A.M. - 6:00 P.M.
//Friday 8:00 A.M. - 12:00 M.

var config = MotusConfiguration(username: "FINAL_USERNAME", groupId: "[PROVIDED_GROUP_ID]")
config.trackingMode = .BusinessMode
config.businessConfiguration =  [
  Workday(weekDay: Weekday.Monday, startHour: "09:00", endHour: "12:00" ),
  Workday(weekDay: Weekday.Tuesday, enabled: false ),
  Workday(weekDay: Weekday.Wednesday, startHour: "08:00", endHour: "18:00" ),
  Workday(weekDay: Weekday.Thursday, enabled: false ),
  Workday(weekDay: Weekday.Friday, startHour: "08:00", endHour: "12:00" ),
  Workday(weekDay: Weekday.Saturday, enabled: false ),
  Workday(weekDay: Weekday.Saturday, enabled: false )
]

self.motus.setup(config)

connectPreviousTrip (defaults false)

When enabled, this setting connects any starting trip to its predecesor if previous trip end is within a mile of the starting trip.

commuteDeduction (defaults nil)

This is where the host app passes the commute deduction configuration, that is, the logic to know wheter a trip will be marked as commute or not.

To use this property you can instantiate a CommuteDeduction object and pass it inside the configuration like:

config.commuteDeduction = CommuteDeduction()

By setting this the SDK will mark trips (after ended) by using the commute property inside the Trip object.

delegate (defaults nil)

To communicate events on the SDK like trip started or trip ended, the SDK exposes a Protocol called MotusDelegate.

SDK expects the host application to pass an object of your app that implements this method so the SDK can call protocol methods on your object when SDk events happen.

MotusDelegate provides interface for host apps to listen for events on that happen on the SDK and actuate over results of those events:

A very simple implementation of the delegate would be:

class MyAppMotusDelegate : MotusDelegate {
  func tripStarted(trip: Trip) {}
  func tripUpdated(trip: Trip) {}
  func tripsUpdated(trip: Trip) {}
  func locationPermissionsChanged(status: CLAuthorizationStatus){}
  func tripEnded(trip: Trip)
  func batteryDegraded(reading: Double)
  func businessHoursStarted()
  func businessHoursEnded()

  func distanceUpdated(distance : Double){
    print("Today's distance updated to: \(distance) meters!.")
  }
}

In order to make the SDK aware of this implementation host application should assign our motus sdk instance field 'delegate' with an instance of our implementation:

motusInstance.delegate = MyAppMotusDelegate()

IMPORTANT: if your app doesn't pass an instance that implements the MotusDelegate protocol, SDK will not be able to let your app know about anything that happens in the SDK context.

debug (defaults to nil)

This setting tells the SDK to write or not logs to a file into Documents/Logs/.

Configuring the SDK

As you may have seen in the Installation section, to setup the SDK you need to use the configuration, like the following example:

var config = MotusConfiguration(username: "FINAL_USERNAME", groupId: "[PROVIDED_GROUP_ID]")
self.motus.setup(config)

However, setup is intended to be used when the app has finished launching, sometimes you need to change things in your app based on user iteraction or other business specific behavior of your app.

Whenever you want to change the configuration, you should call the updateConfiguration method. p.e:

//In AppDelegate.swift
var motus : MotusSDK = MotusSDK.withCredentials("[appId]", secret: "[motus provided secret]")
let configuration : MotusConfiguration = MotusConfiguration(username: "[username]", groupId: "[groupID]")

//In other class within your app
//Lets asume this function will be called in your app when businessHours was changed.
func userChangedBusinessHours(workdays: [Workday]) {
  let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
  let config = appDelegate.configuration

  config.businessConfiguration = workdays
  appDelegate.motus.updateConfiguration(config)
}

SDK storage

SDK uses a secure in disk mechanism to store trips and settings, which saves files to disk encrypted with AES-256, all the settings/trips the SDK stores are saved to Documents/motus/settings.mo which will only be opened by the motus SDK and is not readable from outside of it.

Frequent Questions

How do i reset SDK to factory settings?

MotusSDK has a covenient function to set MotusSDK back to factory settings. You can do this by calling the clearSettings function. p.e:

let delegate : AppDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
delegate.motus.clearSettings()

How do i use Motus SDK to track trips from my app ?

MotusMileage class has the methods to track mileage on the host application, it uses iOS locationManager underneath to detect trips start and stop, to do so, the host application (your app) needs to call the startTracking on the MotusMileage member that's inside the Motus SDK shared instance you create on the app delegate on the setup. p.e:

//Inside some button action or other:
let delegate : AppDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
delegate.motus.mileage.startTracking()

With this we're telling Motus SDK to start checking conditions for a trip start.

On the other side once our app doesn't need to track any trip we can call the stopTracking method to avoid unneeded battery usage when our app is not needing to track trips. p.e.:

//Inside some button action or other:
let delegate : AppDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
delegate.motus.mileage.stopTracking()

How to get the list of trips for current day ?

To get the list of the current day there are 2 options:

  • Get the latest local list of trips (synchronized frequently with the server)

To do this we will use the MotusMileage instance by calling its method trips(). p.e:

let delegate : AppDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
let trips : [Trip] = delegate.motus?.mileage().trips()
  • Make the SDK get the list of trips from the server and then synchronize with local trips

To get this list of trips and trigger server sync we need to pass a responseHandler to the trips() method, this responseHandler will be called with the list of synchronized trips and/or an error if something happened in the middle of the synchronization.

let delegate : AppDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
delegate.motus.mileage.trips(responseHandler: { trips, error in
  if error != nil {
    logw("| Sample: \(error!)")
    return
  }

  logw("| Trips -> \(trips)")

  self.trips = trips;
})

How do i get the list of trips for a specific day?

You can get the list of trips for a past day by passing the formatted date to the trips() method. this call will require server call, so we will need to pass a responseHandler as well. p.e:

let delegate : AppDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
delegate.motus.mileage.trips(forDate: "2016-02-20",responseHandler: { trips, error in
  if error != nil {
    logw("| Sample: \(error!)")
    return
  }

  logw("| Trips -> \(trips)")
  self.trips = trips;
})

How can I delete the trips of a day?

Motus provides the reset function inside the MotusMileage class which delete the trips for a given date identifier.

For example if you want to delete the trips for December 28 of the 2016, this would the code needed:

let delegate : AppDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
delegate.motus.mileage.reset(identifier : “2016-12-28”,  responseHandler : { trips, error
  if error != nil {
    print(“ | A good error \(error)”)
    //Handle error
  }
  print(“| Trips from 2016-12-28 -> \(trips)")
})

How do i migrate from 1.1.3 to 2.0.0?

2.0.0 changes the way the Motus SDK tracks the trips, we've implemented certain heuristics that allows the SDK to track trips more efectively while maintaining the same quality and keeping the battery consumption stable; All this with less background permissions required.

If your app is currently using 1.1.3 the following list should help you set up the 2.0.0 version of the SDK without any trouble.

  1. Change the version of the MotusSDK pod in the Podfile to be 2.0.0.
  2. Remove the background audio permission from your application needed capabilities.
  3. Inside your func applicationWillTerminate(_ application: UIApplication) { add the following:
self.motus.willTerminate()
  1. If your app is setting the config.desiredAccuracy to be .Medium or .High please remove the line that sets it, 2.0.0 only has one accuracy mode and given that host app is no longer able to change it.
  2. If by chance you had the UIFileSharingEnable property set to YES, you can now disable it unless your app uses it for other proposes.

Copyright

© 2016 Motus LLC