Utilize the Event Timeline API
On this page, you can find examples of how to query the Sentiance SDK for historic timeline events, and how to register to receive timeline updates in your app, as new events are detected or existing ones are updated.
Query for Historic Events
let from = Date.distantPast
let to = Date.distantFuture
Sentiance.shared.getTimelineEvents(from: from, to: to).forEach { event in
print("Event ID: \(event.eventId)")
print("Started on: \(event.startDate)")
print("Ended on: \(event.endDate)")
if event.type == .inTransport {
let transport = event as! SENTTransportEvent
print("Type: transport")
print("Mode: \(transport.transportMode)")
if let distance = transport.distanceInMeters {
print("Distance: \(distance)")
}
print("Waypoints: \(transport.waypoints)")
}
else if event.type == .stationary {
let stationary = event as! SENTStationaryEvent
print("Type: stationary")
print("Location: \(stationary.location)")
print("Venue: \(stationary.venue)")
}
else if event.type == .offTheGrid {
print("Type: off-the-grid")
}
else {
print("Type: unknown")
}
}
Subscribe for Event Timeline Updates
public class EventTimelineUpdateReceiver: EventTimelineDelegate {
private let LAST_UPDATE_KEY = "SentianceTimelineEventLastUpdateTime"
private let timelineStore: TimelineStore
private let queue: OperationQueue
init() {
timelineStore = TimelineStore() // your own store implementation
queue = OperationQueue()
queue.maxConcurrentOperationCount = 1
}
public func listenForUpdates() {
// Save a local copy of the most recent event update time, before
// setting the delegate below. This way, we make sure that this
// value does not change by the delegate method, by the time we query
// for updates.
let mostRecentEventUpdateTime = self.mostRecentEventUpdateTime
// Set the delegate to start listening for timeline updates.
Sentiance.shared.eventTimelineDelegate = self
// Finally, let's make sure we haven't missed any events since the
// last time our app ran (e.g. due to unexpected app termination).
let afterDate = Date(timeIntervalSince1970: mostRecentEventUpdateTime)
Sentiance.shared.getTimelineUpdates(after: afterDate)
.forEach { [weak self] timelineEvent in
self?.updateOrInsert(event: timelineEvent,
updateMostRecentEventUpdateTime: false)
}
}
public func onEventTimelineUpdate(event: SENTTimelineEvent) {
// Note: this delegate method invocation happens on the
// main/UI thread.
updateOrInsert(event: event, updateMostRecentEventUpdateTime: true)
}
private func updateOrInsert(event: SENTTimelineEvent,
updateMostRecentEventUpdateTime: Bool) {
// The non-concurrent queue makes sure we don't process incoming
// updates via the delegate method and the result of calling
// getTimelineUpdates() at the same time. Plus, it makes sure
// we do the processing off of the main thread.
queue.addOperation { [weak self] in
guard let self = self else { return }
if let existingEvent = timelineStore.get(id: event.eventId) {
// Make sure the event we're about to update isn't older
// than the one we already have.
if (existingEvent.lastUpdateDate.timeIntervalSince1970 <
event.lastUpdateDate.timeIntervalSince1970) {
timelineStore.update(event: event)
}
} else {
timelineStore.insert(event: event)
}
if updateMostRecentEventUpdateTime {
// Note: events arriving via the onEventTimelineUpdate
// delegate method have a monotonically increasing
// lastUpdateDate.
self.mostRecentEventUpdateTime
= event.lastUpdateDate.timeIntervalSince1970
}
}
}
// We keep track of the most recent lastUpdateDate of the received
// events, so that on the next run, we can use it to process missed
// events (see listenForUpdates()).
private var mostRecentEventUpdateTime : TimeInterval {
get {
// We use UserDefaults. But if your app uses the iOS
// DataProtection capability, this won't work for you
// when the device is locked. Use something that will
// be accessible in this case, such as the keychain or
// a file with a specific protection option.
let defaults = UserDefaults.standard
var updateTime = defaults.double(forKey: LAST_UPDATE_KEY)
if updateTime == 0 {
updateTime = Date().timeIntervalSince1970
self.mostRecentEventUpdateTime = updateTime
}
return updateTime
}
set {
let defaults = UserDefaults.standard
defaults.set(newValue, forKey: LAST_UPDATE_KEY)
}
}
}
Last updated