code review feedback

This commit is contained in:
Zihe Jia 2021-08-27 17:03:55 -07:00
parent d73da7f47f
commit 74bce0de3c
17 changed files with 179 additions and 111 deletions

View file

@ -62,10 +62,10 @@ class GDPRViewController: UIViewController, UITableViewDelegate, UITableViewData
Mixpanel.mainInstance().optInTracking(distinctId: "aDistinctIdForOptIn", properties: p)
descStr = "Opt In with distinctId 'aDistinctIdForOptIn' and \(p)"
case 5:
Mixpanel.initialize(token: "a token id", optOutTrackingByDefault: true)
Mixpanel.initialize(token: "testtoken", optOutTrackingByDefault: true)
descStr = "Init Mixpanel with default opt-out(sample only), to make it work, place it in your startup stage of your app"
case 6:
Mixpanel.initialize(token: "a token id", optOutTrackingByDefault: false)
Mixpanel.initialize(token: "testtoken", optOutTrackingByDefault: false)
descStr = "Init Mixpanel with default opt-in(sample only), to make it work, place it in your startup stage of your app"
default:
break

View file

@ -32,7 +32,7 @@ class LoginViewController: UIViewController {
@IBAction func start(_ sender: Any) {
// Mixpanel.mainInstance().identify(distinctId: distinctIdTextField.text ?? "")
Mixpanel.mainInstance().identify(distinctId: distinctIdTextField.text ?? "demo_user")
Mixpanel.mainInstance().people.set(property: "$name", to: nameTextField.text ?? "")
Mixpanel.mainInstance().track(event: "Logged in")
Mixpanel.mainInstance().flush()

View file

@ -107,12 +107,12 @@ class PeopleViewController: UIViewController, UITableViewDelegate, UITableViewDa
break
}
// let vc = storyboard!.instantiateViewController(withIdentifier: "ActionCompleteViewController") as! ActionCompleteViewController
// vc.actionStr = actionStr
// vc.descStr = descStr
// vc.modalTransitionStyle = UIModalTransitionStyle.crossDissolve
// vc.modalPresentationStyle = UIModalPresentationStyle.overFullScreen
// present(vc, animated: true, completion: nil)
let vc = storyboard!.instantiateViewController(withIdentifier: "ActionCompleteViewController") as! ActionCompleteViewController
vc.actionStr = actionStr
vc.descStr = descStr
vc.modalTransitionStyle = UIModalTransitionStyle.crossDissolve
vc.modalPresentationStyle = UIModalPresentationStyle.overFullScreen
present(vc, animated: true, completion: nil)
}

View file

@ -22,8 +22,6 @@ class TrackingViewController: UIViewController, UITableViewDelegate, UITableView
"Register SuperProperties Once",
"Register SP Once w Default Value",
"Unregister SuperProperty"]
var trackCounter: Int = 0
override func viewDidLoad() {
super.viewDidLoad()

View file

@ -58,6 +58,7 @@ class MixpanelDemoTests: MixpanelBaseTests {
testMixpanel.track(event: "event \(i)")
}
flushAndWaitForTrackingQueue(testMixpanel)
sleep(1)
XCTAssertTrue(eventQueue(token: testMixpanel.apiToken).isEmpty,
"events should have been flushed")
@ -65,6 +66,7 @@ class MixpanelDemoTests: MixpanelBaseTests {
testMixpanel.track(event: "event \(i)")
}
flushAndWaitForTrackingQueue(testMixpanel)
sleep(1)
XCTAssertTrue(eventQueue(token: testMixpanel.apiToken).isEmpty,
"events should have been flushed")
removeDBfile(testMixpanel.apiToken)
@ -79,11 +81,13 @@ class MixpanelDemoTests: MixpanelBaseTests {
testMixpanel.people.set(property: "p1", to: "\(i)")
}
flushAndWaitForTrackingQueue(testMixpanel)
sleep(1)
XCTAssertTrue(peopleQueue(token: testMixpanel.apiToken).isEmpty, "people should have been flushed")
for i in 0..<60 {
testMixpanel.people.set(property: "p1", to: "\(i)")
}
flushAndWaitForTrackingQueue(testMixpanel)
sleep(1)
XCTAssertTrue(peopleQueue(token: testMixpanel.apiToken).isEmpty, "people should have been flushed")
removeDBfile(testMixpanel.apiToken)
}
@ -98,11 +102,13 @@ class MixpanelDemoTests: MixpanelBaseTests {
testMixpanel.getGroup(groupKey: groupKey, groupID: groupValue).set(property: "p1", to: "\(i)")
}
flushAndWaitForTrackingQueue(testMixpanel)
sleep(1)
XCTAssertTrue(groupQueue(token: testMixpanel.apiToken).isEmpty, "groups should have been flushed")
for i in 0..<60 {
testMixpanel.getGroup(groupKey: groupKey, groupID: groupValue).set(property: "p1", to: "\(i)")
}
flushAndWaitForTrackingQueue(testMixpanel)
sleep(1)
XCTAssertTrue(peopleQueue(token: testMixpanel.apiToken).isEmpty, "groups should have been flushed")
removeDBfile(testMixpanel.apiToken)
}
@ -237,6 +243,7 @@ class MixpanelDemoTests: MixpanelBaseTests {
"incorrect project token in people record")
testMixpanel.identify(distinctId: distinctId)
waitForTrackingQueue(testMixpanel)
sleep(2)
let anonymousId = testMixpanel.anonymousId
peopleQueue_value = peopleQueue(token: testMixpanel.apiToken)
unidentifiedQueue = unIdentifiedPeopleQueue(token: testMixpanel.apiToken)
@ -288,11 +295,9 @@ class MixpanelDemoTests: MixpanelBaseTests {
let distinctIdBeforeIdentify: String? = testMixpanel.distinctId
let distinctId = "testIdentifyTrack"
testMixpanel.identify(distinctId: distinctId)
testMixpanel.identify(distinctId: distinctId)
waitForTrackingQueue(testMixpanel)
waitForTrackingQueue(testMixpanel)
sleep(1)
let e: InternalProperties = eventQueue(token: testMixpanel.apiToken).last!
XCTAssertEqual(e["event"] as? String, "$identify", "incorrect event name")
let p: InternalProperties = e["properties"] as! InternalProperties
@ -315,7 +320,7 @@ class MixpanelDemoTests: MixpanelBaseTests {
let newDistinctId = distinctId + String(i)
testMixpanel.identify(distinctId: newDistinctId)
waitForTrackingQueue(testMixpanel)
waitForTrackingQueue(testMixpanel)
sleep(1)
let e: InternalProperties = eventQueue(token: testMixpanel.apiToken).last!
XCTAssertEqual(e["event"] as? String, "$identify", "incorrect event name")
@ -339,21 +344,22 @@ class MixpanelDemoTests: MixpanelBaseTests {
let alias: String = "a1"
testMixpanel.identify(distinctId: distinctId)
waitForTrackingQueue(testMixpanel)
sleep(1)
testMixpanel.createAlias(alias, distinctId: testMixpanel.distinctId)
waitForTrackingQueue(testMixpanel)
var mixpanelIdentity = testMixpanel.mixpanelPersistence.loadIdentity()
var mixpanelIdentity = MixpanelPersistence.loadIdentity(apiToken: testMixpanel.apiToken)
XCTAssertTrue(distinctId == mixpanelIdentity.distinctID && distinctId == mixpanelIdentity.peopleDistinctID && distinctId == mixpanelIdentity.userId && alias == mixpanelIdentity.alias)
testMixpanel.archive()
waitForTrackingQueue(testMixpanel)
testMixpanel.unarchive()
waitForTrackingQueue(testMixpanel)
mixpanelIdentity = testMixpanel.mixpanelPersistence.loadIdentity()
XCTAssertTrue(testMixpanel.distinctId == mixpanelIdentity.distinctID && testMixpanel.people.distinctId == mixpanelIdentity.peopleDistinctID && testMixpanel.anonymousId == mixpanelIdentity.anoymousId &&
mixpanelIdentity = MixpanelPersistence.loadIdentity(apiToken: testMixpanel.apiToken)
XCTAssertTrue(testMixpanel.distinctId == mixpanelIdentity.distinctID && testMixpanel.people.distinctId == mixpanelIdentity.peopleDistinctID && testMixpanel.anonymousId == mixpanelIdentity.anonymousId &&
testMixpanel.userId == mixpanelIdentity.userId && testMixpanel.alias == mixpanelIdentity.alias)
testMixpanel.mixpanelPersistence.deleteMPUserDefaultsData()
MixpanelPersistence.deleteMPUserDefaultsData(apiToken: testMixpanel.apiToken)
waitForTrackingQueue(testMixpanel)
mixpanelIdentity = testMixpanel.mixpanelPersistence.loadIdentity()
XCTAssertTrue("" == mixpanelIdentity.distinctID && nil == mixpanelIdentity.peopleDistinctID && nil == mixpanelIdentity.anoymousId && nil == mixpanelIdentity.userId && nil == mixpanelIdentity.alias)
mixpanelIdentity = MixpanelPersistence.loadIdentity(apiToken: testMixpanel.apiToken)
XCTAssertTrue("" == mixpanelIdentity.distinctID && nil == mixpanelIdentity.peopleDistinctID && nil == mixpanelIdentity.anonymousId && nil == mixpanelIdentity.userId && nil == mixpanelIdentity.alias)
removeDBfile(testMixpanel.apiToken)
}
@ -373,6 +379,7 @@ class MixpanelDemoTests: MixpanelBaseTests {
let userId: String = "u1"
testMixpanel.identify(distinctId: userId)
waitForTrackingQueue(testMixpanel)
sleep(1)
XCTAssertEqual(testMixpanel.anonymousId, distinctId)
XCTAssertEqual(testMixpanel.userId, userId)
XCTAssertEqual(testMixpanel.distinctId, userId)
@ -590,6 +597,7 @@ class MixpanelDemoTests: MixpanelBaseTests {
let testMixpanel = Mixpanel.initialize(token: randomId(), flushInterval: 60)
testMixpanel.identify(distinctId: "d1")
testMixpanel.track(event: "e1")
sleep(1)
let p: Properties = ["p1": "a"]
testMixpanel.registerSuperProperties(p)
testMixpanel.people.set(properties: p)
@ -670,6 +678,7 @@ class MixpanelDemoTests: MixpanelBaseTests {
let p: Properties = ["p1": "a"]
testMixpanel.identify(distinctId: "d1")
waitForTrackingQueue(testMixpanel)
sleep(1)
testMixpanel.registerSuperProperties(p)
testMixpanel.track(event: "e1")
testMixpanel.track(event: "e2")
@ -738,6 +747,7 @@ class MixpanelDemoTests: MixpanelBaseTests {
testMixpanel.track(event: "e1")
testMixpanel.people.set(property: "p1", to: "a")
waitForTrackingQueue(testMixpanel)
sleep(1)
flushAndWaitForTrackingQueue(testMixpanel)
XCTAssertTrue(eventQueue(token: testMixpanel.apiToken).count == 2, "delegate should have stopped flush")
XCTAssertTrue(peopleQueue(token: testMixpanel.apiToken).count == 1, "delegate should have stopped flush")
@ -772,17 +782,17 @@ class MixpanelDemoTests: MixpanelBaseTests {
testMixpanel.time(event: "Time Event B")
testMixpanel.time(event: "Time Event C")
waitForTrackingQueue(testMixpanel)
var testTimedEvents = testMixpanel.mixpanelPersistence.loadTimedEvents()
var testTimedEvents = MixpanelPersistence.loadTimedEvents(apiToken: testMixpanel.apiToken)
XCTAssertTrue(testTimedEvents.count == 3, "Each call to time() should add an event to timedEvents")
XCTAssertNotNil(testTimedEvents["Time Event A"], "Keys in timedEvents should be event names")
testMixpanel.clearTimedEvent(event: "Time Event A")
waitForTrackingQueue(testMixpanel)
testTimedEvents = testMixpanel.mixpanelPersistence.loadTimedEvents()
testTimedEvents = MixpanelPersistence.loadTimedEvents(apiToken: testMixpanel.apiToken)
XCTAssertNil(testTimedEvents["Time Event A"], "clearTimedEvent should remove key/value pair")
XCTAssertTrue(testTimedEvents.count == 2, "clearTimedEvent shoud remove only one key/value pair")
testMixpanel.clearTimedEvents()
waitForTrackingQueue(testMixpanel)
XCTAssertTrue(testMixpanel.mixpanelPersistence.loadTimedEvents().count == 0, "clearTimedEvents should remove all key/value pairs")
XCTAssertTrue(MixpanelPersistence.loadTimedEvents(apiToken: testMixpanel.apiToken).count == 0, "clearTimedEvents should remove all key/value pairs")
removeDBfile(testMixpanel.apiToken)
}
@ -816,6 +826,7 @@ class MixpanelDemoTests: MixpanelBaseTests {
let groupValue = "test_value"
testMixpanel.setGroup(groupKey: groupKey, groupIDs: [groupValue])
waitForTrackingQueue(testMixpanel)
sleep(1)
XCTAssertEqual(testMixpanel.currentSuperProperties()[groupKey] as? [String], [groupValue])
let q = peopleQueue(token: testMixpanel.apiToken).last!["$set"] as! InternalProperties
XCTAssertEqual(q[groupKey] as? [String], [groupValue], "group value people property not queued")
@ -833,6 +844,7 @@ class MixpanelDemoTests: MixpanelBaseTests {
testMixpanel.addGroup(groupKey: groupKey, groupID: groupValue)
waitForTrackingQueue(testMixpanel)
sleep(1)
XCTAssertEqual(testMixpanel.currentSuperProperties()[groupKey] as? [String], [groupValue])
waitForTrackingQueue(testMixpanel)
let q = peopleQueue(token: testMixpanel.apiToken).last!["$set"] as! InternalProperties
@ -869,6 +881,7 @@ class MixpanelDemoTests: MixpanelBaseTests {
testMixpanel.setGroup(groupKey: groupKey, groupIDs: [groupValue, newVal])
waitForTrackingQueue(testMixpanel)
sleep(1)
XCTAssertEqual(testMixpanel.currentSuperProperties()[groupKey] as? [String], [groupValue, newVal])
testMixpanel.removeGroup(groupKey: groupKey, groupID: groupValue)
@ -891,7 +904,7 @@ class MixpanelDemoTests: MixpanelBaseTests {
func testReadWriteMultiThreadShouldNotCrash() {
let concurentQueue = DispatchQueue(label: "multithread", attributes: .concurrent)
let testMixpanel = Mixpanel.initialize(token: randomId(), flushInterval: 60)
for n in 1...10 {
concurentQueue.async {
testMixpanel.track(event: "event\(n)")
@ -976,3 +989,5 @@ class MixpanelDemoTests: MixpanelBaseTests {
}
}

View file

@ -44,6 +44,7 @@ class MixpanelOptOutTests: MixpanelBaseTests {
testMixpanel.optInTracking(distinctId: "testDistinctId")
XCTAssertFalse(testMixpanel.hasOptedOutTracking(), "The current user should have opted in tracking")
waitForTrackingQueue(testMixpanel)
sleep(1)
let event = eventQueue(token: testMixpanel.apiToken).first
XCTAssertEqual((event!["event"] as? String), "$opt_in", "When opted in, a track '$opt_in' should have been queued")
XCTAssertEqual(testMixpanel.distinctId, "testDistinctId", "mixpanel identify failed to set distinct id")
@ -62,6 +63,7 @@ class MixpanelOptOutTests: MixpanelBaseTests {
let testMixpanel = Mixpanel.initialize(token: randomId(), optOutTrackingByDefault: true)
testMixpanel.optInTracking(distinctId: "testDistinctId", properties: testProperties)
waitForTrackingQueue(testMixpanel)
sleep(1)
let eventQueueValue = eventQueue(token: testMixpanel.apiToken)
let props = eventQueueValue.first!["properties"] as? InternalProperties

View file

@ -17,9 +17,11 @@ class MixpanelPeopleTests: MixpanelBaseTests {
func testPeopleSet() {
let testMixpanel = Mixpanel.initialize(token: randomId(), flushInterval: 60)
testMixpanel.identify(distinctId: "d1")
waitForTrackingQueue(testMixpanel)
let p: Properties = ["p1": "a"]
testMixpanel.people.set(properties: p)
waitForTrackingQueue(testMixpanel)
sleep(1)
let q = peopleQueue(token: testMixpanel.apiToken).last!["$set"] as! InternalProperties
XCTAssertEqual(q["p1"] as? String, "a", "custom people property not queued")
assertDefaultPeopleProperties(q)
@ -32,6 +34,7 @@ class MixpanelPeopleTests: MixpanelBaseTests {
let p: Properties = ["p1": "a"]
testMixpanel.people.setOnce(properties: p)
waitForTrackingQueue(testMixpanel)
sleep(1)
let q = peopleQueue(token: testMixpanel.apiToken).last!["$set_once"] as! InternalProperties
XCTAssertEqual(q["p1"] as? String, "a", "custom people property not queued")
assertDefaultPeopleProperties(q)
@ -44,6 +47,7 @@ class MixpanelPeopleTests: MixpanelBaseTests {
let p: Properties = ["$ios_app_version": "override"]
testMixpanel.people.set(properties: p)
waitForTrackingQueue(testMixpanel)
sleep(1)
let q = peopleQueue(token: testMixpanel.apiToken).last!["$set"] as! InternalProperties
XCTAssertEqual(q["$ios_app_version"] as? String,
"override",
@ -57,6 +61,7 @@ class MixpanelPeopleTests: MixpanelBaseTests {
testMixpanel.identify(distinctId: "d1")
testMixpanel.people.set(property: "p1", to: "a")
waitForTrackingQueue(testMixpanel)
sleep(1)
let p: InternalProperties = peopleQueue(token: testMixpanel.apiToken).last!["$set"] as! InternalProperties
XCTAssertEqual(p["p1"] as? String, "a", "custom people property not queued")
assertDefaultPeopleProperties(p)
@ -69,6 +74,7 @@ class MixpanelPeopleTests: MixpanelBaseTests {
testMixpanel.people.set(property: "i", to: i)
}
waitForTrackingQueue(testMixpanel)
sleep(1)
XCTAssertTrue(unIdentifiedPeopleQueue(token: testMixpanel.apiToken).count == 505)
var r: InternalProperties = unIdentifiedPeopleQueue(token: testMixpanel.apiToken).first!
XCTAssertEqual((r["$set"] as? InternalProperties)?["i"] as? Int, 0)
@ -101,6 +107,7 @@ class MixpanelPeopleTests: MixpanelBaseTests {
let p: Properties = ["p1": 3]
testMixpanel.people.increment(properties: p)
waitForTrackingQueue(testMixpanel)
sleep(1)
let q = peopleQueue(token: testMixpanel.apiToken).last!["$add"] as! InternalProperties
XCTAssertTrue(q.count == 1, "incorrect people properties: \(p)")
XCTAssertEqual(q["p1"] as? Int, 3, "custom people property not queued")
@ -112,6 +119,7 @@ class MixpanelPeopleTests: MixpanelBaseTests {
testMixpanel.identify(distinctId: "d1")
testMixpanel.people.increment(property: "p1", by: 3)
waitForTrackingQueue(testMixpanel)
sleep(1)
let p: InternalProperties = peopleQueue(token: testMixpanel.apiToken).last!["$add"] as! InternalProperties
XCTAssertTrue(p.count == 1, "incorrect people properties: \(p)")
XCTAssertEqual(p["p1"] as? Double, 3, "custom people property not queued")
@ -123,6 +131,7 @@ class MixpanelPeopleTests: MixpanelBaseTests {
testMixpanel.identify(distinctId: "d1")
testMixpanel.people.deleteUser()
waitForTrackingQueue(testMixpanel)
sleep(1)
let p: InternalProperties = peopleQueue(token: testMixpanel.apiToken).last!["$delete"] as! InternalProperties
XCTAssertTrue(p.isEmpty, "incorrect people properties: \(p)")
removeDBfile(testMixpanel.apiToken)
@ -134,6 +143,7 @@ class MixpanelPeopleTests: MixpanelBaseTests {
testMixpanel.identify(distinctId: "d1")
testMixpanel.people.trackCharge(amount: 25.34)
waitForTrackingQueue(testMixpanel)
sleep(1)
let r: InternalProperties = peopleQueue(token: testMixpanel.apiToken).last!
let prop = ((r["$append"] as? InternalProperties)?["$transactions"] as? InternalProperties)?["$amount"] as? Double
let prop2 = ((r["$append"] as? InternalProperties)?["$transactions"] as? InternalProperties)?["$time"]
@ -145,8 +155,10 @@ class MixpanelPeopleTests: MixpanelBaseTests {
func testPeopleTrackChargeZero() {
let testMixpanel = Mixpanel.initialize(token: randomId(), flushInterval: 60)
testMixpanel.identify(distinctId: "d1")
waitForTrackingQueue(testMixpanel)
testMixpanel.people.trackCharge(amount: 0)
waitForTrackingQueue(testMixpanel)
sleep(1)
let r: InternalProperties = peopleQueue(token: testMixpanel.apiToken).last!
let prop = ((r["$append"] as? InternalProperties)?["$transactions"] as? InternalProperties)?["$amount"] as? Double
let prop2 = ((r["$append"] as? InternalProperties)?["$transactions"] as? InternalProperties)?["$time"]
@ -161,6 +173,7 @@ class MixpanelPeopleTests: MixpanelBaseTests {
let p: Properties = allPropertyTypes()
testMixpanel.people.trackCharge(amount: 25, properties: ["$time": p["date"]!])
waitForTrackingQueue(testMixpanel)
sleep(1)
let r: InternalProperties = peopleQueue(token: testMixpanel.apiToken).last!
let prop = ((r["$append"] as? InternalProperties)?["$transactions"] as? InternalProperties)?["$amount"] as? Double
let prop2 = ((r["$append"] as? InternalProperties)?["$transactions"] as? InternalProperties)?["$time"] as? String
@ -174,6 +187,7 @@ class MixpanelPeopleTests: MixpanelBaseTests {
testMixpanel.identify(distinctId: "d1")
testMixpanel.people.trackCharge(amount: 25, properties: ["p1": "a"])
waitForTrackingQueue(testMixpanel)
sleep(1)
let r: InternalProperties = peopleQueue(token: testMixpanel.apiToken).last!
let prop = ((r["$append"] as? InternalProperties)?["$transactions"] as? InternalProperties)?["$amount"] as? Double
let prop2 = ((r["$append"] as? InternalProperties)?["$transactions"] as? InternalProperties)?["p1"]
@ -187,6 +201,7 @@ class MixpanelPeopleTests: MixpanelBaseTests {
testMixpanel.identify(distinctId: "d1")
testMixpanel.people.trackCharge(amount: 25)
waitForTrackingQueue(testMixpanel)
sleep(1)
let r: InternalProperties = peopleQueue(token: testMixpanel.apiToken).last!
let prop = ((r["$append"] as? InternalProperties)?["$transactions"] as? InternalProperties)?["$amount"] as? Double
let prop2 = ((r["$append"] as? InternalProperties)?["$transactions"] as? InternalProperties)?["$time"]
@ -200,6 +215,7 @@ class MixpanelPeopleTests: MixpanelBaseTests {
testMixpanel.identify(distinctId: "d1")
testMixpanel.people.clearCharges()
waitForTrackingQueue(testMixpanel)
sleep(1)
let r: InternalProperties = peopleQueue(token: testMixpanel.apiToken).last!
let transactions = (r["$set"] as? InternalProperties)?["$transactions"] as? [MixpanelType]
XCTAssertEqual(transactions?.count, 0)

View file

@ -23,7 +23,6 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
Mixpanel.initialize(token: "MIXPANEL_TOKEN")
Mixpanel.mainInstance().loggingEnabled = true
Mixpanel.mainInstance().registerSuperProperties(["super apple tv properties": 1]);
Mixpanel.mainInstance().track(event: "apple tv track")
return true

View file

@ -51,7 +51,7 @@ class MixpanelAutomaticEventsTests: MixpanelBaseTests {
let testMixpanel = Mixpanel.initialize(token: randomId(), flushInterval: 60)
testMixpanel.minimumSessionDuration = 0;
testMixpanel.trackAutomaticEventsEnabled = false
MixpanelPersistence.init(token: testMixpanel.apiToken).saveAutomacticEventsEnabledFlag(value: true, fromDecide: true)
MixpanelPersistence.saveAutomacticEventsEnabledFlag(value: true, fromDecide: true, apiToken: testMixpanel.apiToken)
testMixpanel.automaticEvents.perform(#selector(AutomaticEvents.appWillResignActive(_:)),
with: Notification(name: Notification.Name(rawValue: "test")))
waitForTrackingQueue(testMixpanel)
@ -63,7 +63,7 @@ class MixpanelAutomaticEventsTests: MixpanelBaseTests {
let testMixpanel = Mixpanel.initialize(token: randomId(), flushInterval: 60)
testMixpanel.minimumSessionDuration = 0;
testMixpanel.trackAutomaticEventsEnabled = true
MixpanelPersistence.init(token: testMixpanel.apiToken).saveAutomacticEventsEnabledFlag(value: false, fromDecide: true)
MixpanelPersistence.saveAutomacticEventsEnabledFlag(value: false, fromDecide: true, apiToken: testMixpanel.apiToken)
testMixpanel.automaticEvents.perform(#selector(AutomaticEvents.appWillResignActive(_:)),
with: Notification(name: Notification.Name(rawValue: "test")))
waitForTrackingQueue(testMixpanel)
@ -78,7 +78,7 @@ class MixpanelAutomaticEventsTests: MixpanelBaseTests {
func testDiscardAutomaticEventsIfDecideIsFalse() {
let testMixpanel = Mixpanel.initialize(token: randomId(), flushInterval: 60)
testMixpanel.minimumSessionDuration = 0;
MixpanelPersistence.init(token: testMixpanel.apiToken).saveAutomacticEventsEnabledFlag(value: false, fromDecide: true)
MixpanelPersistence.saveAutomacticEventsEnabledFlag(value: false, fromDecide: true, apiToken: testMixpanel.apiToken)
testMixpanel.automaticEvents.perform(#selector(AutomaticEvents.appWillResignActive(_:)),
with: Notification(name: Notification.Name(rawValue: "test")))
@ -90,7 +90,7 @@ class MixpanelAutomaticEventsTests: MixpanelBaseTests {
func testFlushAutomaticEventsIfDecideIsTrue() {
let testMixpanel = Mixpanel.initialize(token: randomId(), flushInterval: 60)
testMixpanel.minimumSessionDuration = 0;
MixpanelPersistence.init(token: testMixpanel.apiToken).saveAutomacticEventsEnabledFlag(value: true, fromDecide: true)
MixpanelPersistence.saveAutomacticEventsEnabledFlag(value: true, fromDecide: true, apiToken: testMixpanel.apiToken)
testMixpanel.automaticEvents.perform(#selector(AutomaticEvents.appWillResignActive(_:)),
with: Notification(name: Notification.Name(rawValue: "test")))
waitForTrackingQueue(testMixpanel)

View file

@ -66,6 +66,7 @@ class MixpanelDemoTests: MixpanelBaseTests {
testMixpanel.track(event: "event \(i)")
}
flushAndWaitForTrackingQueue(testMixpanel)
sleep(1)
XCTAssertTrue(eventQueue(token: testMixpanel.apiToken).isEmpty,
"events should have been flushed")
removeDBfile(testMixpanel.apiToken)
@ -80,11 +81,13 @@ class MixpanelDemoTests: MixpanelBaseTests {
testMixpanel.people.set(property: "p1", to: "\(i)")
}
flushAndWaitForTrackingQueue(testMixpanel)
sleep(1)
XCTAssertTrue(peopleQueue(token: testMixpanel.apiToken).isEmpty, "people should have been flushed")
for i in 0..<60 {
testMixpanel.people.set(property: "p1", to: "\(i)")
}
flushAndWaitForTrackingQueue(testMixpanel)
sleep(1)
XCTAssertTrue(peopleQueue(token: testMixpanel.apiToken).isEmpty, "people should have been flushed")
removeDBfile(testMixpanel.apiToken)
}
@ -99,11 +102,13 @@ class MixpanelDemoTests: MixpanelBaseTests {
testMixpanel.getGroup(groupKey: groupKey, groupID: groupValue).set(property: "p1", to: "\(i)")
}
flushAndWaitForTrackingQueue(testMixpanel)
sleep(1)
XCTAssertTrue(groupQueue(token: testMixpanel.apiToken).isEmpty, "groups should have been flushed")
for i in 0..<60 {
testMixpanel.getGroup(groupKey: groupKey, groupID: groupValue).set(property: "p1", to: "\(i)")
}
flushAndWaitForTrackingQueue(testMixpanel)
sleep(1)
XCTAssertTrue(peopleQueue(token: testMixpanel.apiToken).isEmpty, "groups should have been flushed")
removeDBfile(testMixpanel.apiToken)
}
@ -238,6 +243,7 @@ class MixpanelDemoTests: MixpanelBaseTests {
"incorrect project token in people record")
testMixpanel.identify(distinctId: distinctId)
waitForTrackingQueue(testMixpanel)
sleep(2)
let anonymousId = testMixpanel.anonymousId
peopleQueue_value = peopleQueue(token: testMixpanel.apiToken)
unidentifiedQueue = unIdentifiedPeopleQueue(token: testMixpanel.apiToken)
@ -289,11 +295,9 @@ class MixpanelDemoTests: MixpanelBaseTests {
let distinctIdBeforeIdentify: String? = testMixpanel.distinctId
let distinctId = "testIdentifyTrack"
testMixpanel.identify(distinctId: distinctId)
testMixpanel.identify(distinctId: distinctId)
waitForTrackingQueue(testMixpanel)
waitForTrackingQueue(testMixpanel)
sleep(1)
let e: InternalProperties = eventQueue(token: testMixpanel.apiToken).last!
XCTAssertEqual(e["event"] as? String, "$identify", "incorrect event name")
let p: InternalProperties = e["properties"] as! InternalProperties
@ -316,7 +320,7 @@ class MixpanelDemoTests: MixpanelBaseTests {
let newDistinctId = distinctId + String(i)
testMixpanel.identify(distinctId: newDistinctId)
waitForTrackingQueue(testMixpanel)
waitForTrackingQueue(testMixpanel)
sleep(1)
let e: InternalProperties = eventQueue(token: testMixpanel.apiToken).last!
XCTAssertEqual(e["event"] as? String, "$identify", "incorrect event name")
@ -340,21 +344,22 @@ class MixpanelDemoTests: MixpanelBaseTests {
let alias: String = "a1"
testMixpanel.identify(distinctId: distinctId)
waitForTrackingQueue(testMixpanel)
sleep(1)
testMixpanel.createAlias(alias, distinctId: testMixpanel.distinctId)
waitForTrackingQueue(testMixpanel)
var mixpanelIdentity = testMixpanel.mixpanelPersistence.loadIdentity()
var mixpanelIdentity = MixpanelPersistence.loadIdentity(apiToken: testMixpanel.apiToken)
XCTAssertTrue(distinctId == mixpanelIdentity.distinctID && distinctId == mixpanelIdentity.peopleDistinctID && distinctId == mixpanelIdentity.userId && alias == mixpanelIdentity.alias)
testMixpanel.archive()
waitForTrackingQueue(testMixpanel)
testMixpanel.unarchive()
waitForTrackingQueue(testMixpanel)
mixpanelIdentity = testMixpanel.mixpanelPersistence.loadIdentity()
XCTAssertTrue(testMixpanel.distinctId == mixpanelIdentity.distinctID && testMixpanel.people.distinctId == mixpanelIdentity.peopleDistinctID && testMixpanel.anonymousId == mixpanelIdentity.anoymousId &&
mixpanelIdentity = MixpanelPersistence.loadIdentity(apiToken: testMixpanel.apiToken)
XCTAssertTrue(testMixpanel.distinctId == mixpanelIdentity.distinctID && testMixpanel.people.distinctId == mixpanelIdentity.peopleDistinctID && testMixpanel.anonymousId == mixpanelIdentity.anonymousId &&
testMixpanel.userId == mixpanelIdentity.userId && testMixpanel.alias == mixpanelIdentity.alias)
testMixpanel.mixpanelPersistence.deleteMPUserDefaultsData()
MixpanelPersistence.deleteMPUserDefaultsData(apiToken: testMixpanel.apiToken)
waitForTrackingQueue(testMixpanel)
mixpanelIdentity = testMixpanel.mixpanelPersistence.loadIdentity()
XCTAssertTrue("" == mixpanelIdentity.distinctID && nil == mixpanelIdentity.peopleDistinctID && nil == mixpanelIdentity.anoymousId && nil == mixpanelIdentity.userId && nil == mixpanelIdentity.alias)
mixpanelIdentity = MixpanelPersistence.loadIdentity(apiToken: testMixpanel.apiToken)
XCTAssertTrue("" == mixpanelIdentity.distinctID && nil == mixpanelIdentity.peopleDistinctID && nil == mixpanelIdentity.anonymousId && nil == mixpanelIdentity.userId && nil == mixpanelIdentity.alias)
removeDBfile(testMixpanel.apiToken)
}
@ -374,6 +379,7 @@ class MixpanelDemoTests: MixpanelBaseTests {
let userId: String = "u1"
testMixpanel.identify(distinctId: userId)
waitForTrackingQueue(testMixpanel)
sleep(1)
XCTAssertEqual(testMixpanel.anonymousId, distinctId)
XCTAssertEqual(testMixpanel.userId, userId)
XCTAssertEqual(testMixpanel.distinctId, userId)
@ -591,6 +597,7 @@ class MixpanelDemoTests: MixpanelBaseTests {
let testMixpanel = Mixpanel.initialize(token: randomId(), flushInterval: 60)
testMixpanel.identify(distinctId: "d1")
testMixpanel.track(event: "e1")
sleep(1)
let p: Properties = ["p1": "a"]
testMixpanel.registerSuperProperties(p)
testMixpanel.people.set(properties: p)
@ -671,6 +678,7 @@ class MixpanelDemoTests: MixpanelBaseTests {
let p: Properties = ["p1": "a"]
testMixpanel.identify(distinctId: "d1")
waitForTrackingQueue(testMixpanel)
sleep(1)
testMixpanel.registerSuperProperties(p)
testMixpanel.track(event: "e1")
testMixpanel.track(event: "e2")
@ -739,6 +747,7 @@ class MixpanelDemoTests: MixpanelBaseTests {
testMixpanel.track(event: "e1")
testMixpanel.people.set(property: "p1", to: "a")
waitForTrackingQueue(testMixpanel)
sleep(1)
flushAndWaitForTrackingQueue(testMixpanel)
XCTAssertTrue(eventQueue(token: testMixpanel.apiToken).count == 2, "delegate should have stopped flush")
XCTAssertTrue(peopleQueue(token: testMixpanel.apiToken).count == 1, "delegate should have stopped flush")
@ -773,24 +782,20 @@ class MixpanelDemoTests: MixpanelBaseTests {
testMixpanel.time(event: "Time Event B")
testMixpanel.time(event: "Time Event C")
waitForTrackingQueue(testMixpanel)
var testTimedEvents = testMixpanel.mixpanelPersistence.loadTimedEvents()
var testTimedEvents = MixpanelPersistence.loadTimedEvents(apiToken: testMixpanel.apiToken)
XCTAssertTrue(testTimedEvents.count == 3, "Each call to time() should add an event to timedEvents")
XCTAssertNotNil(testTimedEvents["Time Event A"], "Keys in timedEvents should be event names")
testMixpanel.clearTimedEvent(event: "Time Event A")
waitForTrackingQueue(testMixpanel)
testTimedEvents = testMixpanel.mixpanelPersistence.loadTimedEvents()
testTimedEvents = MixpanelPersistence.loadTimedEvents(apiToken: testMixpanel.apiToken)
XCTAssertNil(testTimedEvents["Time Event A"], "clearTimedEvent should remove key/value pair")
XCTAssertTrue(testTimedEvents.count == 2, "clearTimedEvent shoud remove only one key/value pair")
testMixpanel.clearTimedEvents()
waitForTrackingQueue(testMixpanel)
XCTAssertTrue(testMixpanel.mixpanelPersistence.loadTimedEvents().count == 0, "clearTimedEvents should remove all key/value pairs")
XCTAssertTrue(MixpanelPersistence.loadTimedEvents(apiToken: testMixpanel.apiToken).count == 0, "clearTimedEvents should remove all key/value pairs")
removeDBfile(testMixpanel.apiToken)
}
func testTelephonyInfoInitialized() {
XCTAssertNotNil(MixpanelInstance.telephonyInfo, "telephonyInfo wasn't initialized")
}
func testReadWriteLock() {
var array = [Int]()
let lock = ReadWriteLock(label: "test")
@ -821,6 +826,7 @@ class MixpanelDemoTests: MixpanelBaseTests {
let groupValue = "test_value"
testMixpanel.setGroup(groupKey: groupKey, groupIDs: [groupValue])
waitForTrackingQueue(testMixpanel)
sleep(1)
XCTAssertEqual(testMixpanel.currentSuperProperties()[groupKey] as? [String], [groupValue])
let q = peopleQueue(token: testMixpanel.apiToken).last!["$set"] as! InternalProperties
XCTAssertEqual(q[groupKey] as? [String], [groupValue], "group value people property not queued")
@ -838,6 +844,7 @@ class MixpanelDemoTests: MixpanelBaseTests {
testMixpanel.addGroup(groupKey: groupKey, groupID: groupValue)
waitForTrackingQueue(testMixpanel)
sleep(1)
XCTAssertEqual(testMixpanel.currentSuperProperties()[groupKey] as? [String], [groupValue])
waitForTrackingQueue(testMixpanel)
let q = peopleQueue(token: testMixpanel.apiToken).last!["$set"] as! InternalProperties
@ -874,6 +881,7 @@ class MixpanelDemoTests: MixpanelBaseTests {
testMixpanel.setGroup(groupKey: groupKey, groupIDs: [groupValue, newVal])
waitForTrackingQueue(testMixpanel)
sleep(1)
XCTAssertEqual(testMixpanel.currentSuperProperties()[groupKey] as? [String], [groupValue, newVal])
testMixpanel.removeGroup(groupKey: groupKey, groupID: groupValue)
@ -896,7 +904,7 @@ class MixpanelDemoTests: MixpanelBaseTests {
func testReadWriteMultiThreadShouldNotCrash() {
let concurentQueue = DispatchQueue(label: "multithread", attributes: .concurrent)
let testMixpanel = Mixpanel.initialize(token: randomId(), flushInterval: 60)
for n in 1...10 {
concurentQueue.async {
testMixpanel.track(event: "event\(n)")

View file

@ -44,8 +44,10 @@ class MixpanelOptOutTests: MixpanelBaseTests {
testMixpanel.optInTracking(distinctId: "testDistinctId")
XCTAssertFalse(testMixpanel.hasOptedOutTracking(), "The current user should have opted in tracking")
waitForTrackingQueue(testMixpanel)
let event = eventQueue(token: testMixpanel.apiToken).first
XCTAssertEqual((event!["event"] as? String), "$opt_in", "When opted in, a track '$opt_in' should have been queued")
sleep(1)
let event1 = eventQueue(token: testMixpanel.apiToken).first
let event2 = eventQueue(token: testMixpanel.apiToken).last
XCTAssertTrue((event1!["event"] as? String) == "$opt_in" || (event2!["event"] as? String) == "$opt_in", "When opted in, a track '$opt_in' should have been queued")
XCTAssertEqual(testMixpanel.distinctId, "testDistinctId", "mixpanel identify failed to set distinct id")
XCTAssertEqual(testMixpanel.people.distinctId, "testDistinctId", "mixpanel identify failed to set people distinct id")
XCTAssertTrue(unIdentifiedPeopleQueue(token: testMixpanel.apiToken).count == 0, "identify: should move records from unidentified queue")
@ -62,6 +64,7 @@ class MixpanelOptOutTests: MixpanelBaseTests {
let testMixpanel = Mixpanel.initialize(token: randomId(), optOutTrackingByDefault: true)
testMixpanel.optInTracking(distinctId: "testDistinctId", properties: testProperties)
waitForTrackingQueue(testMixpanel)
sleep(1)
let eventQueueValue = eventQueue(token: testMixpanel.apiToken)
let props = eventQueueValue.first!["properties"] as? InternalProperties

View file

@ -17,9 +17,11 @@ class MixpanelPeopleTests: MixpanelBaseTests {
func testPeopleSet() {
let testMixpanel = Mixpanel.initialize(token: randomId(), flushInterval: 60)
testMixpanel.identify(distinctId: "d1")
waitForTrackingQueue(testMixpanel)
let p: Properties = ["p1": "a"]
testMixpanel.people.set(properties: p)
waitForTrackingQueue(testMixpanel)
sleep(1)
let q = peopleQueue(token: testMixpanel.apiToken).last!["$set"] as! InternalProperties
XCTAssertEqual(q["p1"] as? String, "a", "custom people property not queued")
assertDefaultPeopleProperties(q)
@ -32,6 +34,7 @@ class MixpanelPeopleTests: MixpanelBaseTests {
let p: Properties = ["p1": "a"]
testMixpanel.people.setOnce(properties: p)
waitForTrackingQueue(testMixpanel)
sleep(1)
let q = peopleQueue(token: testMixpanel.apiToken).last!["$set_once"] as! InternalProperties
XCTAssertEqual(q["p1"] as? String, "a", "custom people property not queued")
assertDefaultPeopleProperties(q)
@ -44,6 +47,7 @@ class MixpanelPeopleTests: MixpanelBaseTests {
let p: Properties = ["$ios_app_version": "override"]
testMixpanel.people.set(properties: p)
waitForTrackingQueue(testMixpanel)
sleep(1)
let q = peopleQueue(token: testMixpanel.apiToken).last!["$set"] as! InternalProperties
XCTAssertEqual(q["$ios_app_version"] as? String,
"override",
@ -57,6 +61,7 @@ class MixpanelPeopleTests: MixpanelBaseTests {
testMixpanel.identify(distinctId: "d1")
testMixpanel.people.set(property: "p1", to: "a")
waitForTrackingQueue(testMixpanel)
sleep(1)
let p: InternalProperties = peopleQueue(token: testMixpanel.apiToken).last!["$set"] as! InternalProperties
XCTAssertEqual(p["p1"] as? String, "a", "custom people property not queued")
assertDefaultPeopleProperties(p)
@ -69,6 +74,7 @@ class MixpanelPeopleTests: MixpanelBaseTests {
testMixpanel.people.set(property: "i", to: i)
}
waitForTrackingQueue(testMixpanel)
sleep(1)
XCTAssertTrue(unIdentifiedPeopleQueue(token: testMixpanel.apiToken).count == 505)
var r: InternalProperties = unIdentifiedPeopleQueue(token: testMixpanel.apiToken).first!
XCTAssertEqual((r["$set"] as? InternalProperties)?["i"] as? Int, 0)
@ -101,6 +107,7 @@ class MixpanelPeopleTests: MixpanelBaseTests {
let p: Properties = ["p1": 3]
testMixpanel.people.increment(properties: p)
waitForTrackingQueue(testMixpanel)
sleep(1)
let q = peopleQueue(token: testMixpanel.apiToken).last!["$add"] as! InternalProperties
XCTAssertTrue(q.count == 1, "incorrect people properties: \(p)")
XCTAssertEqual(q["p1"] as? Int, 3, "custom people property not queued")
@ -112,6 +119,7 @@ class MixpanelPeopleTests: MixpanelBaseTests {
testMixpanel.identify(distinctId: "d1")
testMixpanel.people.increment(property: "p1", by: 3)
waitForTrackingQueue(testMixpanel)
sleep(1)
let p: InternalProperties = peopleQueue(token: testMixpanel.apiToken).last!["$add"] as! InternalProperties
XCTAssertTrue(p.count == 1, "incorrect people properties: \(p)")
XCTAssertEqual(p["p1"] as? Double, 3, "custom people property not queued")
@ -123,6 +131,7 @@ class MixpanelPeopleTests: MixpanelBaseTests {
testMixpanel.identify(distinctId: "d1")
testMixpanel.people.deleteUser()
waitForTrackingQueue(testMixpanel)
sleep(1)
let p: InternalProperties = peopleQueue(token: testMixpanel.apiToken).last!["$delete"] as! InternalProperties
XCTAssertTrue(p.isEmpty, "incorrect people properties: \(p)")
removeDBfile(testMixpanel.apiToken)
@ -134,6 +143,7 @@ class MixpanelPeopleTests: MixpanelBaseTests {
testMixpanel.identify(distinctId: "d1")
testMixpanel.people.trackCharge(amount: 25.34)
waitForTrackingQueue(testMixpanel)
sleep(1)
let r: InternalProperties = peopleQueue(token: testMixpanel.apiToken).last!
let prop = ((r["$append"] as? InternalProperties)?["$transactions"] as? InternalProperties)?["$amount"] as? Double
let prop2 = ((r["$append"] as? InternalProperties)?["$transactions"] as? InternalProperties)?["$time"]
@ -145,8 +155,10 @@ class MixpanelPeopleTests: MixpanelBaseTests {
func testPeopleTrackChargeZero() {
let testMixpanel = Mixpanel.initialize(token: randomId(), flushInterval: 60)
testMixpanel.identify(distinctId: "d1")
waitForTrackingQueue(testMixpanel)
testMixpanel.people.trackCharge(amount: 0)
waitForTrackingQueue(testMixpanel)
sleep(1)
let r: InternalProperties = peopleQueue(token: testMixpanel.apiToken).last!
let prop = ((r["$append"] as? InternalProperties)?["$transactions"] as? InternalProperties)?["$amount"] as? Double
let prop2 = ((r["$append"] as? InternalProperties)?["$transactions"] as? InternalProperties)?["$time"]
@ -161,6 +173,7 @@ class MixpanelPeopleTests: MixpanelBaseTests {
let p: Properties = allPropertyTypes()
testMixpanel.people.trackCharge(amount: 25, properties: ["$time": p["date"]!])
waitForTrackingQueue(testMixpanel)
sleep(1)
let r: InternalProperties = peopleQueue(token: testMixpanel.apiToken).last!
let prop = ((r["$append"] as? InternalProperties)?["$transactions"] as? InternalProperties)?["$amount"] as? Double
let prop2 = ((r["$append"] as? InternalProperties)?["$transactions"] as? InternalProperties)?["$time"] as? String
@ -174,6 +187,7 @@ class MixpanelPeopleTests: MixpanelBaseTests {
testMixpanel.identify(distinctId: "d1")
testMixpanel.people.trackCharge(amount: 25, properties: ["p1": "a"])
waitForTrackingQueue(testMixpanel)
sleep(1)
let r: InternalProperties = peopleQueue(token: testMixpanel.apiToken).last!
let prop = ((r["$append"] as? InternalProperties)?["$transactions"] as? InternalProperties)?["$amount"] as? Double
let prop2 = ((r["$append"] as? InternalProperties)?["$transactions"] as? InternalProperties)?["p1"]
@ -187,6 +201,7 @@ class MixpanelPeopleTests: MixpanelBaseTests {
testMixpanel.identify(distinctId: "d1")
testMixpanel.people.trackCharge(amount: 25)
waitForTrackingQueue(testMixpanel)
sleep(1)
let r: InternalProperties = peopleQueue(token: testMixpanel.apiToken).last!
let prop = ((r["$append"] as? InternalProperties)?["$transactions"] as? InternalProperties)?["$amount"] as? Double
let prop2 = ((r["$append"] as? InternalProperties)?["$transactions"] as? InternalProperties)?["$time"]
@ -200,6 +215,7 @@ class MixpanelPeopleTests: MixpanelBaseTests {
testMixpanel.identify(distinctId: "d1")
testMixpanel.people.clearCharges()
waitForTrackingQueue(testMixpanel)
sleep(1)
let r: InternalProperties = peopleQueue(token: testMixpanel.apiToken).last!
let transactions = (r["$set"] as? InternalProperties)?["$transactions"] as? [MixpanelType]
XCTAssertEqual(transactions?.count, 0)

View file

@ -21,10 +21,13 @@ class Decide {
let decideRequest: DecideRequest
let lock: ReadWriteLock
var decideFetched = false
let mixpanelPersistence: MixpanelPersistence
required init(basePathIdentifier: String, lock: ReadWriteLock) {
required init(basePathIdentifier: String, lock: ReadWriteLock, mixpanelPersistence: MixpanelPersistence) {
self.decideRequest = DecideRequest(basePathIdentifier: basePathIdentifier)
self.lock = lock
self.mixpanelPersistence = mixpanelPersistence
}
func checkDecide(forceFetch: Bool = false,
@ -46,7 +49,7 @@ class Decide {
}
if let automaticEventsEnabled = result["automatic_events"] as? Bool {
MixpanelPersistence.init(token: token).saveAutomacticEventsEnabledFlag(value: automaticEventsEnabled, fromDecide: true)
MixpanelPersistence.saveAutomacticEventsEnabledFlag(value: automaticEventsEnabled, fromDecide: true, apiToken: token)
}
if let integrations = result["integrations"] as? [String] {

View file

@ -217,7 +217,9 @@ class MPDB {
logSqlError(message: "No blob found in data column for row in \(tableName)")
}
}
Logger.info(message: "Successfully read \(rowsRead) from table \(tableName)")
if rowsRead > 0 {
Logger.info(message: "Successfully read \(rowsRead) from table \(tableName)")
}
} else {
logSqlError(message: "SELECT statement for table \(tableName) could not be prepared")
}

View file

@ -84,7 +84,7 @@ open class MixpanelInstance: CustomDebugStringConvertible, FlushDelegate, AEDele
/// If this is not set, it will query the Autotrack settings from the Mixpanel server
open var trackAutomaticEventsEnabled: Bool? {
didSet {
self.mixpanelPersistence.saveAutomacticEventsEnabledFlag(value: trackAutomaticEventsEnabled ?? false, fromDecide: false)
MixpanelPersistence.saveAutomacticEventsEnabledFlag(value: trackAutomaticEventsEnabled ?? false, fromDecide: false, apiToken: apiToken)
}
}
@ -220,10 +220,10 @@ open class MixpanelInstance: CustomDebugStringConvertible, FlushDelegate, AEDele
mixpanelPersistence.migrate()
self.name = name
self.readWriteLock = ReadWriteLock(label: "com.mixpanel.globallock")
readWriteLock = ReadWriteLock(label: "com.mixpanel.globallock")
flushInstance = Flush(basePathIdentifier: name)
#if DECIDE
decideInstance = Decide(basePathIdentifier: name, lock: self.readWriteLock)
decideInstance = Decide(basePathIdentifier: name, lock: readWriteLock, mixpanelPersistence: mixpanelPersistence)
#endif // DECIDE
let label = "com.mixpanel.\(self.apiToken)"
trackingQueue = DispatchQueue(label: "\(label).tracking)", qos: .utility)
@ -647,13 +647,13 @@ extension MixpanelInstance {
self.people.distinctId = nil
}
self.mixpanelPersistence.saveIdentity(MixpanelIdentity.init(
MixpanelPersistence.saveIdentity(MixpanelIdentity.init(
distinctID: self.distinctId,
peopleDistinctID: self.people.distinctId,
anoymousId: self.anonymousId,
anonymousId: self.anonymousId,
userId: self.userId,
alias: self.alias,
hadPersistedDistinctId: self.hadPersistedDistinctId))
hadPersistedDistinctId: self.hadPersistedDistinctId), apiToken: self.apiToken)
}
if MixpanelInstance.isiOSAppExtension() {
@ -699,13 +699,13 @@ extension MixpanelInstance {
}
self.alias = alias
self.mixpanelPersistence.saveIdentity(MixpanelIdentity.init(
MixpanelPersistence.saveIdentity(MixpanelIdentity.init(
distinctID: self.distinctId,
peopleDistinctID: self.people.distinctId,
anoymousId: self.anonymousId,
anonymousId: self.anonymousId,
userId: self.userId,
alias: self.alias,
hadPersistedDistinctId: self.hadPersistedDistinctId))
hadPersistedDistinctId: self.hadPersistedDistinctId), apiToken: self.apiToken)
}
let properties = ["distinct_id": distinctId, "alias": alias]
@ -729,7 +729,7 @@ extension MixpanelInstance {
return
}
self.mixpanelPersistence.deleteMPUserDefaultsData()
MixpanelPersistence.deleteMPUserDefaultsData(apiToken: self.apiToken)
self.timedEvents = InternalProperties()
self.distinctId = self.defaultDistinctId()
self.anonymousId = self.distinctId
@ -755,32 +755,38 @@ extension MixpanelInstance {
open func archive() {
self.readWriteLock.read {
self.mixpanelPersistence.saveTimedEvents(timedEvents: timedEvents)
self.mixpanelPersistence.saveSuperProperties(superProperties: superProperties)
self.mixpanelPersistence.saveIdentity(MixpanelIdentity.init(
MixpanelPersistence.saveTimedEvents(timedEvents: timedEvents, apiToken: apiToken)
MixpanelPersistence.saveSuperProperties(superProperties: superProperties, apiToken: apiToken)
MixpanelPersistence.saveIdentity(MixpanelIdentity.init(
distinctID: distinctId,
peopleDistinctID: people.distinctId,
anoymousId: anonymousId,
anonymousId: anonymousId,
userId: userId,
alias: alias,
hadPersistedDistinctId: hadPersistedDistinctId))
hadPersistedDistinctId: hadPersistedDistinctId), apiToken: apiToken)
}
}
func unarchive() {
optOutStatus = self.mixpanelPersistence.loadOptOutStatusFlag()
superProperties = self.mixpanelPersistence.loadSuperProperties()
timedEvents = self.mixpanelPersistence.loadTimedEvents()
let mixpanelIdentity = self.mixpanelPersistence.loadIdentity()
optOutStatus = MixpanelPersistence.loadOptOutStatusFlag(apiToken: apiToken)
superProperties = MixpanelPersistence.loadSuperProperties(apiToken: apiToken)
timedEvents = MixpanelPersistence.loadTimedEvents(apiToken: apiToken)
let mixpanelIdentity = MixpanelPersistence.loadIdentity(apiToken: apiToken)
(distinctId, people.distinctId, anonymousId, userId, alias, hadPersistedDistinctId) = (
mixpanelIdentity.distinctID,
mixpanelIdentity.peopleDistinctID,
mixpanelIdentity.anoymousId,
mixpanelIdentity.anonymousId,
mixpanelIdentity.userId,
mixpanelIdentity.alias,
mixpanelIdentity.hadPersistedDistinctId
)
if distinctId == "" {
distinctId = defaultDistinctId()
anonymousId = distinctId
hadPersistedDistinctId = nil
userId = nil
}
}
func trackIntegration() {
@ -1017,7 +1023,7 @@ extension MixpanelInstance {
self.readWriteLock.write {
self.timedEvents = timedEvents
}
self.mixpanelPersistence.saveTimedEvents(timedEvents: timedEvents)
MixpanelPersistence.saveTimedEvents(timedEvents: timedEvents, apiToken: self.apiToken)
}
}
@ -1042,7 +1048,7 @@ extension MixpanelInstance {
self.readWriteLock.write {
self.timedEvents = InternalProperties()
}
self.mixpanelPersistence.saveTimedEvents(timedEvents: InternalProperties())
MixpanelPersistence.saveTimedEvents(timedEvents: InternalProperties(), apiToken: self.apiToken)
}
}
@ -1057,7 +1063,7 @@ extension MixpanelInstance {
guard let self = self else { return }
let updatedTimedEvents = self.trackInstance.clearTimedEvent(event: event, timedEvents: self.timedEvents)
self.mixpanelPersistence.saveTimedEvents(timedEvents: updatedTimedEvents)
MixpanelPersistence.saveTimedEvents(timedEvents: updatedTimedEvents, apiToken: self.apiToken)
}
}
@ -1081,7 +1087,7 @@ extension MixpanelInstance {
self.readWriteLock.write {
self.superProperties = self.trackInstance.clearSuperProperties(self.superProperties)
}
self.mixpanelPersistence.saveSuperProperties(superProperties: self.superProperties)
MixpanelPersistence.saveSuperProperties(superProperties: self.superProperties, apiToken: self.apiToken)
}
/**
@ -1100,7 +1106,7 @@ extension MixpanelInstance {
self.superProperties = self.trackInstance.registerSuperProperties(properties,
superProperties: self.superProperties)
}
self.mixpanelPersistence.saveSuperProperties(superProperties: self.superProperties)
MixpanelPersistence.saveSuperProperties(superProperties: self.superProperties, apiToken: apiToken)
}
/**
@ -1120,7 +1126,7 @@ extension MixpanelInstance {
superProperties: self.superProperties,
defaultValue: defaultValue)
}
self.mixpanelPersistence.saveSuperProperties(superProperties: self.superProperties)
MixpanelPersistence.saveSuperProperties(superProperties: self.superProperties, apiToken: apiToken)
}
/**
@ -1141,7 +1147,7 @@ extension MixpanelInstance {
self.superProperties = self.trackInstance.unregisterSuperProperty(propertyName,
superProperties: self.superProperties)
}
self.mixpanelPersistence.saveSuperProperties(superProperties: self.superProperties)
MixpanelPersistence.saveSuperProperties(superProperties: self.superProperties, apiToken: apiToken)
}
/**
@ -1159,7 +1165,7 @@ extension MixpanelInstance {
self.readWriteLock.write {
self.superProperties = superPropertiesShadow
}
self.mixpanelPersistence.saveSuperProperties(superProperties: self.superProperties)
MixpanelPersistence.saveSuperProperties(superProperties: self.superProperties, apiToken: apiToken)
}
/**
@ -1285,13 +1291,13 @@ extension MixpanelInstance {
self.anonymousId = self.distinctId
self.hadPersistedDistinctId = nil
self.superProperties = InternalProperties()
self.mixpanelPersistence.saveTimedEvents(timedEvents: InternalProperties())
MixpanelPersistence.saveTimedEvents(timedEvents: InternalProperties(), apiToken: self.apiToken)
}
self.archive()
}
optOutStatus = true
self.mixpanelPersistence.saveOptOutStatusFlag(value: optOutStatus!)
MixpanelPersistence.saveOptOutStatusFlag(value: optOutStatus!, apiToken: apiToken)
}
/**
@ -1307,7 +1313,7 @@ extension MixpanelInstance {
*/
open func optInTracking(distinctId: String? = nil, properties: Properties? = nil) {
optOutStatus = false
self.mixpanelPersistence.saveOptOutStatusFlag(value: optOutStatus!)
MixpanelPersistence.saveOptOutStatusFlag(value: optOutStatus!, apiToken: apiToken)
if let distinctId = distinctId {
identify(distinctId: distinctId)

View file

@ -29,7 +29,7 @@ struct PersistenceConstant {
struct MixpanelIdentity {
let distinctID: String
let peopleDistinctID: String?
let anoymousId: String?
let anonymousId: String?
let userId: String?
let alias: String?
let hadPersistedDistinctId: Bool?
@ -91,7 +91,7 @@ class MixpanelPersistence {
}
}
func saveOptOutStatusFlag(value: Bool) {
static func saveOptOutStatusFlag(value: Bool, apiToken: String) {
guard let defaults = UserDefaults(suiteName: MixpanelUserDefaultsKeys.suiteName) else {
return
}
@ -100,7 +100,7 @@ class MixpanelPersistence {
defaults.synchronize()
}
func loadOptOutStatusFlag() -> Bool? {
static func loadOptOutStatusFlag(apiToken: String) -> Bool? {
guard let defaults = UserDefaults(suiteName: MixpanelUserDefaultsKeys.suiteName) else {
return nil
}
@ -109,7 +109,7 @@ class MixpanelPersistence {
}
func saveAutomacticEventsEnabledFlag(value: Bool, fromDecide: Bool) {
static func saveAutomacticEventsEnabledFlag(value: Bool, fromDecide: Bool, apiToken: String) {
guard let defaults = UserDefaults(suiteName: MixpanelUserDefaultsKeys.suiteName) else {
return
}
@ -122,7 +122,7 @@ class MixpanelPersistence {
defaults.synchronize()
}
func loadAutomacticEventsEnabledFlag() -> Bool {
static func loadAutomacticEventsEnabledFlag(apiToken: String) -> Bool {
#if TV_AUTO_EVENTS
return true
#else
@ -141,7 +141,7 @@ class MixpanelPersistence {
#endif
}
func saveTimedEvents(timedEvents: InternalProperties) {
static func saveTimedEvents(timedEvents: InternalProperties, apiToken: String) {
guard let defaults = UserDefaults(suiteName: MixpanelUserDefaultsKeys.suiteName) else {
return
}
@ -151,7 +151,7 @@ class MixpanelPersistence {
defaults.synchronize()
}
func loadTimedEvents() -> InternalProperties {
static func loadTimedEvents(apiToken: String) -> InternalProperties {
guard let defaults = UserDefaults(suiteName: MixpanelUserDefaultsKeys.suiteName) else {
return InternalProperties()
}
@ -162,7 +162,7 @@ class MixpanelPersistence {
return NSKeyedUnarchiver.unarchiveObject(with: timedEventsData) as? InternalProperties ?? InternalProperties()
}
func saveSuperProperties(superProperties: InternalProperties) {
static func saveSuperProperties(superProperties: InternalProperties, apiToken: String) {
guard let defaults = UserDefaults(suiteName: MixpanelUserDefaultsKeys.suiteName) else {
return
}
@ -172,7 +172,7 @@ class MixpanelPersistence {
defaults.synchronize()
}
func loadSuperProperties() -> InternalProperties {
static func loadSuperProperties(apiToken: String) -> InternalProperties {
guard let defaults = UserDefaults(suiteName: MixpanelUserDefaultsKeys.suiteName) else {
return InternalProperties()
}
@ -183,35 +183,35 @@ class MixpanelPersistence {
return NSKeyedUnarchiver.unarchiveObject(with: superPropertiesData) as? InternalProperties ?? InternalProperties()
}
func saveIdentity(_ mixpanelIdentity: MixpanelIdentity) {
static func saveIdentity(_ mixpanelIdentity: MixpanelIdentity, apiToken: String) {
guard let defaults = UserDefaults(suiteName: MixpanelUserDefaultsKeys.suiteName) else {
return
}
let prefix = "\(MixpanelUserDefaultsKeys.prefix)-\(apiToken)-"
defaults.set(mixpanelIdentity.distinctID, forKey: "\(prefix)\(MixpanelUserDefaultsKeys.distinctID)")
defaults.set(mixpanelIdentity.peopleDistinctID, forKey: "\(prefix)\(MixpanelUserDefaultsKeys.peopleDistinctID)")
defaults.set(mixpanelIdentity.anoymousId, forKey: "\(prefix)\(MixpanelUserDefaultsKeys.anonymousId)")
defaults.set(mixpanelIdentity.anonymousId, forKey: "\(prefix)\(MixpanelUserDefaultsKeys.anonymousId)")
defaults.set(mixpanelIdentity.userId, forKey: "\(prefix)\(MixpanelUserDefaultsKeys.userID)")
defaults.set(mixpanelIdentity.alias, forKey: "\(prefix)\(MixpanelUserDefaultsKeys.alias)")
defaults.set(mixpanelIdentity.hadPersistedDistinctId, forKey: "\(prefix)\(MixpanelUserDefaultsKeys.hadPersistedDistinctId)")
defaults.synchronize()
}
func loadIdentity() -> MixpanelIdentity {
static func loadIdentity(apiToken: String) -> MixpanelIdentity {
guard let defaults = UserDefaults(suiteName: MixpanelUserDefaultsKeys.suiteName) else {
return MixpanelIdentity.init(distinctID: "", peopleDistinctID: nil, anoymousId: nil, userId: nil, alias: nil, hadPersistedDistinctId: nil)
return MixpanelIdentity.init(distinctID: "", peopleDistinctID: nil, anonymousId: nil, userId: nil, alias: nil, hadPersistedDistinctId: nil)
}
let prefix = "\(MixpanelUserDefaultsKeys.prefix)-\(apiToken)-"
return MixpanelIdentity.init(
distinctID: defaults.string(forKey: "\(prefix)\(MixpanelUserDefaultsKeys.distinctID)") ?? "",
peopleDistinctID: defaults.string(forKey: "\(prefix)\(MixpanelUserDefaultsKeys.peopleDistinctID)"),
anoymousId: defaults.string(forKey: "\(prefix)\(MixpanelUserDefaultsKeys.anonymousId)"),
anonymousId: defaults.string(forKey: "\(prefix)\(MixpanelUserDefaultsKeys.anonymousId)"),
userId: defaults.string(forKey: "\(prefix)\(MixpanelUserDefaultsKeys.userID)"),
alias: defaults.string(forKey: "\(prefix)\(MixpanelUserDefaultsKeys.alias)"),
hadPersistedDistinctId: defaults.bool(forKey: "\(prefix)\(MixpanelUserDefaultsKeys.hadPersistedDistinctId)"))
}
func deleteMPUserDefaultsData() {
static func deleteMPUserDefaultsData(apiToken: String) {
guard let defaults = UserDefaults(suiteName: MixpanelUserDefaultsKeys.suiteName) else {
return
}
@ -232,6 +232,9 @@ class MixpanelPersistence {
// code for unarchiving from legacy archive files and migrating to SQLite / NSUserDefaults persistence
func migrate() {
if !needMigration() {
return
}
let (eventsQueue,
peopleQueue,
groupsQueue,
@ -246,27 +249,24 @@ class MixpanelPersistence {
peopleUnidentifiedQueue,
optOutStatus,
automaticEventsEnabled) = unarchive()
if !needMigration() {
return
}
saveEntities(eventsQueue, type: PersistenceType.events)
saveEntities(peopleUnidentifiedQueue, type: PersistenceType.people, flag: PersistenceConstant.unIdentifiedFlag)
saveEntities(peopleQueue, type: PersistenceType.people)
saveEntities(groupsQueue, type: PersistenceType.groups)
saveSuperProperties(superProperties: superProperties)
saveTimedEvents(timedEvents: timedEvents)
saveIdentity(MixpanelIdentity.init(
MixpanelPersistence.saveSuperProperties(superProperties: superProperties, apiToken: apiToken)
MixpanelPersistence.saveTimedEvents(timedEvents: timedEvents, apiToken: apiToken)
MixpanelPersistence.saveIdentity(MixpanelIdentity.init(
distinctID: distinctId,
peopleDistinctID: peopleDistinctId,
anoymousId: anonymousId,
anonymousId: anonymousId,
userId: userId,
alias: alias,
hadPersistedDistinctId: hadPersistedDistinctId))
hadPersistedDistinctId: hadPersistedDistinctId), apiToken: apiToken)
if let optOutFlag = optOutStatus {
saveOptOutStatusFlag(value: optOutFlag)
MixpanelPersistence.saveOptOutStatusFlag(value: optOutFlag, apiToken: apiToken)
}
if let automaticEventsFlag = automaticEventsEnabled {
saveAutomacticEventsEnabledFlag(value: automaticEventsFlag, fromDecide: false) // should fromDecide = false here?
MixpanelPersistence.saveAutomacticEventsEnabledFlag(value: automaticEventsFlag, fromDecide: false, apiToken: apiToken) // should fromDecide = false here?
}
return
}

View file

@ -21,7 +21,7 @@ class Track {
let mixpanelPersistence: MixpanelPersistence
var isAutomaticEventEnabled: Bool {
return MixpanelPersistence.init(token: apiToken).loadAutomacticEventsEnabledFlag()
return MixpanelPersistence.loadAutomacticEventsEnabledFlag(apiToken: apiToken)
}
init(apiToken: String, lock: ReadWriteLock, metadata: SessionMetadata, mixpanelPersistence: MixpanelPersistence) {
@ -83,7 +83,7 @@ class Track {
metadata.toDict().forEach { (k, v) in trackEvent[k] = v }
self.mixpanelPersistence.saveEntity(trackEvent, type: .events)
self.mixpanelPersistence.saveTimedEvents(timedEvents: shadowTimedEvents)
MixpanelPersistence.saveTimedEvents(timedEvents: shadowTimedEvents, apiToken: apiToken)
return shadowTimedEvents
}