Skip to content

feat: attribute data type updates#40

Merged
pandeymangg merged 12 commits intomainfrom
feat/attribute-data-type-updates
Feb 17, 2026
Merged

feat: attribute data type updates#40
pandeymangg merged 12 commits intomainfrom
feat/attribute-data-type-updates

Conversation

@pandeymangg
Copy link
Contributor

@pandeymangg pandeymangg commented Feb 13, 2026

setAttribute changes for supporting number, string and date attribute types. Also, adds a change which lets users override the current userId set by just calling the setUserId function again

@pandeymangg pandeymangg marked this pull request as ready for review February 16, 2026 04:21
@coderabbitai
Copy link

coderabbitai bot commented Feb 16, 2026

Walkthrough

This pull request introduces a typed attribute system by creating a new AttributeValue enum that supports string and numeric values. Attributes throughout the SDK are converted from [String: String] to [String: AttributeValue]. The public API is expanded with new methods for setting string, number, and date attributes. HTTPS enforcement during setup is removed. Language attribute extraction is strengthened with safer optional handling. New optional properties for server messages and errors are added to UserResponseData. All affected call sites and tests are updated to use the new AttributeValue type.

🚥 Pre-merge checks | ✅ 3 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 55.56% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title 'feat: attribute data type updates' accurately summarizes the main change: a comprehensive migration from string-based attributes to a typed AttributeValue system across the SDK.
Merge Conflict Detection ✅ Passed ✅ No merge conflicts detected when merging into main
Description check ✅ Passed The pull request description mentions attribute type support (number, string, date) and userId override functionality, which align with the actual changeset that introduces AttributeValue enum and new typed attribute methods.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

Tip

Issue Planner is now in beta. Read the docs and try it out! Share your feedback on Discord.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In `@Sources/FormbricksSDK/Formbricks.swift`:
- Around line 66-70: Re-enable the HTTPS enforcement that was commented out:
restore the guard validating url.scheme?.lowercased() == "https" (the block that
logs to Formbricks.logger and returns using config.appUrl) so the SDK rejects
non-HTTPS endpoints by default; if you need HTTP for local/dev, add an explicit,
documented opt-in (e.g. a config flag like allowInsecureHttp or tied to a debug
build flag) and use that flag to bypass the guard only when intentionally
enabled.

In `@Sources/FormbricksSDK/Networking/Base/APIClient.swift`:
- Around line 32-37: Restore the HTTPS enforcement that was commented out in
APIClient (the guard using components.scheme and comparing to "https") so
requests default to being blocked over HTTP; if localhost/dev needs HTTP, gate
that exception behind a build-config or runtime flag (e.g., only allow non-HTTPS
when compiled with DEBUG or when a new allowInsecureHTTP flag is true), and
update the stale comment to reflect the conditional behavior; ensure the error
path still logs the descriptive message including apiURL via
Formbricks.logger.error and returns nil (or fails) when insecure requests are
not permitted.
🧹 Nitpick comments (4)
Sources/FormbricksSDK/Model/User/AttributeValue.swift (2)

77-79: Consider caching the ISO8601DateFormatter instance.

ISO8601DateFormatter() is relatively expensive to create. If from(_ value: Date) is called frequently (e.g., in a loop setting multiple date attributes), this could become a performance bottleneck.

♻️ Proposed fix: use a static formatter
+    private static let iso8601Formatter = ISO8601DateFormatter()
+
     /// Creates an `AttributeValue` from a `Date`, converting it to an ISO 8601 string.
     /// The backend will detect the ISO 8601 format and treat it as a date type.
     public static func from(_ value: Date) -> AttributeValue {
-        return .string(ISO8601DateFormatter().string(from: value))
+        return .string(iso8601Formatter.string(from: value))
     }

3-11: Doc comment mentions "date" as a distinct type, but dates are stored as .string.

The documentation says "Represents a user attribute value that can be a string, number, or date" and lists date as a separate category. Since dates are actually encoded as .string values internally, consider clarifying this in the doc to avoid confusion for API consumers expecting a .date case.

Tests/FormbricksSDKTests/FormbricksSDKTests.swift (1)

49-55: Consider adding test coverage for .number() and date attributes.

All test paths only exercise .string(...). The new setNumberAttribute, setDateAttribute, and mixed-type setAttributes APIs introduced in Formbricks.swift have no test coverage here.

Sources/FormbricksSDK/Networking/Queue/UpdateQueue.swift (1)

58-65: set(language:) overwrites all pending attributes.

Line 60 replaces self.attributes with ["language": .string(language)], discarding any attributes queued by prior set(attributes:) or add(attribute:forKey:) calls that haven't been committed yet. This appears to be pre-existing behavior, but worth noting since the new typed-attribute API makes it more likely that callers will mix attribute-setting and language-setting calls in quick succession.

Suggested fix: merge instead of replace
-                self.attributes = ["language": .string(language)]
+                var merged = self.attributes ?? [:]
+                merged["language"] = .string(language)
+                self.attributes = merged

@pandeymangg pandeymangg requested a review from Dhruwang February 16, 2026 08:56
@sonarqubecloud
Copy link

@pandeymangg pandeymangg added this pull request to the merge queue Feb 17, 2026
Merged via the queue into main with commit 6ab0e0a Feb 17, 2026
4 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.

2 participants