Skip to content

Commit

Permalink
feat: add offline mode
Browse files Browse the repository at this point in the history
  • Loading branch information
Mercy811 committed Jan 26, 2024
1 parent cf0ca47 commit f64a983
Show file tree
Hide file tree
Showing 8 changed files with 70 additions and 2 deletions.
4 changes: 4 additions & 0 deletions Amplitude-Swift.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
8EDECEC5F98F9974DF3E576F /* ObjCIdentify.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8EDEC5A50E197C9C5067C19E /* ObjCIdentify.swift */; };
8EDECF81C2B1B38D472FD7EF /* ObjCConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8EDECEC5AAE15FD05E76359A /* ObjCConfiguration.swift */; };
8EDECFCCF4219767F26210D6 /* Sessions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8EDEC2B8B38E04CDB51F0E83 /* Sessions.swift */; };
B6EDB4D02B643C8400454B90 /* NetworkConnectivityCheckerPlugin.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6EDB4CF2B643C8400454B90 /* NetworkConnectivityCheckerPlugin.swift */; };
BA0359CA2A51585D007C383B /* legacy_v3.sqlite in Resources */ = {isa = PBXBuildFile; fileRef = BA0359C92A51585D007C383B /* legacy_v3.sqlite */; };
BA0639F62A4DD491000F1CEE /* LegacyDatabaseStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = BA0639F52A4DD491000F1CEE /* LegacyDatabaseStorage.swift */; };
BA1EC0F42A9F2FC700C2D547 /* DefaultTrackingOptionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = BA1EC0F32A9F2FC700C2D547 /* DefaultTrackingOptionsTests.swift */; };
Expand Down Expand Up @@ -168,6 +169,7 @@
8EDECEC5AAE15FD05E76359A /* ObjCConfiguration.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ObjCConfiguration.swift; sourceTree = "<group>"; };
8EDECF8CF745F7339B65D6DB /* ObjCStorage.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ObjCStorage.swift; sourceTree = "<group>"; };
B6DF481F2B5B45BE00B3E6AA /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = PrivacyInfo.xcprivacy; sourceTree = "<group>"; };
B6EDB4CF2B643C8400454B90 /* NetworkConnectivityCheckerPlugin.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkConnectivityCheckerPlugin.swift; sourceTree = "<group>"; };
BA0359C92A51585D007C383B /* legacy_v3.sqlite */ = {isa = PBXFileReference; lastKnownFileType = file; path = legacy_v3.sqlite; sourceTree = "<group>"; };
BA0639F52A4DD491000F1CEE /* LegacyDatabaseStorage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LegacyDatabaseStorage.swift; sourceTree = "<group>"; };
BA1EC0F32A9F2FC700C2D547 /* DefaultTrackingOptionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DefaultTrackingOptionsTests.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -334,6 +336,7 @@
8EDEC448C42C8C0A464FAA15 /* BasePlugins.swift */,
8EDECD39BAA97DD4320C0AA5 /* AnalyticsConnectorPlugin.swift */,
8EDEC48916EFEF6D5B3EEF9A /* AnalyticsConnectorIdentityPlugin.swift */,
B6EDB4CF2B643C8400454B90 /* NetworkConnectivityCheckerPlugin.swift */,
);
path = Plugins;
sourceTree = "<group>";
Expand Down Expand Up @@ -719,6 +722,7 @@
8EDECA4DAFA67CD4785D0161 /* ObjCDefaultTrackingOptions.swift in Sources */,
8EDEC43520B2DCF584F1035D /* ObjCScreenViewedEvent.swift in Sources */,
8EDECC1FC97DDF0BEFAA96E7 /* ObjCDeepLinkOpenedEvent.swift in Sources */,
B6EDB4D02B643C8400454B90 /* NetworkConnectivityCheckerPlugin.swift in Sources */,
8EDEC5F7208B1C327C8703D7 /* ObjCStorage.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
Expand Down
3 changes: 3 additions & 0 deletions Sources/Amplitude/Amplitude.swift
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ public class Amplitude {
state.userId = userId
}

if self.configuration.offline != NetworkConnectivityCheckerPlugin.Disabled {
_ = add(plugin: NetworkConnectivityCheckerPlugin())
}
// required plugin for specific platform, only has lifecyclePlugin now
if let requiredPlugin = VendorSystem.current.requiredPlugin {
_ = add(plugin: requiredPlugin)
Expand Down
5 changes: 4 additions & 1 deletion Sources/Amplitude/Configuration.swift
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ public class Configuration {
public var identifyBatchIntervalMillis: Int
public internal(set) var migrateLegacyData: Bool
public var defaultTracking: DefaultTrackingOptions
public var offline: Bool?

public init(
apiKey: String,
Expand Down Expand Up @@ -60,7 +61,8 @@ public class Configuration {
// `trackingSessionEvents` has been replaced by `defaultTracking.sessions`
defaultTracking: DefaultTrackingOptions = DefaultTrackingOptions(),
identifyBatchIntervalMillis: Int = Constants.Configuration.IDENTIFY_BATCH_INTERVAL_MILLIS,
migrateLegacyData: Bool = true
migrateLegacyData: Bool = true,
offline: Bool = false
) {
let normalizedInstanceName = instanceName == "" ? Constants.Configuration.DEFAULT_INSTANCE : instanceName

Expand Down Expand Up @@ -93,6 +95,7 @@ public class Configuration {
self.migrateLegacyData = migrateLegacyData
// Logging is OFF by default
self.loggerProvider.logLevel = logLevel.rawValue
self.offline = offline
}

func isValid() -> Bool {
Expand Down
6 changes: 5 additions & 1 deletion Sources/Amplitude/Mediator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,11 @@ internal class Mediator {

internal func remove(plugin: Plugin) {
plugins.removeAll { (storedPlugin) -> Bool in
return storedPlugin === plugin
if storedPlugin === plugin {
storedPlugin.teardown()
return true
}
return false
}
}

Expand Down
4 changes: 4 additions & 0 deletions Sources/Amplitude/Plugins/BasePlugins.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ open class BasePlugin {
open func execute(event: BaseEvent) -> BaseEvent? {
return event
}

public func teardown(){
// Clean up any resources from setup if necessary
}
}

open class BeforePlugin: BasePlugin, Plugin {
Expand Down
40 changes: 40 additions & 0 deletions Sources/Amplitude/Plugins/NetworkConnectivityCheckerPlugin.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
//
// NetworkConnectivityCheckerPlugin.swift
// Amplitude-Swift
//
// Created by Xinyi.Ye on 1/26/24.
//

import Foundation
import Network

open class NetworkConnectivityCheckerPlugin: BeforePlugin {
public static let Disabled: Bool? = nil
let monitor = NWPathMonitor()


open override func setup(amplitude: Amplitude) {
super.setup(amplitude: amplitude)
self.amplitude?.logger?.debug(message: "Installing AndroidNetworkConnectivityPlugin, offline feature should be supported.")

// Define handler for network changes
monitor.pathUpdateHandler = { path in
if path.status == .satisfied {
self.amplitude?.logger?.debug(message: "Network connectivity changed to online.")
self.amplitude?.configuration.offline = false
} else {
self.amplitude?.logger?.debug(message: "Network connectivity changed to offline.")
self.amplitude?.configuration.offline = true
}
}

// Start network monitor
let queue = DispatchQueue(label: "networkConnectivityChecker.amplitude.com")
monitor.start(queue: queue)
}

open override func teardown() {
monitor.cancel()
}

}
5 changes: 5 additions & 0 deletions Sources/Amplitude/Types.swift
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ public protocol Plugin: AnyObject {
var type: PluginType { get }
func setup(amplitude: Amplitude)
func execute(event: BaseEvent) -> BaseEvent?
func teardown()
}

public protocol EventPlugin: Plugin {
Expand All @@ -116,6 +117,10 @@ extension Plugin {

public func setup(amplitude: Amplitude) {
}

public func teardown(){
// Clean up any resources from setup if necessary
}
}

public protocol ResponseHandler {
Expand Down
5 changes: 5 additions & 0 deletions Sources/Amplitude/Utilities/EventPipeline.swift
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,11 @@ public class EventPipeline {
}

func flush(completion: (() -> Void)? = nil) {
if self.amplitude.configuration.offline == true {
self.amplitude.logger?.debug(message: "Skipping flush while offline.")
return
}

amplitude.logger?.log(message: "Start flushing \(eventCount) events")
eventCount = 0
guard let storage = self.storage else { return }
Expand Down

0 comments on commit f64a983

Please sign in to comment.