Repository navigation
Release 1.4.1 - #53
Conversation
The backend now de-duplicates identify calls, so the SDK no longer compares an identify with the cached user and drops it when nothing changed. Every identify is sent, and the pending identify is still cached until the backend acknowledges it. Removes the now-unused User comparison helpers and their tests. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
| // Drop identify events that carry nothing new. Non-identify events skip this. | ||
| if event.isIdentifyEvent, didHandleIdentifyEvent(event) { return } | ||
| // Cache the pending user until the backend acknowledges the identify | ||
| if event.isIdentifyEvent { storage.temporaryUser = event.toUser().toJson() } |
There was a problem hiding this comment.
Pending user updates disappear
If an identify with new properties is waiting for an ACK, a later identify with the old properties replaces temporaryUser. If the app closes before either ACK, startup restores only the old properties and loses the pending update. Keep the newer pending data when saving another identify.
| // Drop identify events that carry nothing new. Non-identify events skip this. | ||
| if event.isIdentifyEvent, didHandleIdentifyEvent(event) { return } | ||
| // Cache the pending user until the backend acknowledges the identify | ||
| if event.isIdentifyEvent { storage.temporaryUser = event.toUser().toJson() } |
There was a problem hiding this comment.
Repeated identifies reload screens
When an app calls identify again with unchanged data, its ACK can queue a fake screen reload if a screen is active and the event queue is empty. Backend de-duplication cannot stop this extra client-side request. It sends another screen event and makes later events wait for its ACK. Avoid the reload when nothing about the user changed.
Replace fixed setup delays with expectations for monitor readiness and interface loss. Keep a slower debounce in the interface-down test to cover the timing condition that failed the PR quality gate. SDK behavior is unchanged.
🚀 Description
Release Userpilot iOS SDK 1.4.1.
Backend now owns identify de-duplication, so the SDK no longer drops “unchanged” identify calls client-side. Every
identifyis forwarded; the pending identify is still cached intemporaryUseruntil the backend acknowledges it.Affected areas
AnalyticsPublisherevent routing for identifyUsercomparison helpers (removed)1.4.0→1.4.1(Version.swift,Userpilot.podspec)Public API
@objcsurface changes. Removed helpers were internal (isSameIdentifyEvent,ComparisonStrategy, dictionary compare utilities).📄 Motivation and Context
Client-side identify de-dupe could drop legitimate identifies (and complicated socket replay). With server-side de-duplication in place, the SDK should always send identify and keep only the pending-user cache until ACK.
Commits on
1.4.1sincemain:985e0cf— remove client-side identify de-duplicatione4de00d— bump version to 1.4.1📦 Types of Changes
🔌 Public API & Wrapper Impact
If the public API changed, confirm:
@objc-exposed and Objective-C-bridgeable, and non-throwingWrapper migration notes (required for any public API change)
None needed — internal analytics/storage helpers only; Flutter / React Native / Capacitor can bump to native 1.4.1 with no bridge API changes.
🧪 How Has This Been Tested?
Identify no longer short-circuits when the cached user matches the event; pending user is still written to
temporaryUser.Related XCTest coverage updated (
AnalyticsPublisherTests, removed obsoleteUserTestscomparison cases).Unit tests (XCTest)
Manual testing on real devices
Manual testing on simulators
Tested on different iOS versions (please list — deployment target is iOS 13)
Tested with different device types (iPhone, iPad)
📷 Screenshots / Screen Recordings (if appropriate)
N/A — analytics routing / internal storage change; no UI.
🛠 Migration Notes (optional)
identifycalls to reach the backend (server de-dupes); no client-side drop.None. Internal-only removals:
User.isSameIdentifyEvent(...)ComparisonStrategyAnalyticsPublisher.didHandleIdentifyEvent(_:)🧹 Cleanup Tasks (optional)
None.
✅ Checklist
AGENTS.md).PRODUCTIONwith placeholder socket URL / token, and noNX-in SocketManagerxcodebuild test -scheme Userpilotpasses, and I added tests where applicableswiftlint --strictis clean (no new warnings or errors in Xcode)docs/, README, DocC) if neededUserpilot.podspecstill covers them (pod lib lint)Made with Cursor