Analytics-Swift Plugin Architecture
Segment's plugin architecture enables you to modify and augment how the analytics client works. From modifying event payloads to changing analytics functionality, plugins help to speed up the process of getting things done.
Plugins are run through a timeline, which executes in order of insertion based on their types. Segment has these 5 types:
| Type | Details |
|---|---|
before | Executes before event processing begins. |
enrichment | Executes as the first level of event processing. |
destination | Executes as events begin to pass off to destinations. |
after | Executes after all event processing completes. You can use this to perform cleanup operations. |
utility | Executes only with manual calls such as Logging. |
There are 3 basic types of plugins that you can use as a foundation for modifying functionality. They are: Plugin, EventPlugin, and DestinationPlugin.
Plugin acts on any event payload going through the timeline.
For example, if you want to add something to the context object of any event payload as an enrichment:
1class SomePlugin: Plugin {2let type: PluginType = .enrichment3let name: String4let analytics: Analytics56init(name: String) {7self.name = name8}910override func execute(event: BaseEvent): BaseEvent? {11var workingEvent = event12if var context = workingEvent?.context?.dictionaryValue {13context[keyPath: "foo.bar"] = 1214workingEvent?.context = try? JSON(context)15}16return workingEvent17}18}
EventPlugin is a plugin interface that acts on specific event types. You can choose the event types by only overriding the event functions you want.
For example, if you only want to act on Track and Identify events:
1class SomePlugin: EventPlugin {2let type: PluginType = .enrichment3let name: String4let analytics: Analytics56init(name: String) {7self.name = name8}910func identify(event: IdentifyEvent) -> IdentifyEvent? {11// code to modify identify event12return event13}1415func track(event: TrackEvent) -> TrackEvent? {16// code to modify track event17return event18}19}
The DestinationPlugin interface is commonly used for device-mode destinations. This plugin contains an internal timeline that follows the same process as the analytics timeline, enabling you to modify and augment how events reach a particular destination.
For example, if you want to implement a device-mode destination plugin for AppsFlyer, you can use this:
1internal struct AppsFlyerSettings: Codable {2let appsFlyerDevKey: String3let appleAppID: String4let trackAttributionData: Bool?5}67@objc8class AppsFlyerDestination: UIResponder, DestinationPlugin, UserActivities, RemoteNotifications {910let timeline: Timeline = Timeline()11let type: PluginType = .destination12let name: String13var analytics: Analytics?1415internal var settings: AppsFlyerSettings? = nil1617required init(name: String) {18self.name = name19analytics?.track(name: "AppsFlyer Loaded")20}2122public func update(settings: Settings) {2324guard let settings: AppsFlyerSettings = settings.integrationSettings(name: "AppsFlyer") else {return}25self.settings = settings262728AppsFlyerLib.shared().appsFlyerDevKey = settings.appsFlyerDevKey29AppsFlyerLib.shared().appleAppID = settings.appleAppID30AppsFlyerLib.shared().isDebug = true31AppsFlyerLib.shared().deepLinkDelegate = self3233// additional update logic34}3536// ...3738analytics.add(plugin: AppsFlyerPlugin(name: "AppsFlyer"))39analytics.track("AppsFlyer Event")
update(settings:)Use this function to react to any settings updates. This implicitly calls when settings update.- OS Lifecycle hooks Plugins can also hook into lifecycle events by conforming to the platform appropriate protocol. These functions call implicitly as the lifecycle events process, like:
iOSLifecycleEvents,macOSLifecycleEvents,watchOSLifecycleEvents, andLinuxLifecycleEvents.
Adding plugins enable you to modify your analytics implementation to best fit your needs. You can add a plugin using this line of code:
analytics.add(plugin: yourIntegration)
Though you can add plugins anywhere in your code, it's best to implement your plugin when you configure the client.