Skip to content

Removed Auto Initialization#1571

Merged
NidhiDixit09 merged 3 commits intondixit/EMT-3068from
ndixit/EMT-2937
Feb 20, 2026
Merged

Removed Auto Initialization#1571
NidhiDixit09 merged 3 commits intondixit/EMT-3068from
ndixit/EMT-2937

Conversation

@NidhiDixit09
Copy link
Copy Markdown
Collaborator

  • Added API - - (void)setConsumerProtectionAttributionLevel:(BranchAttributionLevel)level resetSession:(BOOL)resetSession to provide an option to disable resetting session.
  • Removed silent SDK initialization - initSafetyCheck removed.Now APIs will return or log BNCInitError error.
  • Added @synchronized(self) around all 5 init status checks to ensure it waits for any in-progress initSession code (which also uses @synchronized(self)) to finish and update the status before evaluating.

Reference

SDK-XXXX -- <TITLE>.

Summary

Motivation

Type Of Change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • This change requires a documentation update

Testing Instructions

cc @BranchMetrics/saas-sdk-devs for visibility.

Added API - `- (void)setConsumerProtectionAttributionLevel:(BranchAttributionLevel)level resetSession:(BOOL)resetSession` to provide an option to disable resetting session.
Remove silent SDK initialization - initSafetyCheck removed.Now APIs will return or log BNCInitError error.
Added @synchronized(self) around all 5 init status checks to ensure it waits for any in-progress initSession code (which also uses @synchronized(self)) to finish and update the status before evaluating.
@matterai-app
Copy link
Copy Markdown
Contributor

matterai-app Bot commented Feb 17, 2026

Code Quality new feature bug fix

Summary By MatterAI MatterAI logo

🔄 What Changed

Removed silent SDK auto-initialization (initSafetyCheck) in favor of explicit status guards. Core methods in Branch.m now verify BNCInitStatusUninitialized and return a BNCInitError via callbacks dispatched to the main thread. Introduced @synchronized(self) blocks for thread-safe initialization status checks and a new API setConsumerProtectionAttributionLevel:resetSession: to manage attribution without mandatory session resets.

🔍 Impact of the Change

Enforces a strict initialization contract, preventing unpredictable behavior from premature API calls. Moving error callbacks to the main thread and adding synchronization improves thread safety and ensures developers receive immediate, actionable feedback via BNCInitError instead of silent failures.

📁 Total Files Changed

Click to Expand
File ChangeLog
Init Guards Branch.m Implemented initialization checks, main-thread callback dispatching, and thread synchronization for status evaluation.

🧪 Test Added/Recommended

Recommended

  • Unit Test: Verify that calling APIs before initSession triggers the BNCInitError callback.
  • Concurrency Test: Validate that @synchronized(self) correctly handles simultaneous initialization and API calls.
  • Main Thread Check: Assert that all error callbacks are executed on the main queue.

🔒Security Vulnerabilities

No vulnerabilities detected. The implementation of explicit error states and input guards follows defensive programming best practices. 🛡️

⏳ Estimated code review effort

LOW (~10 minutes)

Tip

Quality Recommendations

  1. Ensure all public API entry points in Branch.m consistently implement the BNCInitStatusUninitialized guard.

  2. Verify that BNCCallbackMap is thread-safe when accessed within the main queue dispatch block.

  3. Add a symbolic constant for the dispatch_get_main_queue block to improve readability if reused across multiple methods.

♫ Tanka Poem

Silent starts are gone, 🚀
Explicit calls lead the way,
Threads now sync in peace, 🔒
Errors find the main queue home,
Safety rules the SDK. 🛡️

Sequence Diagram

sequenceDiagram
    participant A as App
    participant B as Branch SDK
    participant L as BranchLogger
    participant M as Main Queue
    participant C as BNCCallbackMap

    A->>B: callAPI(request)
    Note over B: @synchronized(self) check status
    alt Status == Uninitialized
        B->>L: logWarning(BNCInitError)
        B->>M: dispatch_async(main_queue)
        M->>C: callCompletionForRequest(request, error)
        C-->>A: completion(success: NO, error)
    else Status == Initialized
        Note over B: Process Request Normally
    end
Loading

Copy link
Copy Markdown
Contributor

@matterai-app matterai-app Bot left a comment

Choose a reason for hiding this comment

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

🧪 PR Review is completed: Critical review focusing on thread safety. The introduction of @synchronized(self) combined with synchronous main-thread dispatching creates significant deadlock risks in several methods. These should be converted to asynchronous dispatches to match the existing async nature of these methods and prevent deadlocks.

Comment thread Sources/BranchSDK/Branch.m Outdated
Comment thread Sources/BranchSDK/Branch.m Outdated
@NidhiDixit09
Copy link
Copy Markdown
Collaborator Author

@gdeluna-branch Should I call all callbacks reporting error on main thread ? Currenlty I have copied the behavior from the success path - how(sync/asynchronous) and where (main/same thread) callback is called when API succeeds.

Copy link
Copy Markdown
Contributor

@matterai-app matterai-app Bot left a comment

Choose a reason for hiding this comment

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

🧪 PR Review is completed: The changes effectively mitigate the deadlock risks by adopting asynchronous dispatch for callbacks. I've noted one improvement to enhance thread safety regarding the BNCCallbackMap usage.

Comment thread Sources/BranchSDK/Branch.m Outdated
Comment on lines +1233 to +1237
if ([[BNCCallbackMap shared] containsRequest:request]) {
dispatch_async(dispatch_get_main_queue(), ^{
[[BNCCallbackMap shared] callCompletionForRequest:request withSuccessStatus:NO error:error];
});
}
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.

🟡 Concurrency / Thread Safety

Issue: Checking containsRequest: on the current thread (which might be a background thread) creates a potential race condition. The request could be removed from the map between the check and the asynchronous execution. Additionally, if BNCCallbackMap is not thread-safe, accessing it from a background thread is risky.

Fix: Move the containsRequest: check inside the dispatch_async block. This ensures the check and execution happen atomically on the main thread and aligns with the pattern used in other hunks.

Impact: Improves thread safety and prevents potential race conditions.

Suggested change
if ([[BNCCallbackMap shared] containsRequest:request]) {
dispatch_async(dispatch_get_main_queue(), ^{
[[BNCCallbackMap shared] callCompletionForRequest:request withSuccessStatus:NO error:error];
});
}
dispatch_async(dispatch_get_main_queue(), ^{
if ([[BNCCallbackMap shared] containsRequest:request]) {
[[BNCCallbackMap shared] callCompletionForRequest:request withSuccessStatus:NO error:error];
}
});

@gdeluna-branch
Copy link
Copy Markdown
Contributor

@gdeluna-branch Should I call all callbacks reporting error on main thread ? Currenlty I have copied the behavior from the success path - how(sync/asynchronous) and where (main/same thread) callback is called when API succeeds.

Yes since the callbacks return UI data or error for UI we should consistently return on main for both paths.

Copy link
Copy Markdown
Contributor

@matterai-app matterai-app Bot left a comment

Choose a reason for hiding this comment

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

🧪 PR Review is completed: The changes correctly implement explicit error handling for uninitialized states. However, the asynchronous callback dispatch requires a safety check to handle potential race conditions.

Comment thread Sources/BranchSDK/Branch.m
@NidhiDixit09 NidhiDixit09 merged commit 2e3fba2 into ndixit/EMT-3068 Feb 20, 2026
10 checks passed
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