@@ -37,8 +37,8 @@ public protocol MixpanelDelegate: AnyObject {
3737
3838public typealias Properties = [ String : MixpanelType ]
3939typealias InternalProperties = [ String : Any ]
40- typealias EventID = String
41- typealias TimedEvents = [ EventID : TimeInterval ]
40+ typealias TimedEventID = String
41+ typealias TimedEvents = [ TimedEventID : TimeInterval ]
4242typealias Queue = [ InternalProperties ]
4343
4444protocol AppLifecycle {
@@ -1004,6 +1004,7 @@ extension MixpanelInstance {
10041004}
10051005
10061006extension MixpanelInstance {
1007+
10071008 // MARK: - Track
10081009
10091010 /**
@@ -1019,13 +1020,30 @@ extension MixpanelInstance {
10191020 - parameter properties: properties dictionary
10201021 */
10211022 public func track( event: String ? , properties: Properties ? = nil ) {
1023+ track ( event: event, withID: nil , properties: properties)
1024+ }
1025+
1026+ /**
1027+ Tracks an event with properties.
1028+ Properties are optional and can be added only if needed.
1029+
1030+ Properties will allow you to segment your events in your Mixpanel reports.
1031+ Property keys must be String objects and the supported value types need to conform to MixpanelType.
1032+ MixpanelType can be either String, Int, UInt, Double, Float, Bool, [MixpanelType], [String: MixpanelType], Date, URL, or NSNull.
1033+ If the event is being timed, the timer will stop and be added as a property.
1034+
1035+ - parameter event: event name
1036+ - parameter withID: eventID used to link timed events previously timed using `time(eventID)`
1037+ - parameter properties: properties dictionary
1038+ */
1039+ public func track( event: String ? , withID eventID: String ? , properties: Properties ? = nil ) {
10221040 if hasOptedOutTracking ( ) {
10231041 return
10241042 }
10251043
10261044 let epochInterval = Date ( ) . timeIntervalSince1970
10271045
1028- trackingQueue. async { [ weak self, event, properties, epochInterval] in
1046+ trackingQueue. async { [ weak self, event, eventID , properties, epochInterval] in
10291047 guard let self = self else {
10301048 return
10311049 }
@@ -1044,6 +1062,7 @@ extension MixpanelInstance {
10441062 alias: nil ,
10451063 hadPersistedDistinctId: self . hadPersistedDistinctId)
10461064 let timedEventsSnapshot = self . trackInstance. track ( event: event,
1065+ eventID: eventID,
10471066 properties: properties,
10481067 timedEvents: shadowTimedEvents,
10491068 superProperties: shadowSuperProperties,
@@ -1172,10 +1191,36 @@ extension MixpanelInstance {
11721191
11731192 */
11741193 public func time( event: String ) {
1194+ time ( eventID: event)
1195+ }
1196+
1197+ /**
1198+ Starts a timer that will be stopped and added as a property when a
1199+ corresponding event with the identidal eventID is tracked.
1200+
1201+ This method is intended to be used in advance of events that have
1202+ a duration. For example, if a developer were to track an "Image Upload" event
1203+ she might want to also know how long the upload took. Calling this method
1204+ before the upload code would implicitly cause the `track`
1205+ call to record its duration.
1206+
1207+ - precondition:
1208+ // begin timing the image upload:
1209+ mixpanelInstance.time(eventID:"some-unique-id")
1210+ // upload the image:
1211+ self.uploadImageWithSuccessHandler() { _ in
1212+ // track the event
1213+ mixpanelInstance.track("Image Upload", withID: "some-unique-id")
1214+ }
1215+
1216+ - parameter eventID: the id of the event to be timed
1217+
1218+ */
1219+ public func time( eventID: String ) {
11751220 let startTime = Date ( ) . timeIntervalSince1970
1176- trackingQueue. async { [ weak self, startTime, event ] in
1221+ trackingQueue. async { [ weak self, startTime, eventID ] in
11771222 guard let self = self else { return }
1178- let timedEvents = self . trackInstance. time ( event : event , timedEvents: self . timedEvents, startTime: startTime)
1223+ let timedEvents = self . trackInstance. time ( eventID : eventID , timedEvents: self . timedEvents, startTime: startTime)
11791224 self . readWriteLock. write {
11801225 self . timedEvents = timedEvents
11811226 }
@@ -1189,12 +1234,21 @@ extension MixpanelInstance {
11891234 - parameter event: the name of the event to be tracked that was passed to time(event:)
11901235 */
11911236 public func eventElapsedTime( event: String ) -> Double {
1237+ eventElapsedTime ( eventID: event)
1238+ }
1239+
1240+ /**
1241+ Retrieves the time elapsed for the event given it's ID since time(eventID:) was called.
1242+
1243+ - parameter event: the id of the event to be tracked that was passed to time(eventID:)
1244+ */
1245+ public func eventElapsedTime( eventID: String ) -> Double {
11921246 var timedEvents = TimedEvents ( )
11931247 self . readWriteLock. read {
11941248 timedEvents = self . timedEvents
11951249 }
11961250
1197- if let startTime = timedEvents [ event ] {
1251+ if let startTime = timedEvents [ eventID ] {
11981252 return Date ( ) . timeIntervalSince1970 - startTime
11991253 }
12001254 return 0
@@ -1219,10 +1273,19 @@ extension MixpanelInstance {
12191273 - parameter event: the name of the event to clear the timer for
12201274 */
12211275 public func clearTimedEvent( event: String ) {
1222- trackingQueue. async { [ weak self, event] in
1276+ clearTimedEvent ( eventId: event)
1277+ }
1278+
1279+ /**
1280+ Clears the event timer for the provided eventID.
1281+
1282+ - parameter event: the id of the event to clear the timer for
1283+ */
1284+ public func clearTimedEvent( eventId: String ) {
1285+ trackingQueue. async { [ weak self, eventId] in
12231286 guard let self = self else { return }
12241287
1225- let updatedTimedEvents = self . trackInstance. clearTimedEvent ( event : event , timedEvents: self . timedEvents)
1288+ let updatedTimedEvents = self . trackInstance. clearTimedEvent ( eventId : eventId , timedEvents: self . timedEvents)
12261289 MixpanelPersistence . saveTimedEvents ( timedEvents: updatedTimedEvents, instanceName: self . name)
12271290 }
12281291 }
0 commit comments