License | Commercial |
ReleasedLast Release | Jan 2025 |
Maintained by Antonio Pagano, Ezequiel, Edwin Polo, KOBY_VILLALOBOS.
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.
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
.
It should look something like this:
target 'MyApp' do
pod 'MotusSDK'
end
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.
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.
In order to get location and logging working correctly set the following keys on your info.plist:
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.
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
var motus : MotusSDK = MotusSDK.withCredentials("[appId]", secret: "[motus provided secret]")
func application(_ application: UIApplication, didFinishLaunchingWithOptions...
methodlet 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 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:
identifier for the current user.
groupId for the current user.
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.
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)
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)
When enabled, this setting connects any starting trip to its predecesor if previous trip end is within a mile of the starting trip.
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.
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.
This setting tells the SDK to write or not logs to a file into Documents/Logs/
.
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 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.
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()
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()
To get the list of the current day there are 2 options:
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()
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;
})
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;
})
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)")
})
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.
MotusSDK
pod in the Podfile to be 2.0.0.func applicationWillTerminate(_ application: UIApplication) {
add the following:self.motus.willTerminate()
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.UIFileSharingEnable
property set to YES
, you can now disable it unless your app uses it for other proposes.© 2016 Motus LLC