diff --git a/Mixpanel/MixpanelInstance.swift b/Mixpanel/MixpanelInstance.swift
index b30afc696..8c9f0e76e 100644
--- a/Mixpanel/MixpanelInstance.swift
+++ b/Mixpanel/MixpanelInstance.swift
@@ -605,55 +605,25 @@ open class MixpanelInstance: CustomDebugStringConvertible, FlushDelegate, AEDele
}
func defaultDistinctId() -> String {
- #if MIXPANEL_RANDOM_DISTINCT_ID
- let distinctId: String? = UUID().uuidString
- #elseif !os(OSX) && !WATCH_OS
- var distinctId: String? = IFA()
- if distinctId == nil && NSClassFromString("UIDevice") != nil {
+ #if MIXPANEL_UNIQUE_DISTINCT_ID
+ #if !os(OSX) && !WATCH_OS
+ var distinctId: String? = nil
+ if NSClassFromString("UIDevice") != nil {
distinctId = UIDevice.current.identifierForVendor?.uuidString
}
#elseif os(OSX)
let distinctId = MixpanelInstance.macOSIdentifier()
- #else
- let distinctId: String? = nil
- #endif // os(OSX)
+ #endif
+ #else // use a random UUID by default
+ let distinctId: String? = UUID().uuidString
+ #endif
guard let distId = distinctId else {
return UUID().uuidString
}
return distId
}
- #if !os(OSX) && !WATCH_OS
- func IFA() -> String? {
- var ifa: String? = nil
- #if !MIXPANEL_NO_IFA
- if let ASIdentifierManagerClass = NSClassFromString("ASIdentifierManager") {
- let sharedManagerSelector = NSSelectorFromString("sharedManager")
- if let sharedManagerIMP = ASIdentifierManagerClass.method(for: sharedManagerSelector) {
- typealias sharedManagerFunc = @convention(c) (AnyObject, Selector) -> AnyObject?
- let curriedImplementation = unsafeBitCast(sharedManagerIMP, to: sharedManagerFunc.self)
- if let sharedManager = curriedImplementation(ASIdentifierManagerClass.self, sharedManagerSelector) {
- let advertisingTrackingEnabledSelector = NSSelectorFromString("isAdvertisingTrackingEnabled")
- if let isTrackingEnabledIMP = sharedManager.method(for: advertisingTrackingEnabledSelector) {
- typealias isTrackingEnabledFunc = @convention(c) (AnyObject, Selector) -> Bool
- let curriedImplementation2 = unsafeBitCast(isTrackingEnabledIMP, to: isTrackingEnabledFunc.self)
- let isTrackingEnabled = curriedImplementation2(self, advertisingTrackingEnabledSelector)
- if isTrackingEnabled {
- let advertisingIdentifierSelector = NSSelectorFromString("advertisingIdentifier")
- if let advertisingIdentifierIMP = sharedManager.method(for: advertisingIdentifierSelector) {
- typealias adIdentifierFunc = @convention(c) (AnyObject, Selector) -> NSUUID
- let curriedImplementation3 = unsafeBitCast(advertisingIdentifierIMP, to: adIdentifierFunc.self)
- ifa = curriedImplementation3(self, advertisingIdentifierSelector).uuidString
- }
- }
- }
- }
- }
- }
- #endif
- return ifa
- }
- #elseif os(OSX)
+ #if os(OSX)
static func macOSIdentifier() -> String? {
let platformExpert: io_service_t = IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching("IOPlatformExpertDevice"));
let serialNumberAsCFString = IORegistryEntryCreateCFProperty(platformExpert, kIOPlatformSerialNumberKey as CFString, kCFAllocatorDefault, 0);
@@ -755,26 +725,14 @@ extension MixpanelInstance {
/**
Sets the distinct ID of the current user.
- Mixpanel will choose a default local distinct ID based on whether you are using the
- AdSupport.framework or not.
-
- If you are not using the AdSupport Framework (iAds), then we use the IFV String
- (`UIDevice.current().identifierForVendor`) as the default local distinct ID. This ID will
- identify a user across all apps by the same vendor, but cannot be used to link the same
- user across apps from different vendors. If we are unable to get the IFV, we will fall
- back to generating a random persistent UUID
-
- If you are showing iAds in your application, you are allowed use the iOS ID
- for Advertising (IFA) to identify users. If you have this framework in your
- app, Mixpanel will use the IFA as the default local distinct ID. If you have
- AdSupport installed but still don't want to use the IFA, you can define the
- MIXPANEL_NO_IFA flag in your Active Compilation Conditions
- build settings, and Mixpanel will use the IFV as the default local distinct ID.
-
- If we are unable to get an IFA or IFV, we will fall back to generating a
- random persistent UUID. If you want to always use a random persistent UUID
- you can define the MIXPANEL_RANDOM_DISTINCT_ID preprocessor flag
- in your build settings.
+ Mixpanel uses a randomly generated persistent UUID as the default local distinct ID.
+
+ If you want to use a unique persistent UUID, you can define the
+ MIXPANEL_UNIQUE_DISTINCT_ID flag in your Active Compilation Conditions
+ build settings. It then uses the IFV String (`UIDevice.current().identifierForVendor`) as
+ the default local distinct ID. This ID will identify a user across all apps by the same vendor, but cannot be
+ used to link the same user across apps from different vendors. If we are unable to get an IFV, we will fall
+ back to generating a random persistent UUID.
For tracking events, you do not need to call `identify:`. However,
**Mixpanel User profiles always requires an explicit call to `identify:`.**
diff --git a/MixpanelDemo/MixpanelDemoTests/MixpanelDemoTests.swift b/MixpanelDemo/MixpanelDemoTests/MixpanelDemoTests.swift
index ac018a351..6999f529a 100644
--- a/MixpanelDemo/MixpanelDemoTests/MixpanelDemoTests.swift
+++ b/MixpanelDemo/MixpanelDemoTests/MixpanelDemoTests.swift
@@ -168,12 +168,14 @@ class MixpanelDemoTests: MixpanelBaseTests {
// run this twice to test reset works correctly wrt to distinct ids
let distinctId: String = "d1"
// try this for ODIN and nil
+ #if MIXPANEL_UNIQUE_DISTINCT_ID
XCTAssertEqual(mixpanel.distinctId,
mixpanel.defaultDistinctId(),
"mixpanel identify failed to set default distinct id")
XCTAssertEqual(mixpanel.anonymousId,
mixpanel.defaultDistinctId(),
"mixpanel failed to set default anonymous id")
+ #endif
XCTAssertNil(mixpanel.people.distinctId,
"mixpanel people distinct id should default to nil")
XCTAssertNil(mixpanel.people.distinctId,
@@ -182,9 +184,11 @@ class MixpanelDemoTests: MixpanelBaseTests {
waitForTrackingQueue()
XCTAssertTrue(mixpanel.eventsQueue.count == 1,
"events should be sent right away with default distinct id")
+ #if MIXPANEL_UNIQUE_DISTINCT_ID
XCTAssertEqual((mixpanel.eventsQueue.last?["properties"] as? InternalProperties)?["distinct_id"] as? String,
mixpanel.defaultDistinctId(),
"events should use default distinct id if none set")
+ #endif
XCTAssertEqual((mixpanel.eventsQueue.last?["properties"] as? InternalProperties)?["$lib_version"] as? String,
AutomaticProperties.libVersion(),
"events should has lib version in internal properties")
@@ -275,10 +279,9 @@ class MixpanelDemoTests: MixpanelBaseTests {
let p: InternalProperties = e["properties"] as! InternalProperties
XCTAssertEqual(p["distinct_id"] as? String, newDistinctId, "wrong distinct_id")
XCTAssertEqual(p["$anon_distinct_id"] as? String, prevDistinctId, "wrong $anon_distinct_id")
- #if MIXPANEL_RANDOM_DISTINCT_ID
XCTAssertNotEqual(prevDistinctId, originalDistinctId, "After reset, UUID will be used - never the same");
- #else
- XCTAssertEqual(prevDistinctId, originalDistinctId, "After reset, IFA/UIDevice id will be used - always the same");
+ #if MIXPANEL_UNIQUE_DISTINCT_ID
+ XCTAssertEqual(prevDistinctId, originalDistinctId, "After reset, IFV will be used - always the same");
#endif
mixpanel.reset()
waitForTrackingQueue()
@@ -545,9 +548,11 @@ class MixpanelDemoTests: MixpanelBaseTests {
mixpanel.archive()
mixpanel.reset()
waitForTrackingQueue()
+ #if MIXPANEL_UNIQUE_DISTINCT_ID
XCTAssertEqual(mixpanel.distinctId,
mixpanel.defaultDistinctId(),
"distinct id failed to reset")
+ #endif
XCTAssertNil(mixpanel.people.distinctId, "people distinct id failed to reset")
XCTAssertTrue(mixpanel.currentSuperProperties().isEmpty,
"super properties failed to reset")
@@ -555,8 +560,10 @@ class MixpanelDemoTests: MixpanelBaseTests {
XCTAssertTrue(mixpanel.people.peopleQueue.isEmpty, "people queue failed to reset")
mixpanel = Mixpanel.initialize(token: kTestToken, launchOptions: nil, flushInterval: 60)
waitForTrackingQueue()
+ #if MIXPANEL_UNIQUE_DISTINCT_ID
XCTAssertEqual(mixpanel.distinctId, mixpanel.defaultDistinctId(),
"distinct id failed to reset after archive")
+ #endif
XCTAssertNil(mixpanel.people.distinctId,
"people distinct id failed to reset after archive")
XCTAssertTrue(mixpanel.currentSuperProperties().isEmpty,
@@ -599,8 +606,10 @@ class MixpanelDemoTests: MixpanelBaseTests {
func testArchive() {
let testToken = randomId()
mixpanel = Mixpanel.initialize(token: testToken, launchOptions: nil, flushInterval: 60)
+ #if MIXPANEL_UNIQUE_DISTINCT_ID
XCTAssertEqual(mixpanel.distinctId, mixpanel.defaultDistinctId(),
"default distinct id archive failed")
+ #endif
XCTAssertTrue(mixpanel.currentSuperProperties().isEmpty,
"default super properties archive failed")
XCTAssertTrue(mixpanel.eventsQueue.isEmpty, "default events queue archive failed")
@@ -700,8 +709,10 @@ class MixpanelDemoTests: MixpanelBaseTests {
Persistence.deleteMPUserDefaultsData(token: testToken)
mixpanel = Mixpanel.initialize(token: testToken, launchOptions: nil, flushInterval: 60)
waitForTrackingQueue()
+ #if MIXPANEL_UNIQUE_DISTINCT_ID
XCTAssertEqual(mixpanel.distinctId, mixpanel.defaultDistinctId(),
"default distinct id from garbage failed")
+ #endif
XCTAssertTrue(mixpanel.currentSuperProperties().isEmpty,
"default super properties from garbage failed")
XCTAssertNotNil(mixpanel.eventsQueue, "default events queue from garbage is nil")