Skip to content

feat: formbricks v5 changes#46

Merged
pandeymangg merged 6 commits into
mainfrom
epic/v5
May 18, 2026
Merged

feat: formbricks v5 changes#46
pandeymangg merged 6 commits into
mainfrom
epic/v5

Conversation

@pandeymangg

Copy link
Copy Markdown
Contributor

Adds the formbricks v5 changes into the main branch through the epic/v5

pandeymangg and others added 5 commits April 23, 2026 17:53
- Getter: fall back to legacy key when new-key blob fails to decode, and
  only migrate/delete legacy after it decodes as WorkspaceResponse so a
  corrupt blob can't poison the new key.
- refreshWorkspaceIfNeeded: schedule startRefreshTimer on the cached-valid
  path so refresh still fires when the cached response later expires.
- FormbricksConfig.workspaceId: expose as @objc public to match the
  deprecated environmentId alias visibility.
- Tests: clear persisted workspace cache keys in setUp/tearDown to avoid
  cross-test leakage (Formbricks.cleanup() intentionally leaves them).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
macos-15 runners no longer ship the iPhone SE (3rd generation) iOS 18.5
simulator runtime, so the pinned destination fails with "no available
devices matched the request". Switch to iPhone 16 with OS=latest so the
runner picks whatever simulator runtime is installed.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Previous run on macos-15 reported zero available iOS Simulator devices
(only placeholders), meaning xcode-select was pointing at an Xcode without
any installed simulator runtimes. Use maxim-lobanov/setup-xcode to pin to
the latest stable Xcode (which ships with simulators), and print the sim
device list so future failures are self-diagnosing.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@pandeymangg pandeymangg requested a review from Dhruwang May 18, 2026 06:04
@coderabbitai

coderabbitai Bot commented May 18, 2026

Copy link
Copy Markdown

Review Change Stack

Walkthrough

This pull request systematically refactors the Formbricks iOS SDK to replace all environmentId-based identifiers and terminology with workspaceId, modernizing the API surface. The change propagates through configuration, data models, service layer, managers, and views while maintaining backward compatibility via deprecated computed properties and legacy decoding fallbacks. Test coverage validates the migration including UserDefaults cache persistence, notification aliasing, and support for multiple server payload key formats. The CI/CD workflow is updated to target iPhone 16 on the latest iOS version for testing.

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 53.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title 'feat: formbricks v5 changes' uses a generic placeholder term 'v5 changes' that doesn't clearly convey the specific primary change (renaming environment to workspace). Consider a more specific title like 'feat: migrate from environmentId to workspaceId' or 'feat: rename environment references to workspace' to better describe the main changeset.
✅ Passed checks (3 passed)
Check name Status Explanation
Description check ✅ Passed The description states the PR adds formbricks v5 changes through epic/v5 branch, which accurately relates to the substantial refactoring that renames environment-based identifiers to workspace-based ones throughout the codebase.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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


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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 6

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
Sources/FormbricksSDK/Model/Workspace/WorkspaceResponse.swift (1)

14-45: 🧹 Nitpick | 🔵 Trivial | 💤 Low value

Consider extracting common JSON parsing logic.

The getSurveyJson, getSurveyStylingJson, and getSettingsStylingJson methods all repeat the same JSON deserialization pattern to reach dataDict. This could be extracted into a private helper for clarity, though the current approach works correctly.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@Sources/FormbricksSDK/Model/Workspace/WorkspaceResponse.swift` around lines
14 - 45, Extract the repeated JSON deserialization into a private helper on
WorkspaceResponse (e.g. a private func like parsedDataDict() -> [String: Any]?)
that performs the guard using responseString, JSONSerialization and returns the
nested dataDict (the value currently assigned to dataDict in
getSurveyJson/getSurveyStylingJson/getSettingsStylingJson). Replace the
duplicated code in getSurveyJson(forSurveyId:),
getSurveyStylingJson(forSurveyId:) and getSettingsStylingJson() to call that
helper and then run only the remaining logic (search surveys array or pull
styling/settings) so the three public methods become thin and de-duplicated.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@Sources/FormbricksSDK/Formbricks.swift`:
- Around line 76-80: The guard block that checks url.scheme (guard
url.scheme?.lowercased() == "https") is indented with 3 spaces whereas the file
uses 4-space indentation; fix the whitespace so the guard, its body (let
errorMessage ... Formbricks.logger?.error(...)) and return lines use 4-space
indentation to match the rest of the file and keep the block aligned with
surrounding code (reference symbols: url.scheme, config.appUrl,
Formbricks.logger?.error).

In `@Sources/FormbricksSDK/Manager/SurveyManager.swift`:
- Around line 254-276: The getter currently returns decoded WorkspaceResponse
without updating the cached backingWorkspaceResponse and the setter may encode a
nil Optional into a JSON null blob; update the SurveyManager computed property
so that on successful decode from UserDefaults (both workspaceResponseObjectKey
and legacyEnvironmentResponseObjectKey) you assign backingWorkspaceResponse =
decoded before returning, and in the setter handle nil explicitly: if newValue
is non-nil encode and write that value and remove the legacy key, otherwise
remove the workspaceResponseObjectKey and legacyEnvironmentResponseObjectKey
from UserDefaults and set backingWorkspaceResponse = nil so persisted data is
cleared instead of writing a JSON null.

In `@Sources/FormbricksSDK/Model/Workspace/WorkspaceResponseData.swift`:
- Around line 1-6: When decoding cached WorkspaceResponse/WorkspaceResponseData
in SurveyManager (the code that calls JSONDecoder().decode(...) for
WorkspaceResponse), switch the decoder to use JSONDecoder.iso8601Full instead of
plain JSONDecoder so the expiresAt: Date field is parsed correctly; locate the
decode call that targets WorkspaceResponse/WorkspaceResponseData and replace the
decoder instance with JSONDecoder.iso8601Full (from JSON+Formatter.swift) so the
ISO8601 date strings decode using the configured dateDecodingStrategy.

In `@Sources/FormbricksSDK/Networking/Base/APIClient.swift`:
- Around line 33-37: The guard block that checks the URL scheme (the lines
starting with "guard let scheme = components.scheme?.lowercased(), scheme ==
\"https\" else {", the Formbricks.logger?.error(...) call, and "return nil")
uses 3-space indentation instead of the file's 4-space convention; update those
lines to use 4-space indentation so they match the surrounding code style and
the rest of the file.
- Around line 81-84: The code currently force-casts back to Request.Response
after mutating a temporary workspace value; replace the force-cast with a safe
conditional cast and explicit cast when assigning back: use the existing
conditional binding (if var workspace = body as? WorkspaceResponse, let
jsonString = ...) then set workspace.responseString = jsonString and assign body
= workspace as Request.Response using an explicit safe cast instead of `as!`;
reference the WorkspaceResponse type, the body variable, its responseString
property, and Request.Response to locate and change the snippet.

In `@Tests/FormbricksSDKTests/FormbricksSDKTests.swift`:
- Around line 233-237: The test currently corrupts the new-key data and removes
the legacy key so it only verifies "new-key decode fails" rather than exercising
the fallback; update the test to write a valid legacy blob into
UserDefaults.standard under SurveyManager.legacyEnvironmentResponseObjectKey
(instead of removing it) so manager.workspaceResponse exercises the fallback
path to the legacy format, or if you intended to only test absence of fallback,
change the comment to match; locate the lines that set/remove UserDefaults for
SurveyManager.workspaceResponseObjectKey and
SurveyManager.legacyEnvironmentResponseObjectKey and replace the removal with
seeding a valid legacy-encoded value that matches the legacy decoding path used
by SurveyManager.

---

Outside diff comments:
In `@Sources/FormbricksSDK/Model/Workspace/WorkspaceResponse.swift`:
- Around line 14-45: Extract the repeated JSON deserialization into a private
helper on WorkspaceResponse (e.g. a private func like parsedDataDict() ->
[String: Any]?) that performs the guard using responseString, JSONSerialization
and returns the nested dataDict (the value currently assigned to dataDict in
getSurveyJson/getSurveyStylingJson/getSettingsStylingJson). Replace the
duplicated code in getSurveyJson(forSurveyId:),
getSurveyStylingJson(forSurveyId:) and getSettingsStylingJson() to call that
helper and then run only the remaining logic (search surveys array or pull
styling/settings) so the three public methods become thin and de-duplicated.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: f58ea161-c92f-48e1-97ef-538ebd5ea526

📥 Commits

Reviewing files that changed from the base of the PR and between 1d561fd and 65332e1.

📒 Files selected for processing (32)
  • .github/workflows/sonarqube.yml
  • Sources/FormbricksSDK/Formbricks.swift
  • Sources/FormbricksSDK/Helpers/ConfigBuilder.swift
  • Sources/FormbricksSDK/Helpers/FormbricksEnvironment.swift
  • Sources/FormbricksSDK/Helpers/FormbricksWorkspace.swift
  • Sources/FormbricksSDK/Manager/PresentSurveyManager.swift
  • Sources/FormbricksSDK/Manager/SurveyManager.swift
  • Sources/FormbricksSDK/Model/Environment/EnvironmentData.swift
  • Sources/FormbricksSDK/Model/Environment/EnvironmentResponseData.swift
  • Sources/FormbricksSDK/Model/Workspace/ActionClass/ActionClass.swift
  • Sources/FormbricksSDK/Model/Workspace/Common/LocalizedText.swift
  • Sources/FormbricksSDK/Model/Workspace/Settings/BrandColor.swift
  • Sources/FormbricksSDK/Model/Workspace/Settings/Settings.swift
  • Sources/FormbricksSDK/Model/Workspace/Settings/Styling.swift
  • Sources/FormbricksSDK/Model/Workspace/Survey.swift
  • Sources/FormbricksSDK/Model/Workspace/Surveys/ActionClassReference.swift
  • Sources/FormbricksSDK/Model/Workspace/Surveys/Segment.swift
  • Sources/FormbricksSDK/Model/Workspace/Surveys/Trigger.swift
  • Sources/FormbricksSDK/Model/Workspace/WorkspaceData.swift
  • Sources/FormbricksSDK/Model/Workspace/WorkspaceResponse.swift
  • Sources/FormbricksSDK/Model/Workspace/WorkspaceResponseData.swift
  • Sources/FormbricksSDK/Networking/Base/APIClient.swift
  • Sources/FormbricksSDK/Networking/ClientAPI/Endpoints/Environment/GetEnvironmentRequest.swift
  • Sources/FormbricksSDK/Networking/ClientAPI/Endpoints/User/PostUserRequest.swift
  • Sources/FormbricksSDK/Networking/ClientAPI/Endpoints/Workspace/GetWorkspaceRequest.swift
  • Sources/FormbricksSDK/Networking/Service/FormbricksService.swift
  • Sources/FormbricksSDK/WebView/FormbricksViewModel.swift
  • Tests/FormbricksSDKTests/FormbricksSDKTests.swift
  • Tests/FormbricksSDKTests/FormbricksWorkspaceTests.swift
  • Tests/FormbricksSDKTests/MockFormbricksService/MockFormbricksService.swift
  • Tests/FormbricksSDKTests/Networking/APIClientTests.swift
  • Tests/FormbricksSDKTests/Networking/ClientAPIEndpointsTests.swift
💤 Files with no reviewable changes (4)
  • Sources/FormbricksSDK/Networking/ClientAPI/Endpoints/Environment/GetEnvironmentRequest.swift
  • Sources/FormbricksSDK/Model/Environment/EnvironmentData.swift
  • Sources/FormbricksSDK/Helpers/FormbricksEnvironment.swift
  • Sources/FormbricksSDK/Model/Environment/EnvironmentResponseData.swift

Comment thread Sources/FormbricksSDK/Formbricks.swift
Comment thread Sources/FormbricksSDK/Manager/SurveyManager.swift
Comment thread Sources/FormbricksSDK/Model/Workspace/WorkspaceResponseData.swift
Comment thread Sources/FormbricksSDK/Networking/Base/APIClient.swift
Comment thread Sources/FormbricksSDK/Networking/Base/APIClient.swift
Comment thread Tests/FormbricksSDKTests/FormbricksSDKTests.swift
@pandeymangg pandeymangg added this pull request to the merge queue May 18, 2026
Merged via the queue into main with commit 7095b15 May 18, 2026
3 checks passed
@sonarqubecloud

Copy link
Copy Markdown

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