Conversation
WalkthroughThis pull request introduces a typed attribute system by creating a new 🚥 Pre-merge checks | ✅ 3 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (3 passed)
✏️ 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. Comment |
There was a problem hiding this comment.
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 theISO8601DateFormatterinstance.
ISO8601DateFormatter()is relatively expensive to create. Iffrom(_ 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
.stringvalues internally, consider clarifying this in the doc to avoid confusion for API consumers expecting a.datecase.Tests/FormbricksSDKTests/FormbricksSDKTests.swift (1)
49-55: Consider adding test coverage for.number()and date attributes.All test paths only exercise
.string(...). The newsetNumberAttribute,setDateAttribute, and mixed-typesetAttributesAPIs introduced inFormbricks.swifthave no test coverage here.Sources/FormbricksSDK/Networking/Queue/UpdateQueue.swift (1)
58-65:set(language:)overwrites all pending attributes.Line 60 replaces
self.attributeswith["language": .string(language)], discarding any attributes queued by priorset(attributes:)oradd(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
|



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