@@ -15,10 +15,11 @@ class AutoRecordEventClient {
1515 private var isEntrances = false
1616 private var isFirstOpen : Bool
1717 private var isFirstTime = true
18- private var startEngageTimestamp : Int64 !
18+ private var lastEngageTime : Int64 = 0
1919 private var lastScreenName : String ?
2020 private var lastScreenPath : String ?
21- private var lastScreenStartTime : Int64 ?
21+ private var lastScreenUniqueId : String ?
22+ private var lastScreenStartTimestamp : Int64 = 0
2223
2324 init ( clickstream: ClickstreamContext ) {
2425 self . clickstream = clickstream
@@ -33,6 +34,84 @@ class AutoRecordEventClient {
3334 }
3435 }
3536
37+ func onViewDidAppear( screenName: String , screenPath: String , screenHashValue: String ) {
38+ let screenUniqueId = getScreenUniqueId ( screenHashValue)
39+ if !isSameScreen( screenName, screenPath, screenUniqueId) {
40+ recordUserEngagement ( )
41+ recordScreenView ( screenName, screenPath, screenUniqueId)
42+ }
43+ }
44+
45+ func recordScreenView( _ screenName: String , _ screenPath: String , _ screenUniqueId: String ) {
46+ if !clickstream. configuration. isTrackScreenViewEvents {
47+ return
48+ }
49+ let event = clickstream. analyticsClient. createEvent ( withEventType: Event . PresetEvent. SCREEN_VIEW)
50+ let eventTimestamp = event. timestamp
51+ event. addAttribute ( screenName, forKey: Event . ReservedAttribute. SCREEN_NAME)
52+ event. addAttribute ( screenPath, forKey: Event . ReservedAttribute. SCREEN_ID)
53+ event. addAttribute ( screenUniqueId, forKey: Event . ReservedAttribute. SCREEN_UNIQUEID)
54+ if lastScreenName != nil , lastScreenPath != nil , lastScreenUniqueId != nil {
55+ event. addAttribute ( lastScreenName!, forKey: Event . ReservedAttribute. PREVIOUS_SCREEN_NAME)
56+ event. addAttribute ( lastScreenPath!, forKey: Event . ReservedAttribute. PREVIOUS_SCREEN_ID)
57+ event. addAttribute ( lastScreenUniqueId!, forKey: Event . ReservedAttribute. PREVIOUS_SCREEN_UNIQUEID)
58+ }
59+ let previousTimestamp = getPreviousScreenViewTimestamp ( )
60+ if previousTimestamp > 0 {
61+ event. addAttribute ( previousTimestamp, forKey: Event . ReservedAttribute. PREVIOUS_TIMESTAMP)
62+ }
63+ event. addAttribute ( isEntrances ? 1 : 0 , forKey: Event . ReservedAttribute. ENTRANCES)
64+ if lastEngageTime > 0 {
65+ event. addAttribute ( lastEngageTime, forKey: Event . ReservedAttribute. ENGAGEMENT_TIMESTAMP)
66+ }
67+ recordEvent ( event)
68+
69+ isEntrances = false
70+ lastScreenName = screenName
71+ lastScreenPath = screenPath
72+ lastScreenUniqueId = screenUniqueId
73+ lastScreenStartTimestamp = eventTimestamp
74+ UserDefaultsUtil . savePreviousScreenViewTimestamp ( storage: clickstream. storage, timestamp: eventTimestamp)
75+ }
76+
77+ func recordUserEngagement( ) {
78+ if lastScreenStartTimestamp == 0 { return }
79+ lastEngageTime = Date ( ) . millisecondsSince1970 - lastScreenStartTimestamp
80+ if clickstream. configuration. isTrackUserEngagementEvents, lastEngageTime > Constants . minEngagementTime {
81+ let event = clickstream. analyticsClient. createEvent ( withEventType: Event . PresetEvent. USER_ENGAGEMENT)
82+ event. addAttribute ( lastEngageTime, forKey: Event . ReservedAttribute. ENGAGEMENT_TIMESTAMP)
83+ if lastScreenName != nil , lastScreenPath != nil , lastScreenUniqueId != nil {
84+ event. addAttribute ( lastScreenName!, forKey: Event . ReservedAttribute. SCREEN_NAME)
85+ event. addAttribute ( lastScreenPath!, forKey: Event . ReservedAttribute. SCREEN_ID)
86+ event. addAttribute ( lastScreenUniqueId!, forKey: Event . ReservedAttribute. SCREEN_UNIQUEID)
87+ }
88+ recordEvent ( event)
89+ }
90+ }
91+
92+ func getPreviousScreenViewTimestamp( ) -> Int64 {
93+ if lastScreenStartTimestamp > 0 {
94+ return lastScreenStartTimestamp
95+ } else {
96+ return UserDefaultsUtil . getPreviousScreenViewTimestamp ( storage: clickstream. storage)
97+ }
98+ }
99+
100+ func getScreenUniqueId( _ screenHashValue: String ) -> String {
101+ let shortDeviceId = clickstream. systemInfo. deviceId. padding ( toLength: Constants . maxDeviceIdLength,
102+ withPad: Constants . paddingChar,
103+ startingAt: 0 )
104+ return " \( shortDeviceId) - \( screenHashValue) "
105+ }
106+
107+ func isSameScreen( _ screenName: String , _ screenPath: String , _ screenUniqueId: String ) -> Bool {
108+ lastScreenName != nil
109+ && lastScreenPath != nil
110+ && screenName == lastScreenName
111+ && screenPath == lastScreenPath
112+ && screenUniqueId == lastScreenUniqueId
113+ }
114+
36115 func checkAppVersionUpdate( clickstream: ClickstreamContext ) {
37116 let appVersion = UserDefaultsUtil . getAppVersion ( storage: clickstream. storage)
38117 if appVersion != nil {
@@ -82,24 +161,6 @@ class AutoRecordEventClient {
82161 isFirstTime = false
83162 }
84163
85- func recordUserEngagement( ) {
86- let engagementTime = Date ( ) . millisecondsSince1970 - startEngageTimestamp
87- if engagementTime > Constants . minEngagementTime {
88- let event = clickstream. analyticsClient. createEvent ( withEventType: Event . PresetEvent. USER_ENGAGEMENT)
89- event. addAttribute ( engagementTime, forKey: Event . ReservedAttribute. ENGAGEMENT_TIMESTAMP)
90- if lastScreenName != nil , lastScreenPath != nil {
91- event. addAttribute ( lastScreenName!, forKey: Event . ReservedAttribute. SCREEN_NAME)
92- event. addAttribute ( lastScreenPath!, forKey: Event . ReservedAttribute. SCREEN_ID)
93- }
94- recordEvent ( event)
95- }
96- clickstream. analyticsClient. submitEvents ( isBackgroundMode: true )
97- }
98-
99- func updateEngageTimestamp( ) {
100- startEngageTimestamp = Date ( ) . millisecondsSince1970
101- }
102-
103164 func recordSessionStartEvent( ) {
104165 let event = clickstream. analyticsClient. createEvent ( withEventType: Event . PresetEvent. SESSION_START)
105166 recordEvent ( event)
@@ -109,31 +170,6 @@ class AutoRecordEventClient {
109170 isEntrances = true
110171 }
111172
112- func onViewDidAppear( screenName: String , screenPath: String ) {
113- if !clickstream. configuration. isTrackScreenViewEvents {
114- return
115- }
116- let currentTimestamp = Date ( ) . millisecondsSince1970
117- let event = clickstream. analyticsClient. createEvent ( withEventType: Event . PresetEvent. SCREEN_VIEW)
118- event. addAttribute ( screenName, forKey: Event . ReservedAttribute. SCREEN_NAME)
119- event. addAttribute ( screenPath, forKey: Event . ReservedAttribute. SCREEN_ID)
120- if lastScreenName != nil , lastScreenPath != nil {
121- event. addAttribute ( lastScreenName!, forKey: Event . ReservedAttribute. PREVIOUS_SCREEN_NAME)
122- event. addAttribute ( lastScreenPath!, forKey: Event . ReservedAttribute. PREVIOUS_SCREEN_ID)
123- }
124- event. addAttribute ( isEntrances ? 1 : 0 , forKey: Event . ReservedAttribute. ENTRANCES)
125- if !isEntrances, lastScreenStartTime != nil {
126- event. addAttribute ( currentTimestamp - lastScreenStartTime!,
127- forKey: Event . ReservedAttribute. ENGAGEMENT_TIMESTAMP)
128- }
129- recordEvent ( event)
130-
131- isEntrances = false
132- lastScreenName = screenName
133- lastScreenPath = screenPath
134- lastScreenStartTime = currentTimestamp
135- }
136-
137173 func setupExceptionHandler( ) {
138174 NSSetUncaughtExceptionHandler { exception in
139175 AutoRecordEventClient . handleException ( exception)
@@ -168,6 +204,8 @@ class AutoRecordEventClient {
168204extension AutoRecordEventClient {
169205 enum Constants {
170206 static let minEngagementTime = 1_000
207+ static let maxDeviceIdLength = 8
208+ static let paddingChar = " _ "
171209 }
172210}
173211
0 commit comments