-
Notifications
You must be signed in to change notification settings - Fork 64
feat: Support default properties #375
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: Support default properties #375
Conversation
55b8101 to
cbdc37e
Compare
16e9060 to
42389e8
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LG, a minor comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
left a few comments
Automatically sets common device and app properties as person properties during SDK initialization to eliminate race conditions where feature flags couldn't use person properties until identify() calls were processed. Properties automatically set: - $app_version: App version from bundle - $app_build: App build number - $os_name: Operating system name - $os_version: OS version - $device_type: Device type (Mobile, Tablet, Desktop, etc.) - $locale: User's locale Includes configuration option to disable (setDefaultPersonProperties) and automatic refresh on app updates.
If sanitization of default person properties fails, log a warning and skip setting the properties instead of silently falling back to empty dictionary.
Apply SwiftFormat fixes to remove trailing spaces, consecutive spaces, and redundant internal access control.
Document the new default properties support for feature flag evaluation that eliminates race conditions during SDK initialization.
Remove redundant waitFlagsRequest calls before getFlagsRequest calls, since getFlagsRequest internally waits for the expectation. This fixes the "expectations can only be waited on once" error in CI.
System-provided properties don't need sanitization as they are already safe for JSON serialization.
App updates only occur on fresh launches, making this refresh redundant since setDefaultPersonProperties is already called during SDK initialization.
Read locale directly from Locale.current instead of calling expensive dynamicContext() method that computes many unnecessary values.
Method is no longer needed after removing Application Updated refresh logic.
Remove extra blank lines to satisfy SwiftFormat linter.
5faf6c1 to
fe000bc
Compare
The test expects a flags request to be made during SDK initialization which only happens when preloadFeatureFlags is enabled.
- Remove caching of default person properties in storage - Modify getPersonPropertiesForFlags to compute fresh default properties every time - Default properties are now always current (e.g., locale, OS version changes) - Remove setDefaultPersonProperties call from SDK initialization - Add closure parameter to PostHogRemoteConfig for getting fresh default properties - Update all test files to provide empty default properties closure This addresses the concern that cached default properties could become stale and lead to incorrect values being used in feature flag evaluation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR implements automatic default person properties for feature flag evaluation, eliminating race conditions where flags fail to work immediately after SDK initialization. The feature automatically sets common device and app properties (like $app_version, $os_version) as person properties during SDK initialization, ensuring feature flags work without waiting for server-side processing of identify() calls.
- Adds automatic setting of 6 default person properties (
$app_version,$app_build,$os_name,$os_version,$device_type,$locale) - Includes configurable opt-out mechanism via
setDefaultPersonPropertiesconfig option - Updates remote config initialization to support property provider callback pattern
Reviewed Changes
Copilot reviewed 9 out of 9 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| PostHog/PostHogConfig.swift | Adds setDefaultPersonProperties configuration option with detailed documentation |
| PostHog/PostHogSDK.swift | Implements getDefaultPersonProperties() method and updates remote config initialization |
| PostHog/PostHogRemoteConfig.swift | Updates constructor to accept property provider callback and merges default properties |
| PostHogTests/PostHogSDKTest.swift | Adds comprehensive tests for enabled/disabled default properties scenarios |
| PostHogTests/*.swift | Updates test helper constructors to include property provider callback |
| PostHogExample/ContentView.swift | Updates documentation comments explaining automatic property behavior |
| CHANGELOG.md | Documents the new feature |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
left a last comment otherwise LGTM
This ensures consistent API design patterns for Objective-C interoperability and provides clear semantics for the method parameters.
- Add setGroupPropertiesForFlagsIfNeeded helper method - Automatically set person properties for flags in capture() method when userProperties or userPropertiesSetOnce are provided - Automatically set group properties for flags in group() method when groupProperties are provided This ensures feature flag evaluation has access to the latest properties without requiring manual calls to setPersonPropertiesForFlags or setGroupPropertiesForFlags.
- Test that capture() with userProperties automatically sets person properties for flags - Test that group() with groupProperties automatically sets group properties for flags These tests verify that feature flag evaluation has access to properties passed to capture() and group() methods without requiring manual calls to the property setter methods.
…tify This improves code organization by: - Making groupIdentify fully responsible for all group-related operations - Matching the pattern used in identify() for consistency - Ensuring flag properties are set even if groupIdentify is called from other places in the future - Simplifying the public group() method to only handle validation and delegation
- Add hasPersonProcessing() check to setPersonPropertiesForFlags - Add hasPersonProcessing() check to setGroupPropertiesForFlags - Add hasPersonProcessing() check to resetPersonPropertiesForFlags - Add hasPersonProcessing() check to resetGroupPropertiesForFlags This ensures consistency with internal helper methods and prevents setting properties for feature flags when person processing is disabled (e.g., when personProfiles is set to 'never').
- Add optional reloadFeatureFlags parameter to setGroupPropertiesForFlags for consistency with setPersonPropertiesForFlags - Maintain backward compatibility with a convenience overload that defaults to true - Update documentation to explain both usage patterns This allows users to batch multiple group property updates before reloading flags, improving performance when setting properties for multiple groups.
- Remove 'test' prefix from @test methods (Swift Testing convention) - Remove trailing spaces from all lines These changes comply with the project's SwiftFormat and SwiftLint rules.
Clear personPropertiesForFlags and groupPropertiesForFlags when resetting the SDK storage. This ensures that cached feature flag properties are properly cleaned up during reset operations.
|
I'm going to merge this into haacked/366-attach-properties and lets continue the work there. |
…erty reading Addresses PR feedback from #375 by creating a centralized method for extracting person properties from the context. This eliminates code duplication and creates a single source of truth for property keys, making future refactoring easier.
This is a follow-up to #373 (and targets that branch)
💡 Motivation and Context
Feature flags that rely on person properties like
$app_versionor$os_versionoften fail to work immediately after SDK initialization because these properties aren't available untilidentify()calls are processed server-side. This creates a race condition where flags return incorrect values during the critical first moments of app usage.This PR implements automatic person properties similar to the PostHog web SDK, where common device and app properties are automatically set as person properties during SDK initialization.
Properties automatically set:
$app_version- App version from bundle(
CFBundleShortVersionString)$app_build- App build number (CFBundleVersion)$os_name- Operating system name (iOS, macOS, etc.)$os_version- Operating system version$device_type- Device type (Mobile, Tablet, Desktop, etc.)$locale- User's current localeKey benefits:
💚 How did you test it?
📝 Checklist