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: add preset traffic source attributes #62

Merged
merged 3 commits into from
Apr 10, 2024
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
3 changes: 2 additions & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,9 @@ jobs:
cd ../../../../
xcrun llvm-cov export -format="lcov" -instr-profile $pathCoverage .build/Build/Products/Debug-iphonesimulator/Clickstream.o > .build/info.lcov
- name: Upload Test Report
uses: codecov/codecov-action@v3
uses: codecov/codecov-action@v4
with:
token: ${{ secrets.CODECOV_TOKEN }}
name: report
files: .build/info.lcov
swift: true
Expand Down
13 changes: 11 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,8 @@ func application(_ application: UIApplication, didFinishLaunchingWithOptions lau

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

The following example code shows how to add traffic source fields as global attributes when initializing the SDK.

```swift
import Clickstream
...
Expand All @@ -92,8 +94,15 @@ func application(_ application: UIApplication, didFinishLaunchingWithOptions lau
.withEndpoint("https://example.com/collect")
.withLogEvents(true)
.withInitialGlobalAttributes([
"_traffic_source_name": "Summer promotion",
"_traffic_source_medium": "Search engine"
ClickstreamAnalytics.Attr.TRAFFIC_SOURCE_SOURCE: "amazon",
ClickstreamAnalytics.Attr.TRAFFIC_SOURCE_MEDIUM: "cpc",
ClickstreamAnalytics.Attr.TRAFFIC_SOURCE_CAMPAIGN: "summer_promotion",
ClickstreamAnalytics.Attr.TRAFFIC_SOURCE_CAMPAIGN_ID: "summer_promotion_01",
ClickstreamAnalytics.Attr.TRAFFIC_SOURCE_TERM: "running_shoes",
ClickstreamAnalytics.Attr.TRAFFIC_SOURCE_CONTENT: "banner_ad_1",
ClickstreamAnalytics.Attr.TRAFFIC_SOURCE_CLID: "amazon_ad_123",
ClickstreamAnalytics.Attr.TRAFFIC_SOURCE_CLID_PLATFORM: "amazon_ads",
ClickstreamAnalytics.Attr.APP_INSTALL_CHANNEL: "App Store"
])
try ClickstreamAnalytics.initSDK(configuration)
} catch {
Expand Down
24 changes: 24 additions & 0 deletions Sources/Clickstream/ClickstreamAnalytics.swift
Original file line number Diff line number Diff line change
Expand Up @@ -113,8 +113,32 @@ public enum ClickstreamAnalytics {

/// ClickstreamANalytics preset attributes
public enum Attr {
/// Preset attribute screen name
public static let SCREEN_NAME = "_screen_name"
/// Preset attribute screen unique id
public static let SCREEN_UNIQUE_ID = "_screen_unique_id"
/// Preset attribute traffic source source
public static let TRAFFIC_SOURCE_SOURCE = "_traffic_source_source"
/// Preset attribute traffic source medium
public static let TRAFFIC_SOURCE_MEDIUM = "_traffic_source_medium"
/// Preset attribute traffic source campaign
public static let TRAFFIC_SOURCE_CAMPAIGN = "_traffic_source_campaign"
/// Preset attribute traffic source campaign id
public static let TRAFFIC_SOURCE_CAMPAIGN_ID = "_traffic_source_campaign_id"
/// Preset attribute traffic source term
public static let TRAFFIC_SOURCE_TERM = "_traffic_source_term"
/// Preset attribute traffic source content
public static let TRAFFIC_SOURCE_CONTENT = "_traffic_source_content"
/// Preset attribute traffic source clid
public static let TRAFFIC_SOURCE_CLID = "_traffic_source_clid"
/// Preset attribute traffic source clid platform
public static let TRAFFIC_SOURCE_CLID_PLATFORM = "_traffic_source_clid_platform"
/// Preset attribute app install channel
public static let APP_INSTALL_CHANNEL = "_app_install_channel"
/// Preset attribute event value
public static let VALUE = "_value"
/// Preset attribute event currency
public static let CURRENCY = "_currency"
}

/// ClickstreamAnalytics preset item attributes
Expand Down
22 changes: 22 additions & 0 deletions Sources/Clickstream/ClickstreamObjc.swift
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,28 @@ import Foundation
public static let SCREEN_NAME = "_screen_name"
/// Preset attribute screen unique id
public static let SCREEN_UNIQUE_ID = "_screen_unique_id"
/// Preset attribute traffic source source
public static let TRAFFIC_SOURCE_SOURCE = "_traffic_source_source"
/// Preset attribute traffic source medium
public static let TRAFFIC_SOURCE_MEDIUM = "_traffic_source_medium"
/// Preset attribute traffic source campaign
public static let TRAFFIC_SOURCE_CAMPAIGN = "_traffic_source_campaign"
/// Preset attribute traffic source campaign id
public static let TRAFFIC_SOURCE_CAMPAIGN_ID = "_traffic_source_campaign_id"
/// Preset attribute traffic source term
public static let TRAFFIC_SOURCE_TERM = "_traffic_source_term"
/// Preset attribute traffic source content
public static let TRAFFIC_SOURCE_CONTENT = "_traffic_source_content"
/// Preset attribute traffic source clid
public static let TRAFFIC_SOURCE_CLID = "_traffic_source_clid"
/// Preset attribute traffic source clid platform
public static let TRAFFIC_SOURCE_CLID_PLATFORM = "_traffic_source_clid_platform"
/// Preset attribute app install channel
public static let APP_INSTALL_CHANNEL = "_app_install_channel"
/// Preset attribute event value
public static let VALUE = "_value"
/// Preset attribute event currency
public static let CURRENCY = "_currency"
}

/// ClickstreamAnalytics preset item keys for objective-c
Expand Down
2 changes: 1 addition & 1 deletion Tests/ClickstreamTests/Clickstream/EventRecorderTest.swift
Original file line number Diff line number Diff line change
Expand Up @@ -359,7 +359,7 @@ class EventRecorderTest: XCTestCase {

eventRecorder.submitEvents()
XCTAssertEqual(1, eventRecorder.queue.operationCount)
Thread.sleep(forTimeInterval: 0.5)
Thread.sleep(forTimeInterval: 0.8)
let totalEvent = try dbUtil.getEventCount()
XCTAssertEqual(0, totalEvent)
XCTAssertTrue(eventRecorder.bundleSequenceId == 3)
Expand Down
75 changes: 68 additions & 7 deletions Tests/ClickstreamTests/IntegrationTest.swift
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,11 @@ class IntegrationTest: XCTestCase {
ClickstreamAnalytics.Item.ITEM_CATEGORY: "book",
ClickstreamAnalytics.Item.PRICE: 99.9
]
ClickstreamAnalytics.recordEvent("testEvent", ["id": 123], [item_book])
ClickstreamAnalytics.recordEvent("testEvent",
["id": 123,
ClickstreamAnalytics.Attr.VALUE: 99.9,
ClickstreamAnalytics.Attr.CURRENCY: "USD"],
[item_book])
Thread.sleep(forTimeInterval: 0.2)
let testEvent = try getTestEvent()
let items = testEvent["items"] as! [JsonObject]
Expand Down Expand Up @@ -120,7 +124,7 @@ class IntegrationTest: XCTestCase {

func testAddGlobalAttribute() throws {
ClickstreamAnalytics.addGlobalAttributes([
"channel": "AppStore",
ClickstreamAnalytics.Attr.APP_INSTALL_CHANNEL: "App Store",
"level": 5.1,
"class": 5,
"isOpenNotification": true
Expand All @@ -130,26 +134,53 @@ class IntegrationTest: XCTestCase {

let testEvent = try getTestEvent()
let eventAttribute = testEvent["attributes"] as! [String: Any]
XCTAssertEqual("AppStore", eventAttribute["channel"] as! String)
XCTAssertEqual("App Store", eventAttribute[ClickstreamAnalytics.Attr.APP_INSTALL_CHANNEL] as! String)
XCTAssertEqual(5.1, eventAttribute["level"] as! Double)
XCTAssertEqual(5, eventAttribute["class"] as! Int)
XCTAssertEqual(true, eventAttribute["isOpenNotification"] as! Bool)
}

func testAddGlobalAttributeForTrafficSource() throws {
ClickstreamAnalytics.addGlobalAttributes([
ClickstreamAnalytics.Attr.TRAFFIC_SOURCE_SOURCE: "amazon",
ClickstreamAnalytics.Attr.TRAFFIC_SOURCE_MEDIUM: "cpc",
ClickstreamAnalytics.Attr.TRAFFIC_SOURCE_CAMPAIGN: "summer_promotion",
ClickstreamAnalytics.Attr.TRAFFIC_SOURCE_CAMPAIGN_ID: "summer_promotion_01",
ClickstreamAnalytics.Attr.TRAFFIC_SOURCE_TERM: "running_shoes",
ClickstreamAnalytics.Attr.TRAFFIC_SOURCE_CONTENT: "banner_ad_1",
ClickstreamAnalytics.Attr.TRAFFIC_SOURCE_CLID: "amazon_ad_123",
ClickstreamAnalytics.Attr.TRAFFIC_SOURCE_CLID_PLATFORM: "amazon_ads",
ClickstreamAnalytics.Attr.APP_INSTALL_CHANNEL: "App Store"
])
ClickstreamAnalytics.recordEvent("testEvent")
Thread.sleep(forTimeInterval: 0.1)
let testEvent = try getTestEvent()
let eventAttribute = testEvent["attributes"] as! [String: Any]
XCTAssertEqual("amazon", eventAttribute[ClickstreamAnalytics.Attr.TRAFFIC_SOURCE_SOURCE] as! String)
XCTAssertEqual("cpc", eventAttribute[ClickstreamAnalytics.Attr.TRAFFIC_SOURCE_MEDIUM] as! String)
XCTAssertEqual("summer_promotion", eventAttribute[ClickstreamAnalytics.Attr.TRAFFIC_SOURCE_CAMPAIGN] as! String)
XCTAssertEqual("summer_promotion_01", eventAttribute[ClickstreamAnalytics.Attr.TRAFFIC_SOURCE_CAMPAIGN_ID] as! String)
XCTAssertEqual("running_shoes", eventAttribute[ClickstreamAnalytics.Attr.TRAFFIC_SOURCE_TERM] as! String)
XCTAssertEqual("banner_ad_1", eventAttribute[ClickstreamAnalytics.Attr.TRAFFIC_SOURCE_CONTENT] as! String)
XCTAssertEqual("amazon_ad_123", eventAttribute[ClickstreamAnalytics.Attr.TRAFFIC_SOURCE_CLID] as! String)
XCTAssertEqual("amazon_ads", eventAttribute[ClickstreamAnalytics.Attr.TRAFFIC_SOURCE_CLID_PLATFORM] as! String)
XCTAssertEqual("App Store", eventAttribute[ClickstreamAnalytics.Attr.APP_INSTALL_CHANNEL] as! String)
}

func testDeleteGlobalAttribute() throws {
ClickstreamAnalytics.addGlobalAttributes([
"channel": "AppStore",
ClickstreamAnalytics.Attr.APP_INSTALL_CHANNEL: "App Store",
"level": 5.1,
"class": 5,
"isOpenNotification": true
])
ClickstreamAnalytics.deleteGlobalAttributes("channel")
ClickstreamAnalytics.deleteGlobalAttributes(ClickstreamAnalytics.Attr.APP_INSTALL_CHANNEL)
ClickstreamAnalytics.recordEvent("testEvent")
Thread.sleep(forTimeInterval: 0.1)

let testEvent = try getTestEvent()
let eventAttribute = testEvent["attributes"] as! [String: Any]
XCTAssertNil(eventAttribute["channel"])
XCTAssertNil(eventAttribute[ClickstreamAnalytics.Attr.APP_INSTALL_CHANNEL])
XCTAssertEqual(5.1, eventAttribute["level"] as! Double)
XCTAssertEqual(5, eventAttribute["class"] as! Int)
XCTAssertEqual(true, eventAttribute["isOpenNotification"] as! Bool)
Expand Down Expand Up @@ -326,7 +357,9 @@ class IntegrationTest: XCTestCase {
"event_category": "recommended"
]
ClickstreamObjc.recordEvent("testEvent",
["id": 123],
["id": 123,
Attr.VALUE: 99.9,
Attr.CURRENCY: "USD"],
[item])
Thread.sleep(forTimeInterval: 0.2)
let testEvent = try getTestEvent()
Expand Down Expand Up @@ -371,6 +404,34 @@ class IntegrationTest: XCTestCase {
XCTAssertEqual(true, eventAttribute["Successful"] as! Bool)
}

func testAddTrafficSourceForObjc() throws {
let attribute: NSDictionary = [
Attr.TRAFFIC_SOURCE_SOURCE: "amazon",
Attr.TRAFFIC_SOURCE_MEDIUM: "cpc",
Attr.TRAFFIC_SOURCE_CAMPAIGN: "summer_promotion",
Attr.TRAFFIC_SOURCE_CAMPAIGN_ID: "summer_promotion_01",
Attr.TRAFFIC_SOURCE_TERM: "running_shoes",
Attr.TRAFFIC_SOURCE_CONTENT: "banner_ad_1",
Attr.TRAFFIC_SOURCE_CLID: "amazon_ad_123",
Attr.TRAFFIC_SOURCE_CLID_PLATFORM: "amazon_ads",
Attr.APP_INSTALL_CHANNEL: "App Store"
]
ClickstreamObjc.addGlobalAttributes(attribute)
ClickstreamObjc.recordEvent("testEvent")
Thread.sleep(forTimeInterval: 0.1)
let testEvent = try getTestEvent()
let eventAttribute = testEvent["attributes"] as! [String: Any]
XCTAssertNotNil(eventAttribute[Attr.TRAFFIC_SOURCE_SOURCE])
XCTAssertNotNil(eventAttribute[Attr.TRAFFIC_SOURCE_MEDIUM])
XCTAssertNotNil(eventAttribute[Attr.TRAFFIC_SOURCE_CAMPAIGN])
XCTAssertNotNil(eventAttribute[Attr.TRAFFIC_SOURCE_CAMPAIGN_ID])
XCTAssertNotNil(eventAttribute[Attr.TRAFFIC_SOURCE_TERM])
XCTAssertNotNil(eventAttribute[Attr.TRAFFIC_SOURCE_CONTENT])
XCTAssertNotNil(eventAttribute[Attr.TRAFFIC_SOURCE_CLID])
XCTAssertNotNil(eventAttribute[Attr.TRAFFIC_SOURCE_CLID_PLATFORM])
XCTAssertNotNil(eventAttribute[Attr.APP_INSTALL_CHANNEL])
}

func testUserAttributeForObjc() throws {
ClickstreamObjc.setUserId("3231")
let userAttribute: NSDictionary = [
Expand Down
Loading