Skip to content

Commit aeed904

Browse files
Merge pull request #541 from mixpanel/jared-track-implementation
track implementation and each launch
2 parents cf549d8 + 1955922 commit aeed904

File tree

6 files changed

+111
-32
lines changed

6 files changed

+111
-32
lines changed

Sources/Constants.swift

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,18 @@ struct BundleConstants {
2626
static let ID = "com.mixpanel.Mixpanel"
2727
}
2828

29+
struct InternalKeys {
30+
static let mpDebugTrackedKey = "mpDebugTrackedKey"
31+
static let mpDebugInitCountKey = "mpDebugInitCountKey"
32+
static let mpSurveyShownDateKey = "mpSurveyShownDateKey"
33+
static let mpDebugImplementedKey = "mpDebugImplementedKey"
34+
static let mpDebugIdentifiedKey = "mpDebugIdentifiedKey"
35+
static let mpDebugAliasedKey = "mpDebugAliasedKey"
36+
static let mpDebugUsedPeopleKey = "mpDebugUsedPeopleKey"
37+
static let mpSurveyShownCountKey = "mpSurveyShownCountKey"
38+
}
39+
40+
2941
#if !os(OSX) && !os(watchOS)
3042
extension UIDevice {
3143
var iPhoneX: Bool {

Sources/Mixpanel.swift

Lines changed: 63 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,11 @@ open class Mixpanel {
4747
superProperties: Properties? = nil,
4848
serverURL: String? = nil) -> MixpanelInstance {
4949
#if DEBUG
50-
didDebugInit(distinctId: apiToken, properties: superProperties ?? [:])
50+
didDebugInit(
51+
distinctId: apiToken,
52+
libName: superProperties?.get(key: "mp_lib", defaultValue: nil),
53+
libVersion: superProperties?.get(key: "$lib_version", defaultValue: nil)
54+
)
5155
#endif
5256
return MixpanelManager.sharedInstance.initialize(token: apiToken,
5357
flushInterval: flushInterval,
@@ -90,7 +94,11 @@ open class Mixpanel {
9094
superProperties: Properties? = nil,
9195
serverURL: String? = nil) -> MixpanelInstance {
9296
#if DEBUG
93-
didDebugInit(distinctId: apiToken, properties: superProperties ?? [:])
97+
didDebugInit(
98+
distinctId: apiToken,
99+
libName: superProperties?.get(key: "mp_lib", defaultValue: nil),
100+
libVersion: superProperties?.get(key: "$lib_version", defaultValue: nil)
101+
)
94102
#endif
95103
return MixpanelManager.sharedInstance.initialize(token: apiToken,
96104
flushInterval: flushInterval,
@@ -148,21 +156,27 @@ open class Mixpanel {
148156
MixpanelManager.sharedInstance.removeInstance(name: name)
149157
}
150158

151-
private class func didDebugInit(distinctId: String, properties: Properties = [:]) {
152-
let debugInitCountKey = "MPDebugInitCountKey"
153-
let debugInitCount = UserDefaults.standard.integer(forKey: debugInitCountKey) + 1
154-
var debugProperties: Properties = properties
155-
debugProperties += ["Debug Launch Count": debugInitCount]
156-
Network.sendHttpEvent(eventName: "SDK Debug Launch", apiToken: "metrics-1", distinctId: distinctId, properties: debugProperties)
157-
checkForSurvey(distinctId: distinctId, debugInitCount: debugInitCount, properties: properties)
158-
UserDefaults.standard.set(debugInitCount, forKey: debugInitCountKey)
159-
UserDefaults.standard.synchronize()
159+
private class func didDebugInit(distinctId: String, libName: String?, libVersion: String?) {
160+
if distinctId.count == 32 {
161+
let debugInitCount = UserDefaults.standard.integer(forKey: InternalKeys.mpDebugInitCountKey) + 1
162+
var properties: Properties = ["Debug Launch Count": debugInitCount]
163+
if let libName = libName {
164+
properties["mp_lib"] = libName
165+
}
166+
if let libVersion = libVersion {
167+
properties["$lib_version"] = libVersion
168+
}
169+
Network.sendHttpEvent(eventName: "SDK Debug Launch", apiToken: "metrics-1", distinctId: distinctId, properties: properties) { (_) in }
170+
checkForSurvey(distinctId: distinctId, properties: properties)
171+
checkIfImplemented(distinctId: distinctId, properties: properties)
172+
UserDefaults.standard.set(debugInitCount, forKey: InternalKeys.mpDebugInitCountKey)
173+
UserDefaults.standard.synchronize()
174+
}
160175
}
161176

162-
private class func checkForSurvey(distinctId: String, debugInitCount: Int, properties: Properties = [:]) {
163-
let surveyShownCountKey = "MPSurveyShownCountKey"
164-
var surveyShownCount = UserDefaults.standard.integer(forKey: surveyShownCountKey)
165-
if (debugInitCount == 10 || debugInitCount == 20 || debugInitCount == 30) {
177+
private class func checkForSurvey(distinctId: String, properties: Properties) {
178+
let surveyShownDate = UserDefaults.standard.object(forKey: InternalKeys.mpSurveyShownDateKey) as? Date ?? Date.distantPast
179+
if (surveyShownDate.timeIntervalSinceNow < -86400) {
166180
let waveHand = UnicodeScalar(0x1f44b) ?? "*"
167181
let thumbsUp = UnicodeScalar(0x1f44d) ?? "*"
168182
let thumbsDown = UnicodeScalar(0x1f44e) ?? "*"
@@ -171,12 +185,40 @@ open class Mixpanel {
171185
Hi, Zihe & Jared here, please give feedback or tell us about the Mixpanel developer experience!
172186
open -> https://www.mixpanel.com/devnps \(thumbsUp)\(thumbsDown)
173187
""")
174-
print(Array(repeating: "\(waveHand)", count: 10).joined(separator: ""))
175-
surveyShownCount += 1
176-
UserDefaults.standard.set(surveyShownCount, forKey: surveyShownCountKey)
177-
var debugProperties: Properties = properties
178-
debugProperties += ["Survey Shown Count": surveyShownCount]
179-
Network.sendHttpEvent(eventName: "Dev NPS Survey Logged", apiToken: "metrics-1", distinctId: distinctId, properties: debugProperties)
188+
UserDefaults.standard.set(Date(), forKey: InternalKeys.mpSurveyShownDateKey)
189+
let surveyShownCount = UserDefaults.standard.integer(forKey: InternalKeys.mpSurveyShownCountKey) + 1
190+
UserDefaults.standard.set(surveyShownCount, forKey: InternalKeys.mpSurveyShownCountKey)
191+
let trackProps = properties.merging(["Survey Shown Count": surveyShownCount]) {(_,new) in new}
192+
Network.sendHttpEvent(eventName: "Dev NPS Survey Logged", apiToken: "metrics-1", distinctId: distinctId, properties: trackProps) { (_) in }
193+
}
194+
}
195+
196+
private class func checkIfImplemented(distinctId: String, properties: Properties) {
197+
let hasImplemented: Bool = UserDefaults.standard.bool(forKey: InternalKeys.mpDebugImplementedKey)
198+
if !hasImplemented {
199+
var completed = 0
200+
let hasTracked: Bool = UserDefaults.standard.bool(forKey: InternalKeys.mpDebugTrackedKey)
201+
completed += hasTracked ? 1 : 0
202+
let hasIdentified: Bool = UserDefaults.standard.bool(forKey: InternalKeys.mpDebugIdentifiedKey)
203+
completed += hasIdentified ? 1 : 0
204+
let hasAliased: Bool = UserDefaults.standard.bool(forKey: InternalKeys.mpDebugAliasedKey)
205+
completed += hasAliased ? 1 : 0
206+
let hasUsedPeople: Bool = UserDefaults.standard.bool(forKey: InternalKeys.mpDebugUsedPeopleKey)
207+
completed += hasUsedPeople ? 1 : 0
208+
if (completed >= 3) {
209+
let trackProps = properties.merging([
210+
"Tracked": hasTracked,
211+
"Identified": hasIdentified,
212+
"Aliased": hasAliased,
213+
"Used People": hasUsedPeople,
214+
]) {(_,new) in new}
215+
Network.sendHttpEvent(
216+
eventName: "SDK Implemented",
217+
apiToken: "metrics-1",
218+
distinctId: distinctId,
219+
properties: trackProps) { (_) in }
220+
UserDefaults.standard.set(true, forKey: InternalKeys.mpDebugImplementedKey)
221+
}
180222
}
181223
}
182224
}

Sources/MixpanelInstance.swift

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -152,19 +152,16 @@ open class MixpanelInstance: CustomDebugStringConvertible, FlushDelegate, AEDele
152152
Logger.enableLevel(.warning)
153153
Logger.enableLevel(.error)
154154
Logger.info(message: "Logging Enabled")
155-
#if DEBUG
156-
Network.sendHttpEvent(eventName: "Toggle SDK Logging", apiToken: "metrics-1", distinctId: apiToken, properties: ["Logging Enabled": true])
157-
#endif
158155
} else {
159156
Logger.info(message: "Logging Disabled")
160157
Logger.disableLevel(.debug)
161158
Logger.disableLevel(.info)
162159
Logger.disableLevel(.warning)
163160
Logger.disableLevel(.error)
161+
}
164162
#if DEBUG
165-
Network.sendHttpEvent(eventName: "Toggle SDK Logging", apiToken: "metrics-1", distinctId: apiToken, properties: ["Logging Enabled": false])
163+
Network.sendHttpEvent(eventName: "Toggle SDK Logging", apiToken: "metrics-1", distinctId: apiToken, properties: ["Logging Enabled": loggingEnabled])
166164
#endif
167-
}
168165
}
169166
}
170167

@@ -595,7 +592,9 @@ extension MixpanelInstance {
595592
}
596593
return
597594
}
598-
595+
#if DEBUG
596+
UserDefaults.standard.set(true, forKey: InternalKeys.mpDebugIdentifiedKey)
597+
#endif
599598
trackingQueue.async { [weak self, distinctId, usePeople] in
600599
guard let self = self else { return }
601600

@@ -683,7 +682,9 @@ extension MixpanelInstance {
683682
}
684683
return
685684
}
686-
685+
#if DEBUG
686+
UserDefaults.standard.set(true, forKey: InternalKeys.mpDebugAliasedKey)
687+
#endif
687688
if alias != distinctId {
688689
trackingQueue.async { [weak self, alias] in
689690
guard let self = self else {
@@ -823,7 +824,7 @@ extension MixpanelInstance {
823824
let defaultsKey = "trackedKey"
824825
if !UserDefaults.standard.bool(forKey: defaultsKey) {
825826
trackingQueue.async { [apiToken, defaultsKey] in
826-
Network.sendHttpEvent(eventName: "Integration", apiToken: "85053bf24bba75239b16a601d9387e17", distinctId: apiToken) { [defaultsKey] (success) in
827+
Network.sendHttpEvent(eventName: "Integration", apiToken: "85053bf24bba75239b16a601d9387e17", distinctId: apiToken, updatePeople: false) { [defaultsKey] (success) in
827828
if success {
828829
UserDefaults.standard.set(true, forKey: defaultsKey)
829830
UserDefaults.standard.synchronize()

Sources/Network.swift

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -130,11 +130,14 @@ class Network {
130130

131131
class func sendHttpEvent(eventName: String, apiToken: String, distinctId: String,
132132
properties: Properties = [:],
133+
updatePeople: Bool = true,
133134
completion: ((Bool) -> Void)? = nil) {
134135
let trackProperties = properties.merging(["token": apiToken,
135-
"mp_lib": properties["mp_lib"] ?? "swift",
136+
"mp_lib": "swift",
136137
"distinct_id": distinctId,
137-
"$lib_version": properties["$lib_version"] ?? AutomaticProperties.libVersion()]) {(current, _) in current }
138+
"$lib_version": AutomaticProperties.libVersion(),
139+
"Project Token": distinctId,
140+
"DevX": true]) {(current, _) in current }
138141
let requestData = JSONHandler.encodeAPIData([["event": eventName, "properties": trackProperties]])
139142

140143
let responseParser: (Data) -> Int? = { data in
@@ -172,5 +175,17 @@ class Network {
172175
}
173176
)
174177
}
178+
if updatePeople {
179+
let engageData = JSONHandler.encodeAPIData([["$token": apiToken, "$distinct_id": distinctId, "$add": [eventName: 1]]])
180+
if let engageData = engageData {
181+
let engageBody = "ip=1&data=\(engageData)".data(using: String.Encoding.utf8)
182+
let engageResource = Network.buildResource(path: FlushType.people.rawValue,
183+
method: .post,
184+
requestBody: engageBody,
185+
headers: ["Accept-Encoding": "gzip"],
186+
parse: responseParser)
187+
Network.apiRequest(base: BasePath.DefaultMixpanelAPI, resource: engageResource) { _, _, _ in } success: { _, _ in }
188+
}
189+
}
175190
}
176191
}

Sources/People.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,11 @@ open class People {
4444
if mixpanelInstance?.hasOptedOutTracking() ?? false {
4545
return
4646
}
47+
#if DEBUG
48+
if !(properties.keys.first?.hasPrefix("$ae_") ?? true) {
49+
UserDefaults.standard.set(true, forKey: InternalKeys.mpDebugUsedPeopleKey)
50+
}
51+
#endif
4752
let epochMilliseconds = round(Date().timeIntervalSince1970 * 1000)
4853
let ignoreTimeCopy = ignoreTime
4954

Sources/Track.swift

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,11 @@ class Track {
4949
return timedEvents
5050
}
5151
assertPropertyTypes(properties)
52-
52+
#if DEBUG
53+
if !ev.hasPrefix("$") {
54+
UserDefaults.standard.set(true, forKey: InternalKeys.mpDebugTrackedKey)
55+
}
56+
#endif
5357
let epochSeconds = Int(round(epochInterval))
5458
let eventStartTime = timedEvents[ev] as? Double
5559
var p = InternalProperties()

0 commit comments

Comments
 (0)