Skip to content

Commit 2dd236c

Browse files
zhu-xiaoweixiaoweii
andauthored
feat: add preset traffic source attributes (#62)
Co-authored-by: xiaoweii <xiaoweii@amazom.com>
1 parent a2c331e commit 2dd236c

File tree

6 files changed

+128
-11
lines changed

6 files changed

+128
-11
lines changed

.github/workflows/test.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,9 @@ jobs:
2222
cd ../../../../
2323
xcrun llvm-cov export -format="lcov" -instr-profile $pathCoverage .build/Build/Products/Debug-iphonesimulator/Clickstream.o > .build/info.lcov
2424
- name: Upload Test Report
25-
uses: codecov/codecov-action@v3
25+
uses: codecov/codecov-action@v4
2626
with:
27+
token: ${{ secrets.CODECOV_TOKEN }}
2728
name: report
2829
files: .build/info.lcov
2930
swift: true

README.md

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,8 @@ func application(_ application: UIApplication, didFinishLaunchingWithOptions lau
8282

8383
#### 3.2 Initialize the SDK with global attributes and custom configuration
8484

85+
The following example code shows how to add traffic source fields as global attributes when initializing the SDK.
86+
8587
```swift
8688
import Clickstream
8789
...
@@ -92,8 +94,15 @@ func application(_ application: UIApplication, didFinishLaunchingWithOptions lau
9294
.withEndpoint("https://example.com/collect")
9395
.withLogEvents(true)
9496
.withInitialGlobalAttributes([
95-
"_traffic_source_name": "Summer promotion",
96-
"_traffic_source_medium": "Search engine"
97+
ClickstreamAnalytics.Attr.TRAFFIC_SOURCE_SOURCE: "amazon",
98+
ClickstreamAnalytics.Attr.TRAFFIC_SOURCE_MEDIUM: "cpc",
99+
ClickstreamAnalytics.Attr.TRAFFIC_SOURCE_CAMPAIGN: "summer_promotion",
100+
ClickstreamAnalytics.Attr.TRAFFIC_SOURCE_CAMPAIGN_ID: "summer_promotion_01",
101+
ClickstreamAnalytics.Attr.TRAFFIC_SOURCE_TERM: "running_shoes",
102+
ClickstreamAnalytics.Attr.TRAFFIC_SOURCE_CONTENT: "banner_ad_1",
103+
ClickstreamAnalytics.Attr.TRAFFIC_SOURCE_CLID: "amazon_ad_123",
104+
ClickstreamAnalytics.Attr.TRAFFIC_SOURCE_CLID_PLATFORM: "amazon_ads",
105+
ClickstreamAnalytics.Attr.APP_INSTALL_CHANNEL: "App Store"
97106
])
98107
try ClickstreamAnalytics.initSDK(configuration)
99108
} catch {

Sources/Clickstream/ClickstreamAnalytics.swift

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,8 +113,32 @@ public enum ClickstreamAnalytics {
113113

114114
/// ClickstreamANalytics preset attributes
115115
public enum Attr {
116+
/// Preset attribute screen name
116117
public static let SCREEN_NAME = "_screen_name"
118+
/// Preset attribute screen unique id
117119
public static let SCREEN_UNIQUE_ID = "_screen_unique_id"
120+
/// Preset attribute traffic source source
121+
public static let TRAFFIC_SOURCE_SOURCE = "_traffic_source_source"
122+
/// Preset attribute traffic source medium
123+
public static let TRAFFIC_SOURCE_MEDIUM = "_traffic_source_medium"
124+
/// Preset attribute traffic source campaign
125+
public static let TRAFFIC_SOURCE_CAMPAIGN = "_traffic_source_campaign"
126+
/// Preset attribute traffic source campaign id
127+
public static let TRAFFIC_SOURCE_CAMPAIGN_ID = "_traffic_source_campaign_id"
128+
/// Preset attribute traffic source term
129+
public static let TRAFFIC_SOURCE_TERM = "_traffic_source_term"
130+
/// Preset attribute traffic source content
131+
public static let TRAFFIC_SOURCE_CONTENT = "_traffic_source_content"
132+
/// Preset attribute traffic source clid
133+
public static let TRAFFIC_SOURCE_CLID = "_traffic_source_clid"
134+
/// Preset attribute traffic source clid platform
135+
public static let TRAFFIC_SOURCE_CLID_PLATFORM = "_traffic_source_clid_platform"
136+
/// Preset attribute app install channel
137+
public static let APP_INSTALL_CHANNEL = "_app_install_channel"
138+
/// Preset attribute event value
139+
public static let VALUE = "_value"
140+
/// Preset attribute event currency
141+
public static let CURRENCY = "_currency"
118142
}
119143

120144
/// ClickstreamAnalytics preset item attributes

Sources/Clickstream/ClickstreamObjc.swift

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,28 @@ import Foundation
134134
public static let SCREEN_NAME = "_screen_name"
135135
/// Preset attribute screen unique id
136136
public static let SCREEN_UNIQUE_ID = "_screen_unique_id"
137+
/// Preset attribute traffic source source
138+
public static let TRAFFIC_SOURCE_SOURCE = "_traffic_source_source"
139+
/// Preset attribute traffic source medium
140+
public static let TRAFFIC_SOURCE_MEDIUM = "_traffic_source_medium"
141+
/// Preset attribute traffic source campaign
142+
public static let TRAFFIC_SOURCE_CAMPAIGN = "_traffic_source_campaign"
143+
/// Preset attribute traffic source campaign id
144+
public static let TRAFFIC_SOURCE_CAMPAIGN_ID = "_traffic_source_campaign_id"
145+
/// Preset attribute traffic source term
146+
public static let TRAFFIC_SOURCE_TERM = "_traffic_source_term"
147+
/// Preset attribute traffic source content
148+
public static let TRAFFIC_SOURCE_CONTENT = "_traffic_source_content"
149+
/// Preset attribute traffic source clid
150+
public static let TRAFFIC_SOURCE_CLID = "_traffic_source_clid"
151+
/// Preset attribute traffic source clid platform
152+
public static let TRAFFIC_SOURCE_CLID_PLATFORM = "_traffic_source_clid_platform"
153+
/// Preset attribute app install channel
154+
public static let APP_INSTALL_CHANNEL = "_app_install_channel"
155+
/// Preset attribute event value
156+
public static let VALUE = "_value"
157+
/// Preset attribute event currency
158+
public static let CURRENCY = "_currency"
137159
}
138160

139161
/// ClickstreamAnalytics preset item keys for objective-c

Tests/ClickstreamTests/Clickstream/EventRecorderTest.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -359,7 +359,7 @@ class EventRecorderTest: XCTestCase {
359359

360360
eventRecorder.submitEvents()
361361
XCTAssertEqual(1, eventRecorder.queue.operationCount)
362-
Thread.sleep(forTimeInterval: 0.5)
362+
Thread.sleep(forTimeInterval: 0.8)
363363
let totalEvent = try dbUtil.getEventCount()
364364
XCTAssertEqual(0, totalEvent)
365365
XCTAssertTrue(eventRecorder.bundleSequenceId == 3)

Tests/ClickstreamTests/IntegrationTest.swift

Lines changed: 68 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,11 @@ class IntegrationTest: XCTestCase {
7777
ClickstreamAnalytics.Item.ITEM_CATEGORY: "book",
7878
ClickstreamAnalytics.Item.PRICE: 99.9
7979
]
80-
ClickstreamAnalytics.recordEvent("testEvent", ["id": 123], [item_book])
80+
ClickstreamAnalytics.recordEvent("testEvent",
81+
["id": 123,
82+
ClickstreamAnalytics.Attr.VALUE: 99.9,
83+
ClickstreamAnalytics.Attr.CURRENCY: "USD"],
84+
[item_book])
8185
Thread.sleep(forTimeInterval: 0.2)
8286
let testEvent = try getTestEvent()
8387
let items = testEvent["items"] as! [JsonObject]
@@ -120,7 +124,7 @@ class IntegrationTest: XCTestCase {
120124

121125
func testAddGlobalAttribute() throws {
122126
ClickstreamAnalytics.addGlobalAttributes([
123-
"channel": "AppStore",
127+
ClickstreamAnalytics.Attr.APP_INSTALL_CHANNEL: "App Store",
124128
"level": 5.1,
125129
"class": 5,
126130
"isOpenNotification": true
@@ -130,26 +134,53 @@ class IntegrationTest: XCTestCase {
130134

131135
let testEvent = try getTestEvent()
132136
let eventAttribute = testEvent["attributes"] as! [String: Any]
133-
XCTAssertEqual("AppStore", eventAttribute["channel"] as! String)
137+
XCTAssertEqual("App Store", eventAttribute[ClickstreamAnalytics.Attr.APP_INSTALL_CHANNEL] as! String)
134138
XCTAssertEqual(5.1, eventAttribute["level"] as! Double)
135139
XCTAssertEqual(5, eventAttribute["class"] as! Int)
136140
XCTAssertEqual(true, eventAttribute["isOpenNotification"] as! Bool)
137141
}
138142

143+
func testAddGlobalAttributeForTrafficSource() throws {
144+
ClickstreamAnalytics.addGlobalAttributes([
145+
ClickstreamAnalytics.Attr.TRAFFIC_SOURCE_SOURCE: "amazon",
146+
ClickstreamAnalytics.Attr.TRAFFIC_SOURCE_MEDIUM: "cpc",
147+
ClickstreamAnalytics.Attr.TRAFFIC_SOURCE_CAMPAIGN: "summer_promotion",
148+
ClickstreamAnalytics.Attr.TRAFFIC_SOURCE_CAMPAIGN_ID: "summer_promotion_01",
149+
ClickstreamAnalytics.Attr.TRAFFIC_SOURCE_TERM: "running_shoes",
150+
ClickstreamAnalytics.Attr.TRAFFIC_SOURCE_CONTENT: "banner_ad_1",
151+
ClickstreamAnalytics.Attr.TRAFFIC_SOURCE_CLID: "amazon_ad_123",
152+
ClickstreamAnalytics.Attr.TRAFFIC_SOURCE_CLID_PLATFORM: "amazon_ads",
153+
ClickstreamAnalytics.Attr.APP_INSTALL_CHANNEL: "App Store"
154+
])
155+
ClickstreamAnalytics.recordEvent("testEvent")
156+
Thread.sleep(forTimeInterval: 0.1)
157+
let testEvent = try getTestEvent()
158+
let eventAttribute = testEvent["attributes"] as! [String: Any]
159+
XCTAssertEqual("amazon", eventAttribute[ClickstreamAnalytics.Attr.TRAFFIC_SOURCE_SOURCE] as! String)
160+
XCTAssertEqual("cpc", eventAttribute[ClickstreamAnalytics.Attr.TRAFFIC_SOURCE_MEDIUM] as! String)
161+
XCTAssertEqual("summer_promotion", eventAttribute[ClickstreamAnalytics.Attr.TRAFFIC_SOURCE_CAMPAIGN] as! String)
162+
XCTAssertEqual("summer_promotion_01", eventAttribute[ClickstreamAnalytics.Attr.TRAFFIC_SOURCE_CAMPAIGN_ID] as! String)
163+
XCTAssertEqual("running_shoes", eventAttribute[ClickstreamAnalytics.Attr.TRAFFIC_SOURCE_TERM] as! String)
164+
XCTAssertEqual("banner_ad_1", eventAttribute[ClickstreamAnalytics.Attr.TRAFFIC_SOURCE_CONTENT] as! String)
165+
XCTAssertEqual("amazon_ad_123", eventAttribute[ClickstreamAnalytics.Attr.TRAFFIC_SOURCE_CLID] as! String)
166+
XCTAssertEqual("amazon_ads", eventAttribute[ClickstreamAnalytics.Attr.TRAFFIC_SOURCE_CLID_PLATFORM] as! String)
167+
XCTAssertEqual("App Store", eventAttribute[ClickstreamAnalytics.Attr.APP_INSTALL_CHANNEL] as! String)
168+
}
169+
139170
func testDeleteGlobalAttribute() throws {
140171
ClickstreamAnalytics.addGlobalAttributes([
141-
"channel": "AppStore",
172+
ClickstreamAnalytics.Attr.APP_INSTALL_CHANNEL: "App Store",
142173
"level": 5.1,
143174
"class": 5,
144175
"isOpenNotification": true
145176
])
146-
ClickstreamAnalytics.deleteGlobalAttributes("channel")
177+
ClickstreamAnalytics.deleteGlobalAttributes(ClickstreamAnalytics.Attr.APP_INSTALL_CHANNEL)
147178
ClickstreamAnalytics.recordEvent("testEvent")
148179
Thread.sleep(forTimeInterval: 0.1)
149180

150181
let testEvent = try getTestEvent()
151182
let eventAttribute = testEvent["attributes"] as! [String: Any]
152-
XCTAssertNil(eventAttribute["channel"])
183+
XCTAssertNil(eventAttribute[ClickstreamAnalytics.Attr.APP_INSTALL_CHANNEL])
153184
XCTAssertEqual(5.1, eventAttribute["level"] as! Double)
154185
XCTAssertEqual(5, eventAttribute["class"] as! Int)
155186
XCTAssertEqual(true, eventAttribute["isOpenNotification"] as! Bool)
@@ -326,7 +357,9 @@ class IntegrationTest: XCTestCase {
326357
"event_category": "recommended"
327358
]
328359
ClickstreamObjc.recordEvent("testEvent",
329-
["id": 123],
360+
["id": 123,
361+
Attr.VALUE: 99.9,
362+
Attr.CURRENCY: "USD"],
330363
[item])
331364
Thread.sleep(forTimeInterval: 0.2)
332365
let testEvent = try getTestEvent()
@@ -371,6 +404,34 @@ class IntegrationTest: XCTestCase {
371404
XCTAssertEqual(true, eventAttribute["Successful"] as! Bool)
372405
}
373406

407+
func testAddTrafficSourceForObjc() throws {
408+
let attribute: NSDictionary = [
409+
Attr.TRAFFIC_SOURCE_SOURCE: "amazon",
410+
Attr.TRAFFIC_SOURCE_MEDIUM: "cpc",
411+
Attr.TRAFFIC_SOURCE_CAMPAIGN: "summer_promotion",
412+
Attr.TRAFFIC_SOURCE_CAMPAIGN_ID: "summer_promotion_01",
413+
Attr.TRAFFIC_SOURCE_TERM: "running_shoes",
414+
Attr.TRAFFIC_SOURCE_CONTENT: "banner_ad_1",
415+
Attr.TRAFFIC_SOURCE_CLID: "amazon_ad_123",
416+
Attr.TRAFFIC_SOURCE_CLID_PLATFORM: "amazon_ads",
417+
Attr.APP_INSTALL_CHANNEL: "App Store"
418+
]
419+
ClickstreamObjc.addGlobalAttributes(attribute)
420+
ClickstreamObjc.recordEvent("testEvent")
421+
Thread.sleep(forTimeInterval: 0.1)
422+
let testEvent = try getTestEvent()
423+
let eventAttribute = testEvent["attributes"] as! [String: Any]
424+
XCTAssertNotNil(eventAttribute[Attr.TRAFFIC_SOURCE_SOURCE])
425+
XCTAssertNotNil(eventAttribute[Attr.TRAFFIC_SOURCE_MEDIUM])
426+
XCTAssertNotNil(eventAttribute[Attr.TRAFFIC_SOURCE_CAMPAIGN])
427+
XCTAssertNotNil(eventAttribute[Attr.TRAFFIC_SOURCE_CAMPAIGN_ID])
428+
XCTAssertNotNil(eventAttribute[Attr.TRAFFIC_SOURCE_TERM])
429+
XCTAssertNotNil(eventAttribute[Attr.TRAFFIC_SOURCE_CONTENT])
430+
XCTAssertNotNil(eventAttribute[Attr.TRAFFIC_SOURCE_CLID])
431+
XCTAssertNotNil(eventAttribute[Attr.TRAFFIC_SOURCE_CLID_PLATFORM])
432+
XCTAssertNotNil(eventAttribute[Attr.APP_INSTALL_CHANNEL])
433+
}
434+
374435
func testUserAttributeForObjc() throws {
375436
ClickstreamObjc.setUserId("3231")
376437
let userAttribute: NSDictionary = [

0 commit comments

Comments
 (0)