feat: Add double-open bug demonstration and fix toggle (EMT-2816)#14
Open
wpinho-branch wants to merge 19 commits intomainfrom
Open
feat: Add double-open bug demonstration and fix toggle (EMT-2816)#14wpinho-branch wants to merge 19 commits intomainfrom
wpinho-branch wants to merge 19 commits intomainfrom
Conversation
Update SDK dependency to use fix/EMT-2816-double-open-issue branch for testing the double-open prevention solution. Changes: - Point SPM to fix/EMT-2816-double-open-issue branch - Update Package.resolved with new revision - Fix .gitignore merge conflict (enable xcodeproj tracking)
Implement testing UI for the double-open SDK fix: - Add SceneDelegate with toggle between old/new Branch init APIs - Add toggle in HomeView to switch between APIs (requires app restart) - Add OPEN request counter to track /v1/open and /v2/event(open) calls - Add LogsView with Timeline and OPEN Requests tabs for log visualization - Update RoundTrip model with isOpenRequest tracking - Update RoundTripStore with log entries and OPEN detection - Update Info.plist with UIApplicationSceneManifest configuration - Update BranchLinkSimulatorApp.swift for Scene lifecycle The toggle allows comparing behavior: - OLD API: Branch.initSession(launchOptions:) - may cause double OPEN - NEW API: BranchScene.initSession(with:) - prevents double OPEN Expected results when testing: - With OLD API: 2 OPEN requests on cold launch via deep link - With NEW API: 1 OPEN request on cold launch via deep link
Add more detailed logs with visual separators to make it clear: - When COLD LAUNCH happens (app was killed) - When WARM LAUNCH happens (app was in background) - Which API is being used (OLD vs NEW) - What is expected (1 vs 2 OPEN requests) - Branch callback results
Changes: - OLD API now uses Branch.handleDeepLink() instead of BranchScene methods - Cold launch with OLD API processes URL from connectionOptions manually, triggering a second OPEN request (demonstrating the bug) - NEW API skips manual URL processing since BranchScene.initSession already handles the URL internally (demonstrating the fix) Expected behavior: - OLD API (toggle OFF): 2 OPEN requests on cold launch via deep link - NEW API (toggle ON): 1 OPEN request on cold launch via deep link
Changes: - OLD API now uses Branch.application(_:open:options:) for URL schemes (the actual AppDelegate method that would cause double-open) - OLD API now uses Branch.continue(userActivity) for Universal Links - Clear step-by-step logging showing: - Step 1: initSession(launchOptions: nil) → OPEN #1 - Step 2: application(_:open:) → OPEN #2 (bug) - NEW API uses BranchScene.initSession(with:) which handles everything in a single OPEN request
Create basic Info.plist configuration for the BranchLinkSimulatorUITests target with standard bundle settings.
Add comprehensive UI test suite for verifying the double-open bug fix in scene-based iOS apps with Branch SDK. Test coverage: - testToggleExists: Verify toggle accessibility identifier - testToggleFunctionality: Test toggle state changes - testModeDescriptionUpdates: Verify API mode description updates - testViewLogsNavigation: Test navigation to logs screen - testLogsScreenTabs: Verify segmented picker tabs - testOpenRequestCounterVisible: Check OPEN request counter visibility - testClearLogs: Test clear logs functionality - testAllSectionsVisible: Verify main sections render - testAPIModePersisters: Test toggle persistence across restarts - testAccessibilityElements: Verify UI accessibility - testStatusIndicatorStates: Test status indicator text - testOldAPIColdLaunchDocumentation: Document OLD API behavior - testNewAPIColdLaunchDocumentation: Document NEW API behavior - testAppLaunchPerformance: Measure app launch time - testNavigateToLogsPerformance: Measure logs navigation Key implementation details: - Uses coordinate-based tap (dx: 0.9, dy: 0.5) for reliable SwiftUI toggle - Handles both IDFA permission and Branch SDK error alerts - Properly detects SwiftUI SegmentedPickerStyle via segmentedControls - Flexible element detection with multiple fallback checks
Configure BranchLinkSimulatorUITests target in Xcode project: - Add PBXContainerItemProxy for test dependency - Add file references for test sources and Info.plist - Configure build phases (Sources, Frameworks, Resources) - Add target dependency on BranchLinkSimulator app - Configure test host and bundle identifier settings
- Add case-insensitive matching for URL and body patterns - Detect BranchOpenRequest from SDK log messages - Handle api.branch.io URLs with open in either URL or body - Improves reliability of double-open bug detection
…h requests - Intercept all Branch SDK network requests via URLProtocol - Capture and log OPEN requests to RoundTripStore - Track request/response details for debugging - Support all Branch API domains (api.branch.io, api2.branch.io, etc.)
- Register BranchNetworkInterceptor to capture all Branch requests - Parse SDK log messages to detect OPEN requests - Log OPEN request detections to RoundTripStore - Ensure SceneDelegate is used via explicit delegateClass
- Add NEW API mode: BranchScene.initSession(with: connectionOptions) Sends only 1 OPEN request (EMT-2816 fix) - Add OLD API mode: Branch.initSession(launchOptions: nil) Demonstrates the double-open bug (2 OPEN requests) - Add debug logging to file for cold launch analysis - Log connectionOptions.urlContexts and userActivities - Support toggle via @AppStorage("useDoubleOpenFix")
…gate - Replace SwiftUI @main with UIApplicationMain - Ensure SceneDelegate is properly invoked for window/scene management - Required for proper Branch SDK integration with connectionOptions
- Rename section to "EMT-2816: Double-Open Test" - Add accessibility identifiers for E2E testing - Display API mode descriptions (NEW/OLD API) - Add status indicators (fix enabled vs bug mode) - Show visual feedback for double-open bug detection - Add clear logs button for testing workflow
- Package resolution managed by SPM, no need to track
- BranchLinkSimulator.xcscheme - Main app scheme - BranchLinkSimulatorTests.xcscheme - Unit tests scheme - BranchLinkSimulatorUITests.xcscheme - UI tests scheme for E2E testing
- Automated test script for EMT-2816 / INTENG-21106 - Tests both OLD API (bug) and NEW API (fix) scenarios - Cold launch via Universal Link simulation - Validates OPEN request count for each API mode
- Package.resolved with Branch SDK dependency - Points to fix/EMT-2816-double-open-issue_without-fix branch
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR adds a demonstration and testing capability for the double-open bug fix (EMT-2816 / INTENG-21106) in scene-based iOS apps using Branch SDK.
The Bug
When a scene-based iOS app is cold-launched via a deep link, the OLD API pattern causes 2 OPEN requests to be sent instead of 1:
Branch.initSession(launchOptions: nil)scene(_:continue:)handling the Universal LinkThe Fix
The NEW API (
BranchScene.initSession(with: connectionOptions)) handles both initialization and deep link in a single call, sending only 1 OPEN request.Changes
Core Implementation
App Architecture
UIApplicationMainto ensure SceneDelegate is properly invokedE2E Tests
Test Plan
Prerequisites
Manual Testing: Reproducing the Bug (OLD API)
xcrun simctl openurl booted "https://branchlinksimulator.app.link/test"Manual Testing: Verifying the Fix (NEW API)
xcrun simctl openurl booted "https://branchlinksimulator.app.link/test"Running E2E Tests
Expected: All 15 tests pass
Test Cases Covered
testToggleExiststestToggleFunctionalitytestAPIModePersisterstestModeDescriptionUpdatestestStatusIndicatorStatestestOpenRequestCounterVisibletestViewLogsNavigationtestLogsScreenTabstestClearLogstestAllSectionsVisibletestAccessibilityElementstestAppLaunchPerformancetestNavigateToLogsPerformancetestNewAPIColdLaunchDocumentationtestOldAPIColdLaunchDocumentationAPI Comparison
Branch.initSession(launchOptions: nil)BranchScene.initSession(with: connectionOptions)scene(_:continue:)Related