Skip to content

Commit 87a0e7f

Browse files
authored
feat: support item record (#38)
1 parent 1708b75 commit 87a0e7f

15 files changed

+572
-209
lines changed

README.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,30 @@ ClickstreamAnalytics.recordEvent("testEvent", attributes)
138138
ClickstreamAnalytics.recordEvent("button_click")
139139
```
140140

141+
#### Record event with items
142+
143+
You can add the following code to log an event with an item.
144+
145+
**Note: Only pipelines from version 1.1+ can handle items with custom attribute.**
146+
147+
```swift
148+
import Clickstream
149+
150+
let attributes: ClickstreamAttribute = [
151+
ClickstreamAnalytics.Item.ITEM_ID: "123",
152+
ClickstreamAnalytics.Item.CURRENCY: "USD",
153+
"event_category": "recommended"
154+
]
155+
156+
let item_book: ClickstreamAttribute = [
157+
ClickstreamAnalytics.Item.ITEM_ID: 123,
158+
ClickstreamAnalytics.Item.ITEM_NAME: "Nature",
159+
ClickstreamAnalytics.Item.ITEM_CATEGORY: "book",
160+
ClickstreamAnalytics.Item.PRICE: 99.9
161+
]
162+
ClickstreamAnalytics.recordEvent("view_item", attributes, [item_book])
163+
```
164+
141165
#### Add global attribute
142166

143167
```swift

Sources/Clickstream/AWSClickstreamPlugin+ClientBehavior.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,9 @@ extension AWSClickstreamPlugin {
4545
if let attributes = event.attribute {
4646
clickstreamEvent.addAttribute(attributes)
4747
}
48+
if let items = event.items {
49+
clickstreamEvent.addItems(items)
50+
}
4851

4952
Task {
5053
do {

Sources/Clickstream/ClickstreamAnalytics.swift

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,11 @@ public enum ClickstreamAnalytics {
2525
/// - Parameters:
2626
/// - eventName: the event name
2727
/// - attributes: the event attributes
28-
public static func recordEvent(_ eventName: String, _ attributes: ClickstreamAttribute) {
29-
let event = BaseClickstreamEvent(name: eventName, attribute: attributes)
28+
public static func recordEvent(_ eventName: String,
29+
_ attributes: ClickstreamAttribute,
30+
_ items: [ClickstreamAttribute] = [])
31+
{
32+
let event = BaseClickstreamEvent(name: eventName, attribute: attributes, items: items)
3033
Amplify.Analytics.record(event: event)
3134
}
3235

@@ -79,11 +82,28 @@ public enum ClickstreamAnalytics {
7982
public static func disable() {
8083
Amplify.Analytics.disable()
8184
}
82-
83-
85+
8486
/// Enable the SDK
8587
/// - Parameter userId: current userId, nil for logout
8688
public static func enable() {
8789
Amplify.Analytics.enable()
8890
}
91+
92+
/// ClickstreamAnalytics item attributes
93+
public enum Item {
94+
static let ITEM_ID = "id"
95+
static let ITEM_NAME = "name"
96+
static let LOCATION_ID = "location_id"
97+
static let ITEM_BRAND = "brand"
98+
static let CURRENCY = "currency"
99+
static let PRICE = "price"
100+
static let QUANTITY = "quantity"
101+
static let CREATIVE_NAME = "creative_name"
102+
static let CREATIVE_SLOT = "creative_slot"
103+
static let ITEM_CATEGORY = "item_category"
104+
static let ITEM_CATEGORY2 = "item_category2"
105+
static let ITEM_CATEGORY3 = "item_category3"
106+
static let ITEM_CATEGORY4 = "item_category4"
107+
static let ITEM_CATEGORY5 = "item_category5"
108+
}
89109
}

Sources/Clickstream/ClickstreamAttribute.swift

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,15 @@
66
//
77

88
import Amplify
9+
import Foundation
910

1011
/// the attribute for Clickstream which support String, Int, Int64, Double and Bool
1112
public typealias ClickstreamAttribute = AnalyticsProperties
1213

1314
typealias AttributeValue = AnalyticsPropertyValue
1415
/// for support Int64 attribute value
1516
extension Int64: AnalyticsPropertyValue {}
17+
extension Decimal: AnalyticsPropertyValue {}
1618

1719
struct BaseClickstreamEvent: AnalyticsEvent {
1820
var properties: AnalyticsProperties?
@@ -23,14 +25,19 @@ struct BaseClickstreamEvent: AnalyticsEvent {
2325
/// Properties of the event
2426
var attribute: ClickstreamAttribute?
2527

28+
/// Items of the event
29+
var items: [ClickstreamAttribute]?
30+
2631
/// Initializer
2732
/// - Parameters:
2833
/// - name: The name of the event
2934
/// - attribute: Attribute of the event
3035
init(name: String,
31-
attribute: ClickstreamAttribute? = nil)
36+
attribute: ClickstreamAttribute? = nil,
37+
items: [ClickstreamAttribute]? = nil)
3238
{
3339
self.name = name
3440
self.attribute = attribute
41+
self.items = items
3542
}
3643
}

Sources/Clickstream/ClickstreamObjc.swift

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,8 @@ import Foundation
3030
/// - Parameters:
3131
/// - eventName: the event name
3232
/// - attributes: the event attributes which type is NSDictionary
33-
public static func recordEvent(_ eventName: String, _ attributes: NSDictionary) {
34-
ClickstreamAnalytics.recordEvent(eventName, getAttributes(attributes))
33+
public static func recordEvent(_ eventName: String, _ attributes: NSDictionary, _ items: [NSDictionary] = []) {
34+
ClickstreamAnalytics.recordEvent(eventName, getAttributes(attributes), getItems(items))
3535
}
3636

3737
/// Use this method to send events immediately
@@ -71,6 +71,15 @@ import Foundation
7171
try ClickstreamAnalytics.getClickstreamConfiguration()
7272
}
7373

74+
75+
private static func getItems(_ items: [NSDictionary]) -> [ClickstreamAttribute] {
76+
var resultItems: [ClickstreamAttribute] = []
77+
for item in items {
78+
resultItems.append(getAttributes(item))
79+
}
80+
return resultItems
81+
}
82+
7483
/// Disable the SDK
7584
public static func disable() {
7685
ClickstreamAnalytics.disable()

Sources/Clickstream/Dependency/Clickstream/Analytics/AnalyticsClient.swift

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,10 @@ class AnalyticsClient: AnalyticsClientBehaviour {
4545
}
4646

4747
func addGlobalAttribute(_ attribute: AttributeValue, forKey key: String) {
48-
let eventError = Event.checkAttribute(currentNumber: globalAttributes.count, key: key, value: attribute)
48+
let eventError = EventChecker.checkAttribute(
49+
currentNumber: globalAttributes.count,
50+
key: key,
51+
value: attribute)
4952
if eventError.errorCode > 0 {
5053
recordEventError(eventError)
5154
} else {
@@ -54,7 +57,9 @@ class AnalyticsClient: AnalyticsClientBehaviour {
5457
}
5558

5659
func addUserAttribute(_ attribute: AttributeValue, forKey key: String) {
57-
let eventError = Event.checkUserAttribute(currentNumber: userAttributes.count, key: key, value: attribute)
60+
let eventError = EventChecker.checkUserAttribute(
61+
currentNumber: userAttributes.count,
62+
key: key, value: attribute)
5863
if eventError.errorCode > 0 {
5964
recordEventError(eventError)
6065
} else {
@@ -115,7 +120,7 @@ class AnalyticsClient: AnalyticsClientBehaviour {
115120
}
116121

117122
func checkEventName(_ eventName: String) -> Bool {
118-
let eventError = Event.checkEventType(eventType: eventName)
123+
let eventError = EventChecker.checkEventType(eventType: eventName)
119124
if eventError.errorCode > 0 {
120125
recordEventError(eventError)
121126
return false
@@ -139,7 +144,7 @@ class AnalyticsClient: AnalyticsClientBehaviour {
139144
try eventRecorder.save(event)
140145
}
141146

142-
func recordEventError(_ eventError: Event.EventError) {
147+
func recordEventError(_ eventError: EventChecker.EventError) {
143148
Task {
144149
do {
145150
let event = createEvent(withEventType: Event.PresetEvent.CLICKSTREAM_ERROR)

Sources/Clickstream/Dependency/Clickstream/Analytics/AnalyticsPropertiesModel.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
protocol AnalyticsPropertiesModel {
99
func addAttribute(_ attribute: AttributeValue, forKey key: String)
10+
func addItem(_ item: ClickstreamAttribute)
1011
}
1112

1213
extension AnalyticsPropertiesModel {
@@ -15,4 +16,10 @@ extension AnalyticsPropertiesModel {
1516
addAttribute(value, forKey: key)
1617
}
1718
}
19+
20+
func addItems(_ items: [ClickstreamAttribute]) {
21+
for item in items {
22+
addItem(item)
23+
}
24+
}
1825
}

Sources/Clickstream/Dependency/Clickstream/Event/ClickstreamEvent.swift

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ class ClickstreamEvent: AnalyticsPropertiesModel {
1919
let timestamp: Date.Timestamp
2020
let session: Session?
2121
private(set) lazy var attributes: [String: AttributeValue] = [:]
22+
private(set) lazy var items: [ClickstreamAttribute] = []
2223
private(set) lazy var userAttributes: [String: Any] = [:]
2324
let systemInfo: SystemInfo
2425
let netWorkType: String
@@ -43,7 +44,7 @@ class ClickstreamEvent: AnalyticsPropertiesModel {
4344
}
4445

4546
func addAttribute(_ attribute: AttributeValue, forKey key: String) {
46-
let eventError = Event.checkAttribute(currentNumber: attributes.count, key: key, value: attribute)
47+
let eventError = EventChecker.checkAttribute(currentNumber: attributes.count, key: key, value: attribute)
4748
if eventError.errorCode > 0, key != Event.ReservedAttribute.EXCEPTION_STACK {
4849
attributes[Event.ReservedAttribute.ERROR_CODE] = eventError.errorCode
4950
attributes[Event.ReservedAttribute.ERROR_MESSAGE] = eventError.errorMessage
@@ -52,6 +53,20 @@ class ClickstreamEvent: AnalyticsPropertiesModel {
5253
}
5354
}
5455

56+
func addItem(_ item: ClickstreamAttribute) {
57+
let checkResult = EventChecker.checkItem(currentNumber: items.count, item: item)
58+
let eventError = checkResult.eventError
59+
let resultItem = checkResult.resultItem
60+
if eventError.errorCode > 0 {
61+
attributes[Event.ReservedAttribute.ERROR_CODE] = eventError.errorCode
62+
attributes[Event.ReservedAttribute.ERROR_MESSAGE] = eventError.errorMessage
63+
} else {
64+
if !resultItem.isEmpty {
65+
items.append(resultItem)
66+
}
67+
}
68+
}
69+
5570
func addGlobalAttribute(_ attribute: AttributeValue, forKey key: String) {
5671
attributes[key] = attribute
5772
}
@@ -91,19 +106,12 @@ class ClickstreamEvent: AnalyticsPropertiesModel {
91106
event["app_version"] = systemInfo.appVersion
92107
event["app_package_name"] = systemInfo.appPackgeName
93108
event["app_title"] = systemInfo.appTitle
109+
if !items.isEmpty {
110+
event["items"] = items
111+
}
94112
event["user"] = userAttributes
95113
event["attributes"] = getAttributeObject(from: attributes)
96-
return getJsonStringFromObject(jsonObject: event)
97-
}
98-
99-
func getJsonStringFromObject(jsonObject: JsonObject) -> String {
100-
do {
101-
let jsonData = try JSONSerialization.data(withJSONObject: jsonObject, options: [.sortedKeys])
102-
return String(data: jsonData, encoding: .utf8) ?? ""
103-
} catch {
104-
log.error("Error serializing dictionary to JSON: \(error.localizedDescription)")
105-
}
106-
return ""
114+
return event.toJsonString()
107115
}
108116

109117
private func getAttributeObject(from dictionary: AnalyticsProperties) -> JsonObject {

0 commit comments

Comments
 (0)