* Add deviceIdProvider closure for custom device ID generation
Adds a `deviceIdProvider: (() -> String)?` property to MixpanelOptions
that allows customers to supply their own device ID generation logic.
Key behaviors:
- Provider called on init (if no persisted identity) and after reset()/optOutTracking()
- Return same value = persistent device ID (never resets)
- Return different value = ephemeral device ID (resets each time)
- SDK logs warning when provider would replace existing persisted anonymousId
- Empty string from provider falls back to default UUID/IDFV behavior
This gives customers full control over device ID persistence and reset
semantics without needing separate parameters on reset() and optOutTracking().
Includes:
- 13 unit tests covering all behaviors
- Comprehensive documentation in docs/device-id-provider.md
* Address PR review feedback for deviceIdProvider
- Change log level from warn to error for identity mismatch
- Use defaultDeviceId() in unarchive to avoid calling provider twice
- Add whitespace trimming to provider result
- Update documentation table with "Value Used?" column
- Add testIdentifyWithDeviceIdProvider test case
* Add deviceIdProvider QA helpers to MixpanelDemo
- Add persistent and ephemeral device ID provider examples in AppDelegate
- Enhance Reset button with before/after console logging
- Default to no provider (standard SDK behavior) for production
* Make deviceIdProvider return optional String for graceful error handling
Change type from `(() -> String)?` to `(() -> String?)?` so customers can
return nil to signal "use SDK default" when their device ID source fails.
- Update MixpanelOptions type signature and documentation
- Handle optional return in defaultDeviceId() with nil-coalescing
- Update warning message to mention nil or empty string
- Add failingDeviceIdProvider test option in demo app
- Add testProviderReturningNilFallsBackToDefault test
* Add Original ID Merge compatibility note to deviceIdProvider docs
Document the footgun with persistent device IDs + Original ID Merge
on shared devices, where createAlias() can incorrectly merge
identities of different users.
* Add thread-safety warning to deviceIdProvider documentation
The provider closure is called while holding internal locks, so blocking
operations (Keychain, network, UserDefaults) can cause deadlocks. Update
docs and examples to recommend caching the device ID at app launch and
returning the cached value from the provider.
- Add Thread Safety note to MixpanelOptions.swift doc comment
- Update docs/device-id-provider.md with caching pattern
- Revise Best Practices to emphasize non-blocking providers
- Update MixpanelDemo to demonstrate caching pattern