The Just Eat solution to better manage the analytics tracking and improve the relationship with your BI team.
The Just Eat solution to better manage the analytics tracking on iOS and improve the relationship with your BI team.
At Just Eat, tracking events is a fundamental part of our business analysis and the information we collect informs our technical and strategic decisions. To collect the information required we needed a flexible, future-proof and easy to use tracking system that enables us to add, remove and swap the underlying integrations with analytical systems and services with minimal impact on our applications’ code. We also wanted to solve the problem of keeping the required event metadata up-to-date whenever the requirements change.
JustTrack is the event tracking solution we built for that.
For any feature request, bug report or question please use the Issues page and the appropriate label.
.plist
file and Swift code is automatically generated at build time from it.JustTrack is available through CocoaPods. To install it, simply add the following line to your Podfile:
pod "JustTrack"
Import it into your files like so:
// swift
import JustTrack
// Objective-C
@import JustTrack;
xcrun --sdk macosx swift "${PODS_ROOT}/../../JustTrack/EventsGenerator/main.swift" "${SRCROOT}/JustTrack/Events.plist" "${SRCROOT}/JustTrack/TrackingEvents.swift"
Objective C (Versions before 4.0)
xcrun --sdk macosx swift "${PODS_ROOT}/../../JustTrack/JEEventsGenerator/main.swift" "${SRCROOT}/JustTrack/Events.plist" "${SRCROOT}/JustTrack/TrackingEvents.swift"
Where:
${SRCROOT}/JustTrack/Events.plist
is the path to your events declaration plist which can be anywhere in the project."${SRCROOT}/JustTrack/TrackingEvents.swift"
Is the destination file for the automatically generated Swift code.NOTE: Consider giving this script a meaningful name (e.g. “Name: JustTrack Events Generation”)
Let’s see how we use JustTrack:
// configure the tracking with settings and trackers
let eventTracker = EventTracking()
eventTracker.deliveryType = .batch
eventTracker.logClosure = { (logString: String, logLevel: TrackingLogLevel) -> Void in
print("[EventTracker] [\(logLevel)] \(logString)")
}
// load the default tracker, in this case the console tracker
eventTracker.loadDefaultTracker(.consoleLogger)
//enable JustTrack
eventTracker.enable()
One of the problems we found with existing solutions is that the events are declared in code and therefore can only be maintained by developers. Similarly, existing solutions offer very generic tracking facilities for developers. Because of that, whenever the required metadata associated with an event changes for any reason, the developer has to search the code base and update all instances of the event with the correct implementation. This of course is a very fragile process and is prone to errors.
JustTrack tries to solve these problems by declaring events in a plist
file that is used to automatically generate equivalent definitions of the events in Swift that can be used in the app. This provides several benefits:
An Event is made of:
<key>User</key>
<dict>
<key>registeredTrackers</key>
<array>
<string>console</string>
<string>Firebase</string>
</array>
<key>payloadKeys</key>
<array>
<string>action</string>
<string>response</string>
<string>extra</string>
</array>
</dict>
public class EventUser: Event {
public let name: String = "User"
public var payload: Payload {
return [
kAction: action == "" ? NSNull() : action as String,
kResponse: response == "" ? NSNull() : response as String,
kExtra: extra == "" ? NSNull() : extra as String
]
}
public var registeredTrackers: [String] {
return ["console", "Firebase"]
}
private let kAction = "action"
private let kResponse = "response"
private let kExtra = "extra"
public var action: String = ""
public var response: String = ""
public var extra: String = ""
public init(action: String,
response: String,
extra: String) {
super.init()
self.action = action
self.response = response
self.extra = extra
}
}
//Swift
let trackingService: EventTracking = configureJustTrack()
trackingService.trackEvent(EventUser(action: "UserLogIn", response: "success", extra: "Additional info"))
//Objective-C
JETracking *trackingService = [self configureJustTrack];
[trackingService trackEvent:[[JEEventUser alloc] initWithAction:@"UserLogIn" response:@"success" extra:@"Additional info"] ];
You can also create “hardcoded” events by implementing the Event protocol. However we do recommend that you use a plist
file exclusively.
A Tracker is an object implementing the Tracker protocol and is loaded using: tracker.loadCustomTracker( ... )
function. You can implement any tracker you want and JustTrack provides a few default trackers:
In version 4.0 JustTrack has been refactored to bring it up to date with current Swift standards. As such, JustTrack no longer supports Objective-C implementations. Please consider updating any applications that consume this feature. As a result, the way events are named and must be called has been adjusted substatially. Please consider the following points when upgrading.
This update to JustTrack removes Objective-C attributes and prefixes, modernising the implementation in line with Swift standards whilst also removing the Objective-C interoperability.
For example, a generated event class previously defined as:
JEEventUser
will now adopt the naming scheme:
EventUser
The effects of this change on your pre-defined events can be determined within the generated TrackingEvents.swift file.
Please note that any programs that adopt this version will need to adopt this new naming scheme.
The naming of the events and associated payload has also been adjusted in order to ensure the camelCase naming convention is adopted throughout.
Another change made within version 4.0 is the preservation of order within the auto-generated TrackingEvents.swift files. This allows for greater clarity when comparing changes.
JustTrack now allows for the implementation of an array of objects as part of the payload. In order to implement such events, create a new item of type Dictionary and adhere to the objectPayloadKeys notation as detailed by the example event. An array of objects also supports different data types. To add these to your array of objects, simply append the varable type to the end of the value as follows:
Integers:
itemNumber_int
Double:
itemPrice_double
Booleans:
itemAvailable_bool
In version 3.0 of JustTrack the Configuration class has been removed from the JETracker protocol.
If your client code uses Objective-C then your code should continue to function without changes when upgrading.
If your client code uses Swift then then you have two options.
Option 1) The simplest way to upgrade to v3.0 of the SDK is to reintroduce the Configuration typealias in your client code as follows:
public typealias Configuration = [String : String]
Option 2) Replace your initialisers with an equivalent where your arguments are passed in a strongly typed manner. For example, this old init method…
public init(configuration: Configuration) {
super.init()
self.token = configuration[TokenKey]
}
might become…
public init(token: String) {
super.init()
self.token = token
}
JustTrack is available under the Apache License, Version 2.0. See the LICENSE file for more info.