Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Examples/destination_plugins/AdjustDestination.swift
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ public class AdjustDestination: NSObject, DestinationPlugin, RemoteNotifications

internal var settings: AdjustSettings? = nil

@Atomic var started = false
@Atomic public var started = false

required public init(name: String) {
self.name = name
Expand Down
4 changes: 4 additions & 0 deletions Examples/destination_plugins/MixpanelDestination.swift
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ class MixpanelDestination: DestinationPlugin {
private var mixpanel: MixpanelInstance? = nil
private var settings: [String: Any]? = nil

@Atomic public var started = false

required init(name: String) {
self.name = name
type = .destination
Expand Down Expand Up @@ -74,6 +76,8 @@ class MixpanelDestination: DestinationPlugin {
mixpanel = nil
analytics?.log(message: "Could not load Mixpanel settings")
}

started = true
}

func identify(event: IdentifyEvent) -> IdentifyEvent? {
Expand Down
1 change: 1 addition & 0 deletions Examples/other_plugins/ConsentTracking.swift
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ class ConsentTracking: Plugin {
for instance in Self.instances {
instance.replayEvents()
}
clearQueuedEvents()
}

func replayEvents() {
Expand Down
4 changes: 4 additions & 0 deletions Segment.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
46022764261E64A800A9E913 /* iOSLifecycleEvents.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46022763261E64A800A9E913 /* iOSLifecycleEvents.swift */; };
4602276C261E7BF900A9E913 /* iOSDelegation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4602276B261E7BF900A9E913 /* iOSDelegation.swift */; };
46022771261F7A4800A9E913 /* Atomic.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46022770261F7A4800A9E913 /* Atomic.swift */; };
46031D65266E7C10009BA540 /* StartupQueue.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46031D64266E7C10009BA540 /* StartupQueue.swift */; };
462107F22603DA4D00EBC4A8 /* Sovran in Frameworks */ = {isa = PBXBuildFile; productRef = 462107F12603DA4D00EBC4A8 /* Sovran */; };
4621080C2605332D00EBC4A8 /* KeyPath.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4621080B2605332D00EBC4A8 /* KeyPath.swift */; };
46210811260538BE00EBC4A8 /* KeyPath_Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46210810260538BE00EBC4A8 /* KeyPath_Tests.swift */; };
Expand Down Expand Up @@ -103,6 +104,7 @@
46022763261E64A800A9E913 /* iOSLifecycleEvents.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = iOSLifecycleEvents.swift; sourceTree = "<group>"; };
4602276B261E7BF900A9E913 /* iOSDelegation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = iOSDelegation.swift; sourceTree = "<group>"; };
46022770261F7A4800A9E913 /* Atomic.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Atomic.swift; sourceTree = "<group>"; };
46031D64266E7C10009BA540 /* StartupQueue.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StartupQueue.swift; sourceTree = "<group>"; };
4621080B2605332D00EBC4A8 /* KeyPath.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeyPath.swift; sourceTree = "<group>"; };
46210810260538BE00EBC4A8 /* KeyPath_Tests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeyPath_Tests.swift; sourceTree = "<group>"; };
46210835260BBEE400EBC4A8 /* DeviceToken.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeviceToken.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -211,6 +213,7 @@
46A018C125E5857D00F9CCD8 /* Context.swift */,
9692726725A583A6009B5298 /* SegmentDestination.swift */,
46210835260BBEE400EBC4A8 /* DeviceToken.swift */,
46031D64266E7C10009BA540 /* StartupQueue.swift */,
);
path = Plugins;
sourceTree = "<group>";
Expand Down Expand Up @@ -469,6 +472,7 @@
46A018C225E5857D00F9CCD8 /* Context.swift in Sources */,
96208650257AA83E00314F8D /* iOSLifecycleMonitor.swift in Sources */,
96C33AAC25892D6D00F3D538 /* Metrics.swift in Sources */,
46031D65266E7C10009BA540 /* StartupQueue.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down
6 changes: 2 additions & 4 deletions Sources/Segment/Analytics.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,7 @@ public class Analytics {
internal var configuration: Configuration
internal var store: Store
internal var storage: Storage

private var built = false


/// Enabled/disables debug logging to trace your data going through the SDK.
public var debugLogsEnabled = false

Expand All @@ -33,7 +31,7 @@ public class Analytics {
store.provide(state: System.defaultState(configuration: configuration, from: storage))
store.provide(state: UserInfo.defaultState(from: storage))

// Get everything hot and sweaty here
// Get everything running
platformStartup()
}

Expand Down
18 changes: 18 additions & 0 deletions Sources/Segment/Plugins.swift
Original file line number Diff line number Diff line change
Expand Up @@ -141,11 +141,29 @@ extension Analytics {
*/
@discardableResult
public func add(plugin: Plugin) -> String {
// we need to know if the system is already started.
var wasStarted = false
if let system: System = store.currentState(), system.started {
wasStarted = system.started
// if it was, we need to stop it temporarily.
store.dispatch(action: System.SetStartedAction(started: false))
// adding the plugin to the timeline below will eventually call
// update(settings:) at which point, we can start it up again.
}

plugin.configure(analytics: self)
timeline.add(plugin: plugin)
if plugin is DestinationPlugin && !(plugin is SegmentDestination) {
// need to maintain the list of integrations to inject into payload
store.dispatch(action: System.AddIntegrationAction(pluginName: plugin.name))
}

// if the timeline had started before, set it back to started since
// update(settings:) will have been called by now.
if wasStarted {
store.dispatch(action: System.SetStartedAction(started: true))
}

return plugin.name
}

Expand Down
56 changes: 56 additions & 0 deletions Sources/Segment/Plugins/StartupQueue.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
//
// StartupQueue.swift
// Segment
//
// Created by Brandon Sneed on 6/4/21.
//

import Foundation
import Sovran

class StartupQueue: Plugin, Subscriber {
static var specificName = "Segment_StartupQueue"

@Atomic var started: Bool = false

let type: PluginType = .before
let name: String = specificName
var analytics: Analytics? = nil {
didSet {
analytics?.store.subscribe(self, handler: systemUpdate)
}
}

var queuedEvents = [RawEvent]()

required init(name: String) {
// ignore name; hardcoded above.
}

func execute<T: RawEvent>(event: T?) -> T? {
if let e = event, started == false {
// timeline hasn't started, so queue it up.
queuedEvents.append(e)
return nil
}
// the timeline has started, so let the event pass.
return event
}
}

extension StartupQueue {
internal func systemUpdate(state: System) {
started = state.started
if started {
replayEvents()
}
}

internal func replayEvents() {
// replay the queued events to the instance of Analytics we're working with.
for event in queuedEvents {
analytics?.process(event: event)
}
queuedEvents.removeAll()
}
}
1 change: 1 addition & 0 deletions Sources/Segment/Startup.swift
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ extension Analytics: Subscriber {
if let settings = state.settings {
self.update(settings: settings)
}
self.store.dispatch(action: System.SetStartedAction(started: true))
}

// plugins will receive any settings we currently have as they are added.
Expand Down
24 changes: 20 additions & 4 deletions Sources/Segment/State.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,16 @@ struct System: State {
let configuration: Configuration
let integrations: JSON?
let settings: Settings?
let started: Bool

struct UpdateSettingsAction: Action {
let settings: Settings

func reduce(state: System) -> System {
let result = System(configuration: state.configuration,
integrations: state.integrations,
settings: settings)
settings: settings,
started: state.started)
return result
}
}
Expand All @@ -39,7 +41,8 @@ struct System: State {
if let jsonIntegrations = try? JSON(integrations) {
let result = System(configuration: state.configuration,
integrations: jsonIntegrations,
settings: state.settings)
settings: state.settings,
started: state.started)
return result
}
}
Expand All @@ -56,13 +59,26 @@ struct System: State {
if let jsonIntegrations = try? JSON(integrations) {
let result = System(configuration: state.configuration,
integrations: jsonIntegrations,
settings: state.settings)
settings: state.settings,
started: state.started)
return result
}
}
return state
}
}

struct SetStartedAction: Action {
let started: Bool

func reduce(state: System) -> System {
let result = System(configuration: state.configuration,
integrations: state.integrations,
settings: state.settings,
started: started)
return result
}
}
}


Expand Down Expand Up @@ -126,7 +142,7 @@ extension System {
}
}
let integrationDictionary = try! JSON([String: Any]())
return System(configuration: configuration, integrations: integrationDictionary, settings: settings)
return System(configuration: configuration, integrations: integrationDictionary, settings: settings, started: false)
}
}

Expand Down