Skip to content

Commit f581143

Browse files
committed
Add SDK internal tracking
1 parent a578a0e commit f581143

File tree

5 files changed

+92
-50
lines changed

5 files changed

+92
-50
lines changed

MixpanelDemo/MixpanelDemo.xcodeproj/xcshareddata/xcschemes/MixpanelDemoWatch (Notification).xcscheme

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -55,16 +55,18 @@
5555
debugServiceExtension = "internal"
5656
allowLocationSimulation = "YES"
5757
launchAutomaticallySubstyle = "8">
58-
<BuildableProductRunnable
59-
runnableDebuggingMode = "0">
58+
<RemoteRunnable
59+
runnableDebuggingMode = "2"
60+
BundleIdentifier = "com.apple.Carousel"
61+
RemotePath = "/MixpanelDemo">
6062
<BuildableReference
6163
BuildableIdentifier = "primary"
6264
BlueprintIdentifier = "86F86E8A22440C5C00B69832"
6365
BuildableName = "MixpanelDemoWatch.app"
6466
BlueprintName = "MixpanelDemoWatch"
6567
ReferencedContainer = "container:MixpanelDemo.xcodeproj">
6668
</BuildableReference>
67-
</BuildableProductRunnable>
69+
</RemoteRunnable>
6870
</LaunchAction>
6971
<ProfileAction
7072
buildConfiguration = "Release"
@@ -73,16 +75,27 @@
7375
useCustomWorkingDirectory = "NO"
7476
debugDocumentVersioning = "YES"
7577
launchAutomaticallySubstyle = "8">
76-
<BuildableProductRunnable
77-
runnableDebuggingMode = "0">
78+
<RemoteRunnable
79+
runnableDebuggingMode = "2"
80+
BundleIdentifier = "com.apple.Carousel"
81+
RemotePath = "/MixpanelDemo">
7882
<BuildableReference
7983
BuildableIdentifier = "primary"
8084
BlueprintIdentifier = "86F86E8A22440C5C00B69832"
8185
BuildableName = "MixpanelDemoWatch.app"
8286
BlueprintName = "MixpanelDemoWatch"
8387
ReferencedContainer = "container:MixpanelDemo.xcodeproj">
8488
</BuildableReference>
85-
</BuildableProductRunnable>
89+
</RemoteRunnable>
90+
<MacroExpansion>
91+
<BuildableReference
92+
BuildableIdentifier = "primary"
93+
BlueprintIdentifier = "86F86E8A22440C5C00B69832"
94+
BuildableName = "MixpanelDemoWatch.app"
95+
BlueprintName = "MixpanelDemoWatch"
96+
ReferencedContainer = "container:MixpanelDemo.xcodeproj">
97+
</BuildableReference>
98+
</MacroExpansion>
8699
</ProfileAction>
87100
<AnalyzeAction
88101
buildConfiguration = "Debug">

MixpanelDemo/MixpanelDemo.xcodeproj/xcshareddata/xcschemes/MixpanelDemoWatch.xcscheme

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -54,33 +54,46 @@
5454
debugDocumentVersioning = "YES"
5555
debugServiceExtension = "internal"
5656
allowLocationSimulation = "YES">
57-
<BuildableProductRunnable
58-
runnableDebuggingMode = "0">
57+
<RemoteRunnable
58+
runnableDebuggingMode = "2"
59+
BundleIdentifier = "com.apple.Carousel"
60+
RemotePath = "/MixpanelDemo">
5961
<BuildableReference
6062
BuildableIdentifier = "primary"
6163
BlueprintIdentifier = "86F86E8A22440C5C00B69832"
6264
BuildableName = "MixpanelDemoWatch.app"
6365
BlueprintName = "MixpanelDemoWatch"
6466
ReferencedContainer = "container:MixpanelDemo.xcodeproj">
6567
</BuildableReference>
66-
</BuildableProductRunnable>
68+
</RemoteRunnable>
6769
</LaunchAction>
6870
<ProfileAction
6971
buildConfiguration = "Release"
7072
shouldUseLaunchSchemeArgsEnv = "YES"
7173
savedToolIdentifier = ""
7274
useCustomWorkingDirectory = "NO"
7375
debugDocumentVersioning = "YES">
74-
<BuildableProductRunnable
75-
runnableDebuggingMode = "0">
76+
<RemoteRunnable
77+
runnableDebuggingMode = "2"
78+
BundleIdentifier = "com.apple.Carousel"
79+
RemotePath = "/MixpanelDemo">
7680
<BuildableReference
7781
BuildableIdentifier = "primary"
7882
BlueprintIdentifier = "86F86E8A22440C5C00B69832"
7983
BuildableName = "MixpanelDemoWatch.app"
8084
BlueprintName = "MixpanelDemoWatch"
8185
ReferencedContainer = "container:MixpanelDemo.xcodeproj">
8286
</BuildableReference>
83-
</BuildableProductRunnable>
87+
</RemoteRunnable>
88+
<MacroExpansion>
89+
<BuildableReference
90+
BuildableIdentifier = "primary"
91+
BlueprintIdentifier = "86F86E8A22440C5C00B69832"
92+
BuildableName = "MixpanelDemoWatch.app"
93+
BlueprintName = "MixpanelDemoWatch"
94+
ReferencedContainer = "container:MixpanelDemo.xcodeproj">
95+
</BuildableReference>
96+
</MacroExpansion>
8497
</ProfileAction>
8598
<AnalyzeAction
8699
buildConfiguration = "Debug">

Sources/Mixpanel.swift

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ open class Mixpanel {
4747
superProperties: Properties? = nil,
4848
serverURL: String? = nil) -> MixpanelInstance {
4949
#if DEBUG
50-
didDebugInit(distinctId: apiToken)
50+
didDebugInit(distinctId: apiToken, properties: superProperties ?? [:])
5151
#endif
5252
return MixpanelManager.sharedInstance.initialize(token: apiToken,
5353
flushInterval: flushInterval,
@@ -90,7 +90,7 @@ open class Mixpanel {
9090
superProperties: Properties? = nil,
9191
serverURL: String? = nil) -> MixpanelInstance {
9292
#if DEBUG
93-
didDebugInit(distinctId: apiToken)
93+
didDebugInit(distinctId: apiToken, properties: superProperties ?? [:])
9494
#endif
9595
return MixpanelManager.sharedInstance.initialize(token: apiToken,
9696
flushInterval: flushInterval,
@@ -148,30 +148,35 @@ open class Mixpanel {
148148
MixpanelManager.sharedInstance.removeInstance(name: name)
149149
}
150150

151-
private class func didDebugInit(distinctId: String) {
151+
private class func didDebugInit(distinctId: String, properties: Properties = [:]) {
152152
let debugInitCountKey = "MPDebugInitCountKey"
153153
let debugInitCount = UserDefaults.standard.integer(forKey: debugInitCountKey) + 1
154-
if debugInitCount == 1 {
155-
Network.sendHttpEvent(eventName: "First SDK Debug Launch", apiToken: "metrics-1", distinctId: distinctId) { (_) in }
156-
}
157-
checkForSurvey(distinctId: distinctId, debugInitCount: debugInitCount)
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)
158158
UserDefaults.standard.set(debugInitCount, forKey: debugInitCountKey)
159159
UserDefaults.standard.synchronize()
160160
}
161161

162-
private class func checkForSurvey(distinctId: String, debugInitCount: Int) {
162+
private class func checkForSurvey(distinctId: String, debugInitCount: Int, properties: Properties = [:]) {
163163
let surveyShownCountKey = "MPSurveyShownCountKey"
164164
var surveyShownCount = UserDefaults.standard.integer(forKey: surveyShownCountKey)
165-
if (debugInitCount > 10 && surveyShownCount < 1) || (debugInitCount > 20 && surveyShownCount < 2) || (debugInitCount > 30 && surveyShownCount < 3) {
165+
if (debugInitCount == 10 || debugInitCount == 20 || debugInitCount == 30) {
166166
let waveHand = UnicodeScalar(0x1f44b) ?? "*"
167167
let thumbsUp = UnicodeScalar(0x1f44d) ?? "*"
168168
let thumbsDown = UnicodeScalar(0x1f44e) ?? "*"
169+
print(Array(repeating: "\(waveHand)", count: 5).joined(separator: ""))
169170
print("""
170-
\(waveHand)\(waveHand) Zihe & Jared here, tell us about the Mixpanel developer experience! https://www.mixpanel.com/devnps \(thumbsUp)\(thumbsDown)
171+
Hi, Zihe & Jared here, please tell us about the Mixpanel developer experience!
172+
open -> https://www.mixpanel.com/devnps \(thumbsUp)\(thumbsDown)
171173
""")
174+
print(Array(repeating: "\(waveHand)", count: 5).joined(separator: ""))
172175
surveyShownCount += 1
173176
UserDefaults.standard.set(surveyShownCount, forKey: surveyShownCountKey)
174-
Network.sendHttpEvent(eventName: "Dev NPS Survey Logged", apiToken: "metrics-1", distinctId: distinctId, properties: ["Survey Shown Count": surveyShownCount, "Debug Launch Count": debugInitCount]) { (_) in }
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)
175180
}
176181
}
177182
}

Sources/MixpanelInstance.swift

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -151,15 +151,19 @@ open class MixpanelInstance: CustomDebugStringConvertible, FlushDelegate, AEDele
151151
Logger.enableLevel(.info)
152152
Logger.enableLevel(.warning)
153153
Logger.enableLevel(.error)
154-
155154
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
156158
} else {
157159
Logger.info(message: "Logging Disabled")
158-
159160
Logger.disableLevel(.debug)
160161
Logger.disableLevel(.info)
161162
Logger.disableLevel(.warning)
162163
Logger.disableLevel(.error)
164+
#if DEBUG
165+
Network.sendHttpEvent(eventName: "Toggle SDK Logging", apiToken: "metrics-1", distinctId: apiToken, properties: ["Logging Enabled": false])
166+
#endif
163167
}
164168
}
165169
}

Sources/Network.swift

Lines changed: 32 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import Foundation
1111
struct BasePath {
1212
static let DefaultMixpanelAPI = "https://api.mixpanel.com"
1313
static var namedBasePaths = [String: String]()
14-
14+
1515
static func buildURL(base: String, path: String, queryItems: [URLQueryItem]?) -> URL? {
1616
guard let url = URL(string: base) else {
1717
return nil
@@ -25,7 +25,7 @@ struct BasePath {
2525
components.percentEncodedQuery = components.percentEncodedQuery?.replacingOccurrences(of: "+", with: "%2B")
2626
return components.url
2727
}
28-
28+
2929
static func getServerURL(identifier: String) -> String {
3030
return namedBasePaths[identifier] ?? DefaultMixpanelAPI
3131
}
@@ -53,24 +53,24 @@ enum Reason {
5353
}
5454

5555
class Network {
56-
56+
5757
let basePathIdentifier: String
58-
58+
5959
required init(basePathIdentifier: String) {
6060
self.basePathIdentifier = basePathIdentifier
6161
}
62-
62+
6363
class func apiRequest<A>(base: String,
6464
resource: Resource<A>,
6565
failure: @escaping (Reason, Data?, URLResponse?) -> Void,
6666
success: @escaping (A, URLResponse?) -> Void) {
6767
guard let request = buildURLRequest(base, resource: resource) else {
6868
return
6969
}
70-
70+
7171
URLSession.shared.dataTask(with: request) { (data, response, error) -> Void in
7272
guard let httpResponse = response as? HTTPURLResponse else {
73-
73+
7474
if let hasError = error {
7575
failure(.other(hasError), data, response)
7676
} else {
@@ -90,30 +90,30 @@ class Network {
9090
failure(.parseError, data, response)
9191
return
9292
}
93-
93+
9494
success(result, response)
9595
}.resume()
9696
}
97-
97+
9898
private class func buildURLRequest<A>(_ base: String, resource: Resource<A>) -> URLRequest? {
9999
guard let url = BasePath.buildURL(base: base,
100100
path: resource.path,
101101
queryItems: resource.queryItems) else {
102102
return nil
103103
}
104-
104+
105105
Logger.debug(message: "Fetching URL")
106106
Logger.debug(message: url.absoluteURL)
107107
var request = URLRequest(url: url)
108108
request.httpMethod = resource.method.rawValue
109109
request.httpBody = resource.requestBody
110-
110+
111111
for (k, v) in resource.headers {
112112
request.setValue(v, forHTTPHeaderField: k)
113113
}
114114
return request as URLRequest
115115
}
116-
116+
117117
class func buildResource<A>(path: String,
118118
method: RequestMethod,
119119
requestBody: Data? = nil,
@@ -127,42 +127,49 @@ class Network {
127127
headers: headers,
128128
parse: parse)
129129
}
130-
131-
class func sendHttpEvent(eventName: String, apiToken: String, distinctId: String, properties: Dictionary<String, Any> = [:], completion: @escaping (Bool) -> Void) {
130+
131+
class func sendHttpEvent(eventName: String, apiToken: String, distinctId: String,
132+
properties: Properties = [:],
133+
completion: ((Bool) -> Void)? = nil) {
132134
let trackProperties = properties.merging(["token": apiToken,
133-
"mp_lib": "swift",
135+
"mp_lib": properties["mp_lib"] ?? "swift",
134136
"distinct_id": distinctId,
135-
"$lib_version": AutomaticProperties.libVersion()]) {(current, _) in current }
137+
"$lib_version": properties["$lib_version"] ?? AutomaticProperties.libVersion()]) {(current, _) in current }
136138
let requestData = JSONHandler.encodeAPIData([["event": eventName, "properties": trackProperties]])
137-
139+
138140
let responseParser: (Data) -> Int? = { data in
139141
let response = String(data: data, encoding: String.Encoding.utf8)
140142
if let response = response {
141143
return Int(response) ?? 0
142144
}
143145
return nil
144146
}
145-
147+
146148
if let requestData = requestData {
147149
let requestBody = "ip=1&data=\(requestData)"
148150
.data(using: String.Encoding.utf8)
149-
151+
150152
let resource = Network.buildResource(path: FlushType.events.rawValue,
151153
method: .post,
152154
requestBody: requestBody,
153155
headers: ["Accept-Encoding": "gzip"],
154156
parse: responseParser)
155-
157+
156158
Network.apiRequest(base: BasePath.DefaultMixpanelAPI,
157159
resource: resource,
158160
failure: { (_, _, _) in
159-
Logger.debug(message: "failed to track \(eventName)")
160-
completion(false)
161-
},
161+
Logger.debug(message: "failed to track \(eventName)")
162+
if let completion = completion {
163+
completion(false)
164+
}
165+
166+
},
162167
success: { (_, _) in
163-
Logger.debug(message: "\(eventName) tracked")
164-
completion(true)
168+
Logger.debug(message: "\(eventName) tracked")
169+
if let completion = completion {
170+
completion(true)
165171
}
172+
}
166173
)
167174
}
168175
}

0 commit comments

Comments
 (0)