Skip to content

fix: Call identify hooks during init.#487

Merged
tanderson-ld merged 8 commits intov11from
beeklimt/SDK-2049
Mar 24, 2026
Merged

fix: Call identify hooks during init.#487
tanderson-ld merged 8 commits intov11from
beeklimt/SDK-2049

Conversation

@beekld
Copy link
Copy Markdown
Contributor

@beekld beekld commented Mar 19, 2026

Requirements

  • I have added test coverage for new or changed functionality
  • I have followed the repository's pull request submission guidelines
  • I have validated my changes against all supported platform versions

Related issues

N/A

Describe the solution you've provided

Before this change, beforeIdentify and afterIdentify were only called when identify was called. After this change, they are also called as part of init.

Describe alternatives you've considered

None.

Additional context

I don't think this would be considered a breaking change, but I wouldn't mind a second opinion. The change in behavior is observable by the user, but the new behavior is what was originally intended. So I would consider this a bugfix, and would not expect customers to need to make any changes to their code to deal with the change.


Note

Medium Risk
Changes observable hook execution timing by invoking beforeIdentify/afterIdentify during LDClient init and by including plugin-provided hooks in that lifecycle, which could affect apps with side-effecting hooks. Scope is limited to hook plumbing and tests, with no auth or data model changes.

Overview
LDClient now executes identify hooks as part of initialization: it runs beforeIdentify with method name "init" and defers afterIdentify until the initial setOnline completes.

Plugin hooks are collected earlier (during LDClient init rather than LDClient.start) so plugin-provided hooks participate in the init identify lifecycle, and the hook helper APIs in LDClientIdentifyHook.swift are widened to internal to support this.

Tests are updated/expanded to assert the additional init-time hook calls, preserve hook ordering, and verify plugin hooks fire during init.

Written by Cursor Bugbot for commit ab0372a. This will update automatically on new commits. Configure here.

@beekld beekld marked this pull request as ready for review March 19, 2026 19:34
@beekld beekld requested a review from a team as a code owner March 19, 2026 19:34
flagStore.replaceStore(newStoredItems: cachedFlags)
}

let hookState = executeBeforeIdentifyHooks(context: context)
Copy link
Copy Markdown
Contributor

@tanderson-ld tanderson-ld Mar 20, 2026

Choose a reason for hiding this comment

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

The beforeIdentify hooks should run after the auto environment attributes are added to the context (so that the implementer of the beforeIdentify call can see all the added attributes), and before we use that modified context to load cache or make network connections.

https://github.com/launchdarkly/sdk-specs/tree/main/specs/HOOK-hooks#conditional-requirement-1412

So likely it needs to be called right after this block, but double check.

        if config.autoEnvAttributes {
            context = AutoEnvContextModifier(environmentReporter: environmentReporter, logger: config.logger).modifyContext(context)
        }

You can think of "identify" as updating the context the SDK is going to use and do things with. If the SDK does anything with the context that can be detected or observed by the outside world, such as making network requests or loading cache which impacts flag evals, and it does so before beforeIdentify, it has sorta violated the logical order and it is a externally detectable contradiction of the API.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Okay, I think I've got it, and I think that's the right place. I mean, it seems clear from the spec that beforeIdentify should be called before flagCache.getCachedData at least. It's not obvious on first glance whether the various make functions on the previous lines have side effects, so it's better to err on calling the hooks before them.

There was one slight complication -- Swift really does not like init methods calling member functions before all object properties have been initialized, and flagSynchronizer is initialized after the cache is loaded. But the code in executeBeforeIdentifyHooks is very short and doesn't access any properties other than hooks, so I copy-pasted the code into init.

Please take another look.

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.

Did the commit get pushed?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

🤦‍♀️ no. okay. it's been pushed now. sorry about that.

@beekld beekld requested a review from tanderson-ld March 20, 2026 23:16
Copy link
Copy Markdown

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Fix All in Cursor

Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.

@tanderson-ld tanderson-ld merged commit 844d5d4 into v11 Mar 24, 2026
18 checks passed
@tanderson-ld tanderson-ld deleted the beeklimt/SDK-2049 branch March 24, 2026 20:21
tanderson-ld pushed a commit that referenced this pull request Mar 24, 2026
🤖 I have created a release *beep* *boop*
---


##
[11.1.2](11.1.1...11.1.2)
(2026-03-24)


### Bug Fixes

* app hang in didEnterBackground by making ConnectionInformationStore
writes async
([#489](#489))
([72b0ab4](72b0ab4))
* Call identify hooks during init.
([#487](#487))
([844d5d4](844d5d4))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> Low risk release bookkeeping only: version strings and
documentation/changelog updates with no functional code changes in this
diff.
> 
> **Overview**
> Bumps the SDK version from `11.1.1` to `11.1.2` across release
metadata (`.release-please-manifest.json`), build settings
(`DYLIB_CURRENT_VERSION`/`MARKETING_VERSION` in `project.pbxproj`),
CocoaPods (`LaunchDarkly.podspec`), and runtime reporting
(`ReportingConsts.sdkVersion`).
> 
> Updates `CHANGELOG.md` with the `11.1.2` release notes and refreshes
the SPM install snippet in `README.md` to reference `11.1.2`.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
feb3392. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: LaunchDarklyReleaseBot <LaunchDarklyReleaseBot@launchdarkly.com>
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.

2 participants