Skip to content

feat: [SDK-5383] enqueue a session create when a new session starts - #1779

Merged
fadi-george merged 3 commits into
new-session-eventsfrom
fadi/sdk-5383
Oct 20, 2026
Merged

fadi-george merged 3 commits into
new-session-eventsfrom
fadi/sdk-5383

Conversation

@fadi-george

@fadi-george fadi-george commented Oct 19, 2026 •

Copy link
Copy Markdown
Collaborator

Description

One Line Summary

When the sessions API flag is on, enqueue a session create when a new session starts.

Details

Motivation

Part of the iOS SDK Sessions stack (SDK-5383). New sessions need a POST /apps/{app_id}/sessions, sent through the session operation executor added in #1768. Replaces #1770, which closed when its base branch was deleted. Android counterpart: OneSignal/OneSignal-Android-SDK#2780.

Scope

  • OneSignalUserManagerImpl.startNewSession passes the new session's record to enqueueSessionCreate, which queues the create (local session ID as idempotency key, start_time, pinned IDs) when the session's captured usesSessionsApi is true. OSSessionService.startNewSession now returns the record it started.
  • Runs on the existing new-session path (OneSignal.m shouldStartNewSession), so the 30 s threshold, cold-start behavior, and privacy-consent gates are unchanged. Resuming within the threshold sends no create.
  • Fixes a prewarm double start that this PR would have turned into two creates. Init's start does nothing while storage is locked; on a foreground 30 s or more later, deferred recovery and the tracker each started a session, which already double counted legacy session_count. The 30 s check moves from OneSignal.m into OSSessionStartGate (same rule), and recovery and tracker starts are skipped when a session started within 30 s. Starts from init are never skipped.
  • Unlike Android, a create with missing IDs is still queued; the executor holds it until the user is created.
  • Flag off: no create. The legacy session start is unchanged.
  • Aligns the create body with the current spec: device_type is renamed to subscription_type and sent as iOSPush, like outcomes. The idempotency key is already the bare session UUID.
  • Not included: direct_attribution_id (SDK-5399), session end (SDK-5391).

Testing

Unit testing

Added SessionRecordUserTests cases through startNewSession: a create with the session's ID and start time, a separate create per session, and no create with the flag off. The executor test now checks subscription_type. Added OSSessionStartGateTests for the 30 s resume and init rules and for deduplicating the prewarm starts. The OneSignal.m wiring has no test, since the Obj-C UnitTests that drive init and the lifecycle are commented out.

UnitTestApp_TestPlan_Reduced, SessionRecordUserTests, OSSessionOperationExecutorTests, and OSSessionServiceTests pass locally. SwiftLint reports no new violations.

Manual testing

Not tested on device yet; end-to-end verification is planned in the iOS rollout and QA ticket.

Affected code checklist

  • Notifications
    • Display
    • Open
    • Push Processing
    • Confirm Deliveries
  • Outcomes
  • Sessions
  • In-App Messaging
  • REST API requests
  • Public API changes

Checklist

Overview

  • I have filled out all REQUIRED sections above
  • PR does one thing
  • Any Public API changes are explained in the PR details and conform to existing APIs

Testing

  • I have included test coverage for these changes, or explained why they are not needed
  • All automated tests pass, or I explained why that is not possible
  • I have personally tested this on my device, or explained why that is not possible

Final pass

  • Code is as readable as possible.
  • I have reviewed this PR myself, ensuring it meets each checklist item

🤖 Generated with Claude Code

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@abdulraqeeb33 abdulraqeeb33 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The wiring looks right. The create is the record just persisted, flag-off still skips it, and a normal resume still goes through the 30s gate.

One path now sends two creates, noted on the enqueue. The new tests never enter that gate.

fadi-george and others added 2 commits October 20, 2026 10:56
…ion create

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@abdulraqeeb33 abdulraqeeb33 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The prewarm dedupe can stay. Init is not deduped, and the locked-storage return happens before the slot is claimed, so recovery and the foreground start collapse to one session.

The create body still needs integer device_type. See the inline.

@fadi-george
fadi-george dismissed abdulraqeeb33’s stale review October 20, 2026 20:24

Ignoring device_type comment.

@fadi-george
fadi-george merged commit 07db939 into new-session-events Oct 20, 2026
7 of 8 checks passed
@fadi-george
fadi-george deleted the fadi/sdk-5383 branch October 20, 2026 20:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants