Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Context plugin #8

Merged
merged 3 commits into from
Nov 23, 2022
Merged
Show file tree
Hide file tree
Changes from all 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: 2 additions & 0 deletions .swiftlint.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
disabled_rules:
- function_body_length
- trailing_comma
- todo
identifier_name:
allowed_symbols: "_"
min_length: 1
cyclomatic_complexity: 25
2 changes: 1 addition & 1 deletion Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ let package = Package(
.macOS("10.15"),
.iOS("13.0"),
.tvOS("13.0"),
.watchOS("7.1"),
.watchOS("7.0"),
],
products: [
// Products define the executables and libraries a package produces, and make them visible to other packages.
Expand Down
2 changes: 1 addition & 1 deletion Sources/Amplitude/Configuration.swift
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// File.swift
// Configuration.swift
//
//
// Created by Marvin Liu on 10/27/22.
Expand Down
20 changes: 19 additions & 1 deletion Sources/Amplitude/Constants.swift
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// File.swift
// Constants.swift
//
//
// Created by Marvin Liu on 10/27/22.
Expand All @@ -22,6 +22,7 @@ enum ServerZone: String {

public struct Constants {
static let SDK_LIBRARY = "amplitude-swift"
static let SDK_VERSION = "0.0.0" // TODO: SHOULD IMPLEMENT THE SEMENTIC RELEASE TO AUTO UPDATE THIS VALUE
static let DEFAULT_API_HOST = "https://api2.amplitude.com/2/httpapi"
static let EU_DEFAULT_API_HOST = "https://api.eu.amplitude.com/2/httpapi"
static let BATCH_API_HOST = "https://api2.amplitude.com/batch"
Expand All @@ -32,6 +33,23 @@ public struct Constants {
static let MAX_PROPERTY_KEYS = 1024
static let MAX_STRING_LENGTH = 1024

static let AMP_TRACKING_OPTION_CARRIER = "carrier"
static let AMP_TRACKING_OPTION_CITY = "city"
static let AMP_TRACKING_OPTION_COUNTRY = "country"
static let AMP_TRACKING_OPTION_DEVICE_MANUFACTURER = "device_manufacturer"
static let AMP_TRACKING_OPTION_DEVICE_MODEL = "device_model"
static let AMP_TRACKING_OPTION_DMA = "dma"
static let AMP_TRACKING_OPTION_IDFA = "idfa"
static let AMP_TRACKING_OPTION_IDFV = "idfv"
static let AMP_TRACKING_OPTION_IP_ADDRESS = "ip_address"
static let AMP_TRACKING_OPTION_LANGUAGE = "language"
static let AMP_TRACKING_OPTION_LAT_LNG = "lat_lng"
static let AMP_TRACKING_OPTION_OS_NAME = "os_name"
static let AMP_TRACKING_OPTION_OS_VERSION = "os_version"
static let AMP_TRACKING_OPTION_PLATFORM = "platform"
static let AMP_TRACKING_OPTION_REGION = "region"
static let AMP_TRACKING_OPTION_VERSION_NAME = "version_name"

struct Configuration {
static let FLUSH_QUEUE_SIZE = 30
static let FLUSH_INTERVAL_MILLIS = 30 * 1000 // 30s
Expand Down
4 changes: 2 additions & 2 deletions Sources/Amplitude/Plugins/AmplitudeDestinationPlugin.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

public class AmplitudeDestinationPlugin: DestinationPlugin {
public let timeline = Timeline()
public var amplitude: Amplitude? = nil
public var amplitude: Amplitude?
public let type: PluginType = .destination
private var pipeline: EventPipeline?

Expand Down Expand Up @@ -54,7 +54,7 @@ public class AmplitudeDestinationPlugin: DestinationPlugin {
add(plugin: IdentityEventSender())
}

public func execute(event: BaseEvent) -> BaseEvent? {
public func execute(event: BaseEvent?) -> BaseEvent? {
return event
}
}
150 changes: 145 additions & 5 deletions Sources/Amplitude/Plugins/ContextPlugin.swift
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// File.swift
// ContextPlugin.swift
//
//
// Created by Marvin Liu on 10/28/22.
Expand All @@ -9,13 +9,153 @@ import Foundation

class ContextPlugin: Plugin {
var type: PluginType = PluginType.before
public weak var amplitude: Amplitude?
internal static var device = VendorSystem.current

var amplitude: Amplitude?
func execute(event: BaseEvent?) -> BaseEvent? {
guard let workingEvent = event else { return event }

func setup(amplitude: Amplitude) {
let context = staticContext

// merge context data
mergeContext(event: workingEvent, context: context)

return workingEvent
}

internal var staticContext = staticContextData()

internal static func staticContextData() -> [String: Any] {
var staticContext = [String: Any]()
// library
staticContext["library"] = "\(Constants.SDK_LIBRARY)/\(Constants.SDK_VERSION)"

// app info
let info = Bundle.main.infoDictionary
let localizedInfo = Bundle.main.localizedInfoDictionary
var app = [String: Any]()
if let info = info {
app.merge(info) { (_, new) in new }
}

if let localizedInfo = localizedInfo {
app.merge(localizedInfo) { (_, new) in new }
}

if app.count != 0 {
staticContext["version_name"] = app["CFBundleShortVersionString"] ?? ""
}

// platform/device info
let device = self.device
staticContext["device_manufacturer"] = device.manufacturer
staticContext["device_model"] = device.model
staticContext["vendorID"] = device.identifierForVendor
staticContext["os_name"] = device.os_name
staticContext["os_version"] = device.os_version
staticContext["platform"] = device.platform
if Locale.preferredLanguages.count > 0 {
staticContext["language"] = Locale.preferredLanguages[0]
}

// TODO: need to add logic for multi carrier
/* let networkInfo = NSClassFromString("CTTelephonyNetworkInfo")
if networkInfo != nil {
let subscriberCellularProvider = NSSelectorFromString("subscriberCellularProvider")
let carrier = networkInfo?.method(for: subscriberCellularProvider) ?? "unknown"
staticContext["carrier"] = carrier
}
*/

if Locale.preferredLanguages.count > 0 {
staticContext["country"] = Locale.current.regionCode
}

return staticContext
}

func execute(event: BaseEvent) -> BaseEvent? {
return event
internal func mergeContext(event: BaseEvent, context: [String: Any]) {
if event.timestamp == nil {
event.timestamp = NSDate().timeIntervalSince1970 * 1000
}
if event.insertId == nil {
event.insertId = NSUUID().uuidString
}
if event.library == nil {
event.library = context["library"] as? String
}
if event.userId == nil {
// TODO: get stored userId
// event.userId = self.amplitude.store.userId
}
if event.deviceId == nil {
// TODO: get stored deviceID
// event.deviceId = self.amplitude.store.deviceId
}
if event.partnerId == nil {
if let pId = self.amplitude?.configuration.partnerId {
event.partnerId = pId
}
}
if event.ip == nil {
// get the ip in server side if there is no event level ip
event.ip = "$remote"
}
let configuration = self.amplitude?.configuration
let trackingOptions = configuration?.trackingOptions

if configuration?.enableCoppaControl ?? false {
trackingOptions?.mergeIn(other: TrackingOptions().forCoppaControl())
}

if trackingOptions?.shouldTrackVersionName() ?? false {
event.versionName = context["version_name"] as? String
}
if trackingOptions?.shouldTrackOsName() ?? false {
event.osName = context["os_name"] as? String
}
if trackingOptions?.shouldTrackOsVersion() ?? false {
event.osVersion = context["os_version"] as? String
}
if trackingOptions?.shouldTrackDeviceManufacturer() ?? false {
event.deviceManufacturer = context["device_manufacturer"] as? String
}
if trackingOptions?.shouldTrackDeviceModel() ?? false {
event.deviceModel = context["device_model"] as? String
}
if trackingOptions?.shouldTrackCarrier() ?? false {
event.carrier = context["carrier"] as? String
}
if trackingOptions?.shouldTrackIpAddress() ?? false {
guard event.ip != nil else {
event.ip = "$remote"
return
}
}
if trackingOptions?.shouldTrackCountry() ?? false && event.ip != "$remote" {
event.country = context["country"] as? String
}
// TODO: get lat and lng from locationInfoBlock
/*if (trackingOptions?.shouldTrackLatLng() ?? false) && (self.amplitude.locationInfoBlock != nil) {
let location = self.amplitude.locationInfoBlock();
event.locationLat = location.lat
event.locationLng = location.lng
}*/
if trackingOptions?.shouldTrackLanguage() ?? false {
event.language = context["language"] as? String
}
if trackingOptions?.shouldTrackPlatform() ?? false {
event.platform = context["platform"] as? String
}
if event.plan == nil {
if let plan = self.amplitude?.configuration.plan {
event.plan = plan
}
}
if event.ingestionMetadata == nil {
if let ingestionMetadata = self.amplitude?.configuration.ingestionMetadata {
event.ingestionMetadata = ingestionMetadata
}
}
}
}
2 changes: 1 addition & 1 deletion Sources/Amplitude/Plugins/IdentityEventSender.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ internal class IdentityEventSender: Plugin {

}

func execute(event: BaseEvent) -> BaseEvent? {
func execute(event: BaseEvent?) -> BaseEvent? {
return event
}
}
Loading