Skip to content

chore: sync upstream PR #8527 - fix(ios): adopt UIScene life cycle in default iOS app templates#84

Open
riderx wants to merge 24 commits into
plusfrom
sync/upstream-pr-8527
Open

chore: sync upstream PR #8527 - fix(ios): adopt UIScene life cycle in default iOS app templates#84
riderx wants to merge 24 commits into
plusfrom
sync/upstream-pr-8527

Conversation

@riderx

@riderx riderx commented Jul 11, 2026

Copy link
Copy Markdown
Member

Merge Conflict Resolution Required

The sync of upstream PR ionic-team#8527 from @nilspep encountered merge conflicts.

Original PR: ionic-team#8527

What happened

  • Claude Code attempted to resolve the merge conflicts
  • This PR was created so CI and manual review can finish the sync safely

Synced from upstream by Capacitor+ Bot

Summary by CodeRabbit

  • New Features

    • Added support for retrieving decimal configuration values in Android and iOS plugins.
    • Expanded iOS Swift Package Manager configuration with symlinks and module aliases.
    • Updated iOS app templates with modern scene lifecycle support.
    • Improved Android system bar and safe-area inset handling, including configurable CSS or disabled modes.
  • Bug Fixes

    • Live-reload settings now revert correctly when commands fail.
    • Improved Android photo capture URI permissions.
  • Release

    • Updated packages and release notes to version 8.4.1.

Github Workflow (on behalf of markemer) and others added 24 commits May 7, 2026 16:55
Co-authored-by: jcesarmobile <jcesarmobile@gmail.com>
Co-authored-by: Joey Pender <joey.pender@outsystems.com>
Co-authored-by: Pedro Bilro <pedro.gustavo.bilro@outsystems.com>
Co-authored-by: Mark Anderson <mark.anderson@outsystems.com>
…#8476)

Co-authored-by: jcesarmobile <jcesarmobile@gmail.com>
…am#8492)

Co-authored-by: Mark Anderson <mark.anderson@outsystems.com>
Apple's TN3187 states that starting with the next major iOS release
following iOS 26, apps built with the latest SDK will fail to launch
if they don't adopt the UIScene-based life cycle. Both default iOS
templates (ios-spm-template and ios-pods-template) still use the
pre-scene AppDelegate-only life cycle, so any app scaffolded today via
`npx cap add ios` will fail to launch on that SDK with no crash log
(UIKit logs: "UIScene life cycle is required for apps built with this
SDK") -- the app process starts, immediately shows a black screen,
and returns to the Home Screen.

This adds the minimal, Apple-documented fix to both templates:
- SceneDelegate.swift implementing UIWindowSceneDelegate
- AppDelegate: configurationForConnecting / didDiscardSceneSessions
- Info.plist: UIApplicationSceneManifest, matching Apple's current
  official example verbatim (same keys/config name/delegate class)
- project.pbxproj: register SceneDelegate.swift in the App target

Since the app's root view controller (CAPBridgeViewController) loads
from Main.storyboard, the system auto-configures the scene window from
UISceneStoryboardFile, so no manual window setup is needed in
SceneDelegate.

Verified end-to-end on a real device (rebuilt, installed, and
launched an app using this exact template layout) -- confirmed this
resolves a silent launch failure with zero crash log.

Ref: https://developer.apple.com/documentation/technotes/tn3187-migrating-to-the-uikit-scene-based-life-cycle

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@riderx

riderx commented Jul 11, 2026

Copy link
Copy Markdown
Member Author

Claude Code could not resolve this upstream sync completely. Please review the branch carefully before merging.

@github-actions

Copy link
Copy Markdown

Beta npm build

Maintainers can publish one Capacitor Plus workspace package from this PR to npm for fast testing.

Comment /publish-beta <package> after the PR checks are green.

Examples:

/publish-beta core
/publish-beta cli
/publish-beta @capacitor-plus/core

If exactly one workspace package changed, /publish-beta without a package will use that package.

Packages:

  • core (@capacitor-plus/core)
  • cli (@capacitor-plus/cli)
  • android (@capacitor-plus/android)
  • ios (@capacitor-plus/ios)

The workflow will:

  • publish a prerelease package on the beta tag
  • add a pinned pr-84 dist-tag for the selected package
  • update this comment with the install command

Security note: beta publish is only enabled for branches inside this repository.

@coderabbitai

coderabbitai Bot commented Jul 11, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The release updates package metadata and changelogs for version 8.4.1, extends CLI Swift Package Manager and telemetry handling, changes Android SystemBars configuration and plugin APIs, adds iOS scene lifecycle templates, and increases several CI job timeouts.

Changes

Capacitor 8.4.1 platform and tooling updates

Layer / File(s) Summary
Release metadata and validation
.github/workflows/test.yml, CHANGELOG.md, */CHANGELOG.md, */package.json, lerna.json
Updates package versions and identities, release notes, compare links, and selected CI timeouts.
CLI SPM package options and version alignment
cli/src/declarations.ts, cli/src/ios/update.ts, cli/src/util/spm.ts
Adds per-plugin SPM symlink and module-alias options, rewrites incompatible Swift package constraints, and removes generated SPM symlinks during cleanup.
CLI telemetry and error-path handling
cli/src/telemetry.ts, cli/src/ipc.ts, cli/src/tasks/run.ts, cli/test/telemetry.spec.ts
Adds iOS package-manager telemetry, updates telemetry response handling, tests detection fallbacks, and reverts live-reload configuration after errors.
Android plugin configuration and system bars
android/capacitor/src/main/java/com/getcapacitor/{util,plugin}/*, android/capacitor/src/test/java/com/getcapacitor/plugin/SystemBarsTest.java
Adds double-valued plugin configuration access, introduces CSS/disabled inset handling modes, refactors bar visibility, and tests visibility calls.
Android runtime compatibility cleanup
android/capacitor/src/main/java/com/getcapacitor/{BridgeWebChromeClient.java,FileUtils.java,WebViewLocalServer.java,cordova/MockCordovaWebViewImpl.java,plugin/CapacitorCookieManager.java,plugin/util/HttpRequestHandler.java}, android/package.json
Adds URI permission flags and simplifies equivalent expressions across Android runtime code while updating Android package metadata.
iOS scene lifecycle templates and plugin API
ios-pods-template/App/App/*, ios-spm-template/App/App/*, ios/Capacitor/Capacitor/PluginConfig.swift
Adds UIScene manifests, AppDelegate hooks, SceneDelegate implementations, project wiring, and the iOS getDouble accessor.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant CapacitorConfig
  participant generatePackageText
  participant PackageSwift
  participant updateIOS
  CapacitorConfig->>generatePackageText: packageOptions
  generatePackageText->>PackageSwift: generate symlink and moduleAliases entries
  updateIOS->>PackageSwift: rewrite incompatible version constraint
Loading
sequenceDiagram
  participant InfoPlist
  participant AppDelegate
  participant SceneDelegate
  participant MainStoryboard
  InfoPlist->>AppDelegate: provide Default Configuration
  AppDelegate->>SceneDelegate: connect UIWindowScene
  SceneDelegate->>MainStoryboard: use Main storyboard
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 18.42% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main iOS template change and the upstream sync context of the pull request.
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.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch

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

@cursor cursor 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.

Risk: high. This upstream sync touches iOS templates, Android runtime, and CLI across 37 files and exceeds the low-risk approval threshold. Leaving a non-blocking comment; reviewers assigned for human review.

Open in Web View Automation 

Sent by Cursor Approval Agent: Pull Request Approver External

@cursor cursor 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.

Risk: medium. Cursor Bugbot was not present on this PR, so approval is based on remaining signals only. This multi-platform upstream sync touches iOS templates, Android runtime, and CLI and needs human review before merge. Reviewers assigned.

Open in Web View Automation 

Sent by Cursor Approval Agent: Pull Request Approver

@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: 8

Caution

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

⚠️ Outside diff range comments (1)
cli/src/tasks/run.ts (1)

96-101: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Rollback the Android manifest in the error path. The catch only reverts the live-reload Cap config; it leaves the Android manifest edited by writeCordovaAndroidManifest(..., true) if run() fails after that point. Hoist cordovaPlugins so the catch can call the matching false write too.

🤖 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 `@cli/src/tasks/run.ts` around lines 96 - 101, Hoist the cordovaPlugins
variable outside the try block so it is available to error handling. In run(),
update the catch path to call writeCordovaAndroidManifest(cordovaPlugins,
config, platformName, false) for Android after live-reload setup, alongside
reverting the Cap config, ensuring both edits are rolled back when execution
fails.
🤖 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 `@android/capacitor/src/main/java/com/getcapacitor/plugin/SystemBars.java`:
- Around line 210-211: Extract the duplicated safe-area calculation and
injection sequence into a helper such as
injectSafeAreaCSSFromInsets(WindowInsetsCompat insets) in SystemBars, then
replace both repeated branches with calls to that helper while preserving the
existing inset values and behavior.
- Around line 99-108: Normalize the value read in the SystemBars configuration
logic before comparison, using the same Locale.US-based case normalization
applied to style. Update the configuredInsetsHandling handling so case variants
such as “Disable” and “DISABLE” match INSETS_HANDLING_DISABLE, while preserving
the existing fallback warning and CSS default for unsupported values.

In `@android/capacitor/src/test/java/com/getcapacitor/plugin/SystemBarsTest.java`:
- Around line 22-72: Extend SystemBarsTest coverage to exercise the hide=true
branch in setHidden. Update invokeSetHidden to accept a boolean hide argument,
adjust existing show tests to pass false, and add corresponding tests for empty,
status, and navigation bar values that verify the appropriate controller.hide
call and ensure other bar types are not invoked.

In `@android/CHANGELOG.md`:
- Around line 10-20: Change the 8.4.0 release heading in the changelog from an
h1 to an h2 by using two leading hash characters, keeping the Bug Fixes and
Features subsections unchanged.

In `@CHANGELOG.md`:
- Around line 6-52: Regenerate CHANGELOG.md through the release tooling so the
8.4.1 through 8.3.2 release headers and associated links consistently reference
the Cap-go/capacitor-plus repository instead of mixing in ionic-team/capacitor
URLs.

In `@cli/CHANGELOG.md`:
- Around line 13-22: Change the 8.4.0 release heading in the changelog from an
h1 to an h2 so its “Bug Fixes” and “Features” h3 subsections follow the same
heading hierarchy as other release sections.

In `@cli/src/ios/update.ts`:
- Around line 62-85: Move the single await getCapacitorPackageVersion(config,
config.ios.name) call outside the validSPMPackages.map callback, storing its
result before Promise.all; reuse that iosPlatformVersion for every plugin while
preserving the existing version comparison and update logic.

In `@ios-spm-template/App/App/Info.plist`:
- Around line 27-45: Add an explicit UISceneClassName entry with UIWindowScene
to the application scene configuration alongside UISceneDelegateClassName in
UIApplicationSceneManifest, preserving the existing single-window configuration.

---

Outside diff comments:
In `@cli/src/tasks/run.ts`:
- Around line 96-101: Hoist the cordovaPlugins variable outside the try block so
it is available to error handling. In run(), update the catch path to call
writeCordovaAndroidManifest(cordovaPlugins, config, platformName, false) for
Android after live-reload setup, alongside reverting the Cap config, ensuring
both edits are rolled back when execution fails.
🪄 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: e683360b-e22c-45ad-9fe8-385dc66013db

📥 Commits

Reviewing files that changed from the base of the PR and between 51a1030 and 061c018.

📒 Files selected for processing (37)
  • .github/workflows/test.yml
  • CHANGELOG.md
  • android/CHANGELOG.md
  • android/capacitor/src/main/java/com/getcapacitor/BridgeWebChromeClient.java
  • android/capacitor/src/main/java/com/getcapacitor/FileUtils.java
  • android/capacitor/src/main/java/com/getcapacitor/PluginConfig.java
  • android/capacitor/src/main/java/com/getcapacitor/WebViewLocalServer.java
  • android/capacitor/src/main/java/com/getcapacitor/cordova/MockCordovaWebViewImpl.java
  • android/capacitor/src/main/java/com/getcapacitor/plugin/CapacitorCookieManager.java
  • android/capacitor/src/main/java/com/getcapacitor/plugin/SystemBars.java
  • android/capacitor/src/main/java/com/getcapacitor/plugin/util/HttpRequestHandler.java
  • android/capacitor/src/main/java/com/getcapacitor/util/JSONUtils.java
  • android/capacitor/src/test/java/com/getcapacitor/plugin/SystemBarsTest.java
  • android/package.json
  • cli/CHANGELOG.md
  • cli/package.json
  • cli/src/declarations.ts
  • cli/src/ios/update.ts
  • cli/src/ipc.ts
  • cli/src/tasks/run.ts
  • cli/src/telemetry.ts
  • cli/src/util/spm.ts
  • cli/test/telemetry.spec.ts
  • core/CHANGELOG.md
  • core/package.json
  • ios-pods-template/App/App.xcodeproj/project.pbxproj
  • ios-pods-template/App/App/AppDelegate.swift
  • ios-pods-template/App/App/Info.plist
  • ios-pods-template/App/App/SceneDelegate.swift
  • ios-spm-template/App/App.xcodeproj/project.pbxproj
  • ios-spm-template/App/App/AppDelegate.swift
  • ios-spm-template/App/App/Info.plist
  • ios-spm-template/App/App/SceneDelegate.swift
  • ios/CHANGELOG.md
  • ios/Capacitor/Capacitor/PluginConfig.swift
  • ios/package.json
  • lerna.json
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

  • Cap-go/capacitor-updater (manual)

Comment on lines +99 to 108
String configuredInsetsHandling = getConfig().getString("insetsHandling", INSETS_HANDLING_CSS);
if (INSETS_HANDLING_CSS.equals(configuredInsetsHandling) || INSETS_HANDLING_DISABLE.equals(configuredInsetsHandling)) {
insetsHandling = configuredInsetsHandling;
} else {
Logger.warn(
"SystemBars",
"Unknown insetsHandling value '" + configuredInsetsHandling + "'. Falling back to '" + INSETS_HANDLING_CSS + "'."
);
insetsHandling = INSETS_HANDLING_CSS;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Normalize case before comparing insetsHandling.

Unlike style (normalized via .toUpperCase(Locale.US) at line 96), configuredInsetsHandling is compared case-sensitively. A user who configures "Disable"/"DISABLE" silently gets "css" behavior instead of the intended "disable", with only a log warning as feedback.

🔧 Proposed fix
-        String configuredInsetsHandling = getConfig().getString("insetsHandling", INSETS_HANDLING_CSS);
+        String configuredInsetsHandling = getConfig().getString("insetsHandling", INSETS_HANDLING_CSS).toLowerCase(Locale.US);
         if (INSETS_HANDLING_CSS.equals(configuredInsetsHandling) || INSETS_HANDLING_DISABLE.equals(configuredInsetsHandling)) {
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
String configuredInsetsHandling = getConfig().getString("insetsHandling", INSETS_HANDLING_CSS);
if (INSETS_HANDLING_CSS.equals(configuredInsetsHandling) || INSETS_HANDLING_DISABLE.equals(configuredInsetsHandling)) {
insetsHandling = configuredInsetsHandling;
} else {
Logger.warn(
"SystemBars",
"Unknown insetsHandling value '" + configuredInsetsHandling + "'. Falling back to '" + INSETS_HANDLING_CSS + "'."
);
insetsHandling = INSETS_HANDLING_CSS;
}
String configuredInsetsHandling = getConfig().getString("insetsHandling", INSETS_HANDLING_CSS).toLowerCase(Locale.US);
if (INSETS_HANDLING_CSS.equals(configuredInsetsHandling) || INSETS_HANDLING_DISABLE.equals(configuredInsetsHandling)) {
insetsHandling = configuredInsetsHandling;
} else {
Logger.warn(
"SystemBars",
"Unknown insetsHandling value '" + configuredInsetsHandling + "'. Falling back to '" + INSETS_HANDLING_CSS + "'."
);
insetsHandling = INSETS_HANDLING_CSS;
}
🤖 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 `@android/capacitor/src/main/java/com/getcapacitor/plugin/SystemBars.java`
around lines 99 - 108, Normalize the value read in the SystemBars configuration
logic before comparison, using the same Locale.US-based case normalization
applied to style. Update the configuredInsetsHandling handling so case variants
such as “Disable” and “DISABLE” match INSETS_HANDLING_DISABLE, while preserving
the existing fallback warning and CSS default for unsupported values.

Comment on lines +210 to +211
Insets safeAreaInsets = calcSafeAreaInsets(insets);
injectSafeAreaCSS(safeAreaInsets.top, safeAreaInsets.right, safeAreaInsets.bottom, safeAreaInsets.left);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Optional: extract duplicated safe-area injection into a helper.

Both branches repeat calcSafeAreaInsets(...) followed by injectSafeAreaCSS(...). Consider a small helper (e.g., injectSafeAreaCSSFromInsets(WindowInsetsCompat insets)) to avoid the duplication.

Also applies to: 243-244

🤖 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 `@android/capacitor/src/main/java/com/getcapacitor/plugin/SystemBars.java`
around lines 210 - 211, Extract the duplicated safe-area calculation and
injection sequence into a helper such as
injectSafeAreaCSSFromInsets(WindowInsetsCompat insets) in SystemBars, then
replace both repeated branches with calls to that helper while preserving the
existing inset values and behavior.

Comment on lines +22 to +72
@Test
public void showWithEmptyBarShowsSystemBars() throws Exception {
WindowInsetsControllerCompat controller = invokeSetHidden("");

verify(controller).show(WindowInsetsCompat.Type.systemBars());
verify(controller, never()).show(WindowInsetsCompat.Type.statusBars());
verify(controller, never()).show(WindowInsetsCompat.Type.navigationBars());
}

@Test
public void showWithStatusBarShowsOnlyStatusBars() throws Exception {
WindowInsetsControllerCompat controller = invokeSetHidden("StatusBar");

verify(controller).show(WindowInsetsCompat.Type.statusBars());
verify(controller, never()).show(WindowInsetsCompat.Type.systemBars());
verify(controller, never()).show(WindowInsetsCompat.Type.navigationBars());
}

@Test
public void showWithNavigationBarShowsOnlyNavigationBars() throws Exception {
WindowInsetsControllerCompat controller = invokeSetHidden("NavigationBar");

verify(controller).show(WindowInsetsCompat.Type.navigationBars());
verify(controller, never()).show(WindowInsetsCompat.Type.systemBars());
verify(controller, never()).show(WindowInsetsCompat.Type.statusBars());
}

private WindowInsetsControllerCompat invokeSetHidden(String bar) throws Exception {
SystemBars plugin = new SystemBars();
Bridge bridge = mock(Bridge.class);
AppCompatActivity activity = mock(AppCompatActivity.class);
Window window = mock(Window.class);
View decorView = mock(View.class);
WindowInsetsControllerCompat controller = mock(WindowInsetsControllerCompat.class);

when(bridge.getActivity()).thenReturn(activity);
when(activity.getWindow()).thenReturn(window);
when(window.getDecorView()).thenReturn(decorView);

plugin.setBridge(bridge);

try (MockedStatic<WindowCompat> windowCompat = mockStatic(WindowCompat.class)) {
windowCompat.when(() -> WindowCompat.getInsetsController(window, decorView)).thenReturn(controller);

Method setHidden = SystemBars.class.getDeclaredMethod("setHidden", boolean.class, String.class);
setHidden.setAccessible(true);
setHidden.invoke(plugin, false, bar);
}

return controller;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Missing test coverage for the hide=true branch.

All three tests call setHidden(false, bar), only exercising the "show" side of the refactored branching. The hide=true path (Lines 307-315 in SystemBars.java) added/refactored in this same PR has no corresponding test.

✅ Suggested additional tests
`@Test`
public void hideWithEmptyBarHidesSystemBars() throws Exception {
    WindowInsetsControllerCompat controller = invokeSetHidden(true, "");
    verify(controller).hide(WindowInsetsCompat.Type.systemBars());
}

Consider parameterizing invokeSetHidden with a hide boolean to cover both directions.

🤖 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 `@android/capacitor/src/test/java/com/getcapacitor/plugin/SystemBarsTest.java`
around lines 22 - 72, Extend SystemBarsTest coverage to exercise the hide=true
branch in setHidden. Update invokeSetHidden to accept a boolean hide argument,
adjust existing show tests to pass false, and add corresponding tests for empty,
status, and navigation bar values that verify the appropriate controller.hide
call and ensure other bar types are not invoked.

Comment thread android/CHANGELOG.md
Comment on lines +10 to +20
# [8.4.0](https://github.com/ionic-team/capacitor/compare/8.3.4...8.4.0) (2026-06-02)

### Bug Fixes

* **android:** use proguard-android-optimize for AGP 9 compatibility ([52ceef3](https://github.com/Cap-go/capacitor-plus/commit/52ceef3769544c6cb0cbc83963dcc4552983578b))





## [8.0.7](https://github.com/Cap-go/capacitor-plus/compare/8.0.6...8.0.7) (2026-01-12)

**Note:** Version bump only for package @capacitor-plus/android

- **android:** show only the requested system bar ([#8480](https://github.com/ionic-team/capacitor/issues/8480)) ([4c6c321](https://github.com/ionic-team/capacitor/commit/4c6c3219afb5223211e857457e46283c37eb9424))
- **SystemBars:** make `safe-area-inset-x` available on API <= 34 ([#8424](https://github.com/ionic-team/capacitor/issues/8424)) ([e456de0](https://github.com/ionic-team/capacitor/commit/e456de083e19644f484bec5a5359cb67960ac8bc))
- **SystemBars:** respect `insetsHandling` disable ([#8481](https://github.com/ionic-team/capacitor/issues/8481)) ([d4ad7ff](https://github.com/ionic-team/capacitor/commit/d4ad7ffe39daf66e0cfc63af9028d5c05543bde7))

### Features

- add method getDouble to plugin config ([#7638](https://github.com/ionic-team/capacitor/issues/7638)) ([93c72de](https://github.com/ionic-team/capacitor/commit/93c72de40a2ec4c78b33659250cb08340083088e))

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Fix the 8.4.0 heading level.

Line [10] is an h1, so the h3 subsections at Lines [12] and [18] skip a heading level. Make the release heading an h2, consistent with the other release sections.

Proposed fix
-# [8.4.0](https://github.com/ionic-team/capacitor/compare/8.3.4...8.4.0) (2026-06-02)
+## [8.4.0](https://github.com/ionic-team/capacitor/compare/8.3.4...8.4.0) (2026-06-02)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
# [8.4.0](https://github.com/ionic-team/capacitor/compare/8.3.4...8.4.0) (2026-06-02)
### Bug Fixes
* **android:** use proguard-android-optimize for AGP 9 compatibility ([52ceef3](https://github.com/Cap-go/capacitor-plus/commit/52ceef3769544c6cb0cbc83963dcc4552983578b))
## [8.0.7](https://github.com/Cap-go/capacitor-plus/compare/8.0.6...8.0.7) (2026-01-12)
**Note:** Version bump only for package @capacitor-plus/android
- **android:** show only the requested system bar ([#8480](https://github.com/ionic-team/capacitor/issues/8480)) ([4c6c321](https://github.com/ionic-team/capacitor/commit/4c6c3219afb5223211e857457e46283c37eb9424))
- **SystemBars:** make `safe-area-inset-x` available on API <= 34 ([#8424](https://github.com/ionic-team/capacitor/issues/8424)) ([e456de0](https://github.com/ionic-team/capacitor/commit/e456de083e19644f484bec5a5359cb67960ac8bc))
- **SystemBars:** respect `insetsHandling` disable ([#8481](https://github.com/ionic-team/capacitor/issues/8481)) ([d4ad7ff](https://github.com/ionic-team/capacitor/commit/d4ad7ffe39daf66e0cfc63af9028d5c05543bde7))
### Features
- add method getDouble to plugin config ([#7638](https://github.com/ionic-team/capacitor/issues/7638)) ([93c72de](https://github.com/ionic-team/capacitor/commit/93c72de40a2ec4c78b33659250cb08340083088e))
## [8.4.0](https://github.com/ionic-team/capacitor/compare/8.3.4...8.4.0) (2026-06-02)
### Bug Fixes
- **android:** show only the requested system bar ([`#8480`](https://github.com/ionic-team/capacitor/issues/8480)) ([4c6c321](https://github.com/ionic-team/capacitor/commit/4c6c3219afb5223211e857457e46283c37eb9424))
- **SystemBars:** make `safe-area-inset-x` available on API <= 34 ([`#8424`](https://github.com/ionic-team/capacitor/issues/8424)) ([e456de0](https://github.com/ionic-team/capacitor/commit/e456de083e19644f484bec5a5359cb67960ac8bc))
- **SystemBars:** respect `insetsHandling` disable ([`#8481`](https://github.com/ionic-team/capacitor/issues/8481)) ([d4ad7ff](https://github.com/ionic-team/capacitor/commit/d4ad7ffe39daf66e0cfc63af9028d5c05543bde7))
### Features
- add method getDouble to plugin config ([`#7638`](https://github.com/ionic-team/capacitor/issues/7638)) ([93c72de](https://github.com/ionic-team/capacitor/commit/93c72de40a2ec4c78b33659250cb08340083088e))
🧰 Tools
🪛 markdownlint-cli2 (0.22.1)

[warning] 12-12: Heading levels should only increment by one level at a time
Expected: h2; Actual: h3

(MD001, heading-increment)

🤖 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 `@android/CHANGELOG.md` around lines 10 - 20, Change the 8.4.0 release heading
in the changelog from an h1 to an h2 by using two leading hash characters,
keeping the Bug Fixes and Features subsections unchanged.

Source: Linters/SAST tools

Comment thread CHANGELOG.md
Comment on lines +6 to +52
## [8.4.1](https://github.com/ionic-team/capacitor/compare/8.4.0...8.4.1) (2026-06-19)

### Bug Fixes

- **cli:** make SPM dependency patch work on prereleases ([#8508](https://github.com/ionic-team/capacitor/issues/8508)) ([6048e90](https://github.com/ionic-team/capacitor/commit/6048e90171afa0229a3c25b52a23c377c6bb804c))
- **cli:** patch Capacitor SPM dependency version in plugins ([#8492](https://github.com/ionic-team/capacitor/issues/8492)) ([28bb2c6](https://github.com/ionic-team/capacitor/commit/28bb2c687069dfdd6aa7abc866004a1c6388d103))

# [8.4.0](https://github.com/ionic-team/capacitor/compare/8.3.4...8.4.0) (2026-06-02)

### Bug Fixes

- **android:** show only the requested system bar ([#8480](https://github.com/ionic-team/capacitor/issues/8480)) ([4c6c321](https://github.com/ionic-team/capacitor/commit/4c6c3219afb5223211e857457e46283c37eb9424))
- **cli:** revert live reload config on failure ([#8485](https://github.com/ionic-team/capacitor/issues/8485)) ([1d031a4](https://github.com/ionic-team/capacitor/commit/1d031a4abec2c793079ba8897ad2e40c4cc6c7f9))
- **SystemBars:** make `safe-area-inset-x` available on API <= 34 ([#8424](https://github.com/ionic-team/capacitor/issues/8424)) ([e456de0](https://github.com/ionic-team/capacitor/commit/e456de083e19644f484bec5a5359cb67960ac8bc))
- **SystemBars:** respect `insetsHandling` disable ([#8481](https://github.com/ionic-team/capacitor/issues/8481)) ([d4ad7ff](https://github.com/ionic-team/capacitor/commit/d4ad7ffe39daf66e0cfc63af9028d5c05543bde7))

### Features

- add method getDouble to plugin config ([#7638](https://github.com/ionic-team/capacitor/issues/7638)) ([93c72de](https://github.com/ionic-team/capacitor/commit/93c72de40a2ec4c78b33659250cb08340083088e))
- **cli:** add experimental packageOptions ([#8471](https://github.com/ionic-team/capacitor/issues/8471)) ([258867b](https://github.com/ionic-team/capacitor/commit/258867b7bf37b1837b99b02ec9638e5a6df08d97))
- **cli:** capture ios_package_manager in telemetry ([#8482](https://github.com/ionic-team/capacitor/issues/8482)) ([b4b297a](https://github.com/ionic-team/capacitor/commit/b4b297a52f8732659662d5e5aaeff81c0f7d9835))

## [8.3.4](https://github.com/ionic-team/capacitor/compare/8.3.3...8.3.4) (2026-05-12)

**Note:** Version bump only for package capacitor

## [8.3.3](https://github.com/ionic-team/capacitor/compare/8.3.2...8.3.3) (2026-05-08)

### Bug Fixes

- **cli:** copy plugin files in CocoaPods projects ([#8467](https://github.com/ionic-team/capacitor/issues/8467)) ([b2d7719](https://github.com/ionic-team/capacitor/commit/b2d771926a180e60deea31992d7d4abcd5ca3bc7))

## [8.3.2](https://github.com/ionic-team/capacitor/compare/8.3.1...8.3.2) (2026-05-07)

### Bug Fixes

- **cli:** add cSettings support for compiler flags in generated Package.swift ([#8448](https://github.com/ionic-team/capacitor/issues/8448)) ([0bd0676](https://github.com/ionic-team/capacitor/commit/0bd0676315c5fd77e50312dd7b5bf4990dcbd7d0))
- **cli:** add system framework and weak framework support in SPM Package.swift ([#8447](https://github.com/ionic-team/capacitor/issues/8447)) ([3232f0f](https://github.com/ionic-team/capacitor/commit/3232f0fe1d9811b0b5c500e3dc05cb8a250177f8))
- **cli:** correct Capacitor plugin SPM compat check ([#8440](https://github.com/ionic-team/capacitor/issues/8440)) ([e5ccc45](https://github.com/ionic-team/capacitor/commit/e5ccc451dda27d56bca824ed644bd20fe4d988cb))
- **cli:** generate binaryTarget entries for custom xcframeworks in Package.swift ([#8445](https://github.com/ionic-team/capacitor/issues/8445)) ([1f7e33f](https://github.com/ionic-team/capacitor/commit/1f7e33fca43d183332ec19d22b0d75ef81d8cc6d))
- **cli:** generate resource entries in Package.swift ([#8455](https://github.com/ionic-team/capacitor/issues/8455)) ([790bd27](https://github.com/ionic-team/capacitor/commit/790bd27123497111984227010c3162cec94a108e))
- **cli:** handle Cordova plugins without iOS source files ([#8443](https://github.com/ionic-team/capacitor/issues/8443)) ([0da130e](https://github.com/ionic-team/capacitor/commit/0da130eb7a861bee4e2c35bc0aac53ba9c983fc3))
- **cli:** link plugin dependencies in Package.swift ([#8457](https://github.com/ionic-team/capacitor/issues/8457)) ([b3c769e](https://github.com/ionic-team/capacitor/commit/b3c769e856c826b1174518877cf86ac7ce73bf09))
- **ios:** support Cordova plugins with Package.swift ([#8438](https://github.com/ionic-team/capacitor/issues/8438)) ([139943b](https://github.com/ionic-team/capacitor/commit/139943b0c05fddb2d1ce2d6f468800fddf17b4cf))
- **SystemBars:** avoid extra view padding on API <= 34 ([#8439](https://github.com/ionic-team/capacitor/issues/8439)) ([5b135a7](https://github.com/ionic-team/capacitor/commit/5b135a70217be560e7176c8d5b514cc92ed3e4e4))

## [8.3.1](https://github.com/ionic-team/capacitor/compare/8.3.0...8.3.1) (2026-04-16)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== files =="
git ls-files | rg '(^|/)(CHANGELOG\.md|package\.json|release|changelog|changeset|version|ci|github/workflows|\.github/workflows)($|/)'

echo "== changelog link patterns =="
rg -n "ionic-team/capacitor|Cap-go/capacitor-plus" CHANGELOG.md .github package.json . 2>/dev/null | sed -n '1,220p'

echo "== changelog-related files outline =="
for f in CHANGELOG.md package.json; do
  if [ -f "$f" ]; then
    echo "--- $f ---"
    wc -l "$f"
  fi
done

echo "== package scripts if present =="
python3 - <<'PY'
import json, os
p='package.json'
if os.path.exists(p):
    data=json.load(open(p))
    print(json.dumps(data.get('scripts', {}), indent=2, sort_keys=True))
PY

Repository: Cap-go/capacitor-plus

Length of output: 43463


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== root CHANGELOG top =="
sed -n '1,90p' CHANGELOG.md | cat -n

echo "== ios CHANGELOG top =="
sed -n '1,90p' ios/CHANGELOG.md | cat -n

echo "== release/changelog tooling refs =="
rg -n "conventional|changelog|release|version|compare/" .github package.json lerna.json .releaserc* . 2>/dev/null | sed -n '1,260p'

echo "== repo identity refs =="
rg -n "Cap-go/capacitor-plus|ionic-team/capacitor" README.md ios/README.md package.json ios/package.json .github/workflows/*.yml 2>/dev/null | sed -n '1,220p'

Repository: Cap-go/capacitor-plus

Length of output: 50377


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== root CHANGELOG 50-120 =="
sed -n '50,120p' CHANGELOG.md | cat -n

echo "== build workflow changelog generation =="
sed -n '45,120p' .github/workflows/build.yml | cat -n

echo "== bump_version workflow relevant bits =="
sed -n '45,95p' .github/workflows/bump_version.yml | cat -n

Repository: Cap-go/capacitor-plus

Length of output: 14372


🏁 Script executed:

#!/bin/bash
set -euo pipefail

sed -n '45,120p' .github/workflows/build.yml | cat -n

Repository: Cap-go/capacitor-plus

Length of output: 2935


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== git remote =="
git remote -v

echo "== lerna.json =="
cat lerna.json

echo "== package.json repository fields =="
python3 - <<'PY'
import json
data=json.load(open('package.json'))
for k in ['repository','homepage','bugs','name','version']:
    print(f'{k}: {data.get(k)}')
PY

echo "== root changelog 8.3.1..8.4.1 links only =="
rg -n "## \\[8\\.(3\\.1|3\\.2|3\\.3|3\\.4|4\\.0|4\\.1)\\]|github.com/.*/compare|github.com/.*/issues|github.com/.*/commit" CHANGELOG.md | sed -n '1,120p'

Repository: Cap-go/capacitor-plus

Length of output: 25059


Regenerate CHANGELOG.md through the release tooling (CHANGELOG.md:6-52)

This section mixes ionic-team/capacitor links in the 8.4.1–8.3.2 headers with Cap-go/capacitor-plus links below. Keep the changelog fork-scoped end to end so the release notes point at the same repo throughout.

🧰 Tools
🪛 markdownlint-cli2 (0.22.1)

[warning] 15-15: Heading levels should only increment by one level at a time
Expected: h2; Actual: h3

(MD001, heading-increment)

🤖 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 `@CHANGELOG.md` around lines 6 - 52, Regenerate CHANGELOG.md through the
release tooling so the 8.4.1 through 8.3.2 release headers and associated links
consistently reference the Cap-go/capacitor-plus repository instead of mixing in
ionic-team/capacitor URLs.

Source: Coding guidelines

Comment thread cli/CHANGELOG.md
Comment on lines +13 to +22
# [8.4.0](https://github.com/ionic-team/capacitor/compare/8.3.4...8.4.0) (2026-06-02)

### Bug Fixes

* address follow-up review comments ([8bee786](https://github.com/Cap-go/capacitor-plus/commit/8bee786e2c68ca6c351e88f104b518291c1f81e3))
* **cli:** add cSettings support for compiler flags in generated Package.swift ([#8448](https://github.com/Cap-go/capacitor-plus/issues/8448)) ([0bd0676](https://github.com/Cap-go/capacitor-plus/commit/0bd0676315c5fd77e50312dd7b5bf4990dcbd7d0))
* **cli:** add system framework and weak framework support in SPM Package.swift ([#8447](https://github.com/Cap-go/capacitor-plus/issues/8447)) ([3232f0f](https://github.com/Cap-go/capacitor-plus/commit/3232f0fe1d9811b0b5c500e3dc05cb8a250177f8))
* **cli:** Allow to run update on non macOS ([#8344](https://github.com/Cap-go/capacitor-plus/issues/8344)) ([a441280](https://github.com/Cap-go/capacitor-plus/commit/a441280d7c6b310ca516d6fb2736c09525987774))
* **cli:** check CAPACITOR_COCOAPODS_PATH in determinePackageManager ([#8407](https://github.com/Cap-go/capacitor-plus/issues/8407)) ([acb64ab](https://github.com/Cap-go/capacitor-plus/commit/acb64ab92a37ff53701cde453558e272e2e11eb6))
* **cli:** correct Capacitor plugin SPM compat check ([#8440](https://github.com/Cap-go/capacitor-plus/issues/8440)) ([e5ccc45](https://github.com/Cap-go/capacitor-plus/commit/e5ccc451dda27d56bca824ed644bd20fe4d988cb))
* **cli:** Don't overwrite config.server section with `--live-reload` ([#7528](https://github.com/Cap-go/capacitor-plus/issues/7528)) ([782b9d9](https://github.com/Cap-go/capacitor-plus/commit/782b9d9c26dcf1282b918996becb0224c0baca1d))
* **cli:** generate binaryTarget entries for custom xcframeworks in Package.swift ([#8445](https://github.com/Cap-go/capacitor-plus/issues/8445)) ([1f7e33f](https://github.com/Cap-go/capacitor-plus/commit/1f7e33fca43d183332ec19d22b0d75ef81d8cc6d))
* **cli:** handle Cordova plugins without iOS source files ([#8443](https://github.com/Cap-go/capacitor-plus/issues/8443)) ([0da130e](https://github.com/Cap-go/capacitor-plus/commit/0da130eb7a861bee4e2c35bc0aac53ba9c983fc3))
* **cli:** inline CSS sourcemaps in addition to JS sourcemaps ([#8377](https://github.com/Cap-go/capacitor-plus/issues/8377)) ([69476ab](https://github.com/Cap-go/capacitor-plus/commit/69476ab9c0b47911a14d2482cab53a877a5ae784))
* **cli:** Update tar package ([#8311](https://github.com/Cap-go/capacitor-plus/issues/8311)) ([0969c5c](https://github.com/Cap-go/capacitor-plus/commit/0969c5cd0b16cf23d2489a85a3b8fa1bee2ebf3b))
* **ios:** support Cordova plugins with Package.swift ([#8438](https://github.com/Cap-go/capacitor-plus/issues/8438)) ([139943b](https://github.com/Cap-go/capacitor-plus/commit/139943b0c05fddb2d1ce2d6f468800fddf17b4cf))
* resolve upstream sync conflicts ([75cbb30](https://github.com/Cap-go/capacitor-plus/commit/75cbb3097a7068bcb37313cbe6301628079101ca))
* **SystemBars:** use native safe area insets on Android ([#8384](https://github.com/Cap-go/capacitor-plus/issues/8384)) ([4e99598](https://github.com/Cap-go/capacitor-plus/commit/4e99598a2a57ee97e82be1aaa09492744622fa60))

- **cli:** revert live reload config on failure ([#8485](https://github.com/ionic-team/capacitor/issues/8485)) ([1d031a4](https://github.com/ionic-team/capacitor/commit/1d031a4abec2c793079ba8897ad2e40c4cc6c7f9))

### Features

* **cli:** Add --https option for --live-reload ([#8194](https://github.com/Cap-go/capacitor-plus/issues/8194)) ([5db81e6](https://github.com/Cap-go/capacitor-plus/commit/5db81e68c67652e9d2b29d7ad30629b423d2ad30))
* **cli:** Add packageManager to iOS config ([#8321](https://github.com/Cap-go/capacitor-plus/issues/8321)) ([a125498](https://github.com/Cap-go/capacitor-plus/commit/a1254983bbb9dcb273d93f3c5f639b792e516406))
* **cli:** Experimental config for swift-tools-version in SPM apps ([#8372](https://github.com/Cap-go/capacitor-plus/issues/8372)) ([d2ee84f](https://github.com/Cap-go/capacitor-plus/commit/d2ee84f8186909b142b418c02fc19f79d3c6a6ed))
* **cli:** support SPM package traits in generated Package.swift ([#8351](https://github.com/Cap-go/capacitor-plus/issues/8351)) ([27e6aa8](https://github.com/Cap-go/capacitor-plus/commit/27e6aa89cf22e0b1a6d46710faed9aa8899600b0))


### Reverts

* revert version bump from [#8319](https://github.com/Cap-go/capacitor-plus/issues/8319) and [#8320](https://github.com/Cap-go/capacitor-plus/issues/8320) ([a48ebb6](https://github.com/Cap-go/capacitor-plus/commit/a48ebb622ea4ebe92927bf1756a4d8ac6012884b))





## [8.0.8](https://github.com/Cap-go/capacitor-plus/compare/8.0.7...8.0.8) (2026-04-08)

**Note:** Version bump only for package @capacitor-plus/cli





## [8.0.7](https://github.com/Cap-go/capacitor-plus/compare/8.0.6...8.0.7) (2026-01-12)

**Note:** Version bump only for package @capacitor-plus/cli




- **cli:** add experimental packageOptions ([#8471](https://github.com/ionic-team/capacitor/issues/8471)) ([258867b](https://github.com/ionic-team/capacitor/commit/258867b7bf37b1837b99b02ec9638e5a6df08d97))
- **cli:** capture ios_package_manager in telemetry ([#8482](https://github.com/ionic-team/capacitor/issues/8482)) ([b4b297a](https://github.com/ionic-team/capacitor/commit/b4b297a52f8732659662d5e5aaeff81c0f7d9835))

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Fix the 8.4.0 heading level.

Line [13] is an h1, so the h3 subsections at Lines [15] and [19] skip a heading level. Make the release heading an h2, consistent with the other release sections.

Proposed fix
-# [8.4.0](https://github.com/ionic-team/capacitor/compare/8.3.4...8.4.0) (2026-06-02)
+## [8.4.0](https://github.com/ionic-team/capacitor/compare/8.3.4...8.4.0) (2026-06-02)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
# [8.4.0](https://github.com/ionic-team/capacitor/compare/8.3.4...8.4.0) (2026-06-02)
### Bug Fixes
* address follow-up review comments ([8bee786](https://github.com/Cap-go/capacitor-plus/commit/8bee786e2c68ca6c351e88f104b518291c1f81e3))
* **cli:** add cSettings support for compiler flags in generated Package.swift ([#8448](https://github.com/Cap-go/capacitor-plus/issues/8448)) ([0bd0676](https://github.com/Cap-go/capacitor-plus/commit/0bd0676315c5fd77e50312dd7b5bf4990dcbd7d0))
* **cli:** add system framework and weak framework support in SPM Package.swift ([#8447](https://github.com/Cap-go/capacitor-plus/issues/8447)) ([3232f0f](https://github.com/Cap-go/capacitor-plus/commit/3232f0fe1d9811b0b5c500e3dc05cb8a250177f8))
* **cli:** Allow to run update on non macOS ([#8344](https://github.com/Cap-go/capacitor-plus/issues/8344)) ([a441280](https://github.com/Cap-go/capacitor-plus/commit/a441280d7c6b310ca516d6fb2736c09525987774))
* **cli:** check CAPACITOR_COCOAPODS_PATH in determinePackageManager ([#8407](https://github.com/Cap-go/capacitor-plus/issues/8407)) ([acb64ab](https://github.com/Cap-go/capacitor-plus/commit/acb64ab92a37ff53701cde453558e272e2e11eb6))
* **cli:** correct Capacitor plugin SPM compat check ([#8440](https://github.com/Cap-go/capacitor-plus/issues/8440)) ([e5ccc45](https://github.com/Cap-go/capacitor-plus/commit/e5ccc451dda27d56bca824ed644bd20fe4d988cb))
* **cli:** Don't overwrite config.server section with `--live-reload` ([#7528](https://github.com/Cap-go/capacitor-plus/issues/7528)) ([782b9d9](https://github.com/Cap-go/capacitor-plus/commit/782b9d9c26dcf1282b918996becb0224c0baca1d))
* **cli:** generate binaryTarget entries for custom xcframeworks in Package.swift ([#8445](https://github.com/Cap-go/capacitor-plus/issues/8445)) ([1f7e33f](https://github.com/Cap-go/capacitor-plus/commit/1f7e33fca43d183332ec19d22b0d75ef81d8cc6d))
* **cli:** handle Cordova plugins without iOS source files ([#8443](https://github.com/Cap-go/capacitor-plus/issues/8443)) ([0da130e](https://github.com/Cap-go/capacitor-plus/commit/0da130eb7a861bee4e2c35bc0aac53ba9c983fc3))
* **cli:** inline CSS sourcemaps in addition to JS sourcemaps ([#8377](https://github.com/Cap-go/capacitor-plus/issues/8377)) ([69476ab](https://github.com/Cap-go/capacitor-plus/commit/69476ab9c0b47911a14d2482cab53a877a5ae784))
* **cli:** Update tar package ([#8311](https://github.com/Cap-go/capacitor-plus/issues/8311)) ([0969c5c](https://github.com/Cap-go/capacitor-plus/commit/0969c5cd0b16cf23d2489a85a3b8fa1bee2ebf3b))
* **ios:** support Cordova plugins with Package.swift ([#8438](https://github.com/Cap-go/capacitor-plus/issues/8438)) ([139943b](https://github.com/Cap-go/capacitor-plus/commit/139943b0c05fddb2d1ce2d6f468800fddf17b4cf))
* resolve upstream sync conflicts ([75cbb30](https://github.com/Cap-go/capacitor-plus/commit/75cbb3097a7068bcb37313cbe6301628079101ca))
* **SystemBars:** use native safe area insets on Android ([#8384](https://github.com/Cap-go/capacitor-plus/issues/8384)) ([4e99598](https://github.com/Cap-go/capacitor-plus/commit/4e99598a2a57ee97e82be1aaa09492744622fa60))
- **cli:** revert live reload config on failure ([#8485](https://github.com/ionic-team/capacitor/issues/8485)) ([1d031a4](https://github.com/ionic-team/capacitor/commit/1d031a4abec2c793079ba8897ad2e40c4cc6c7f9))
### Features
* **cli:** Add --https option for --live-reload ([#8194](https://github.com/Cap-go/capacitor-plus/issues/8194)) ([5db81e6](https://github.com/Cap-go/capacitor-plus/commit/5db81e68c67652e9d2b29d7ad30629b423d2ad30))
* **cli:** Add packageManager to iOS config ([#8321](https://github.com/Cap-go/capacitor-plus/issues/8321)) ([a125498](https://github.com/Cap-go/capacitor-plus/commit/a1254983bbb9dcb273d93f3c5f639b792e516406))
* **cli:** Experimental config for swift-tools-version in SPM apps ([#8372](https://github.com/Cap-go/capacitor-plus/issues/8372)) ([d2ee84f](https://github.com/Cap-go/capacitor-plus/commit/d2ee84f8186909b142b418c02fc19f79d3c6a6ed))
* **cli:** support SPM package traits in generated Package.swift ([#8351](https://github.com/Cap-go/capacitor-plus/issues/8351)) ([27e6aa8](https://github.com/Cap-go/capacitor-plus/commit/27e6aa89cf22e0b1a6d46710faed9aa8899600b0))
### Reverts
* revert version bump from [#8319](https://github.com/Cap-go/capacitor-plus/issues/8319) and [#8320](https://github.com/Cap-go/capacitor-plus/issues/8320) ([a48ebb6](https://github.com/Cap-go/capacitor-plus/commit/a48ebb622ea4ebe92927bf1756a4d8ac6012884b))
## [8.0.8](https://github.com/Cap-go/capacitor-plus/compare/8.0.7...8.0.8) (2026-04-08)
**Note:** Version bump only for package @capacitor-plus/cli
## [8.0.7](https://github.com/Cap-go/capacitor-plus/compare/8.0.6...8.0.7) (2026-01-12)
**Note:** Version bump only for package @capacitor-plus/cli
- **cli:** add experimental packageOptions ([#8471](https://github.com/ionic-team/capacitor/issues/8471)) ([258867b](https://github.com/ionic-team/capacitor/commit/258867b7bf37b1837b99b02ec9638e5a6df08d97))
- **cli:** capture ios_package_manager in telemetry ([#8482](https://github.com/ionic-team/capacitor/issues/8482)) ([b4b297a](https://github.com/ionic-team/capacitor/commit/b4b297a52f8732659662d5e5aaeff81c0f7d9835))
## [8.4.0](https://github.com/ionic-team/capacitor/compare/8.3.4...8.4.0) (2026-06-02)
### Bug Fixes
- **cli:** revert live reload config on failure ([`#8485`](https://github.com/ionic-team/capacitor/issues/8485)) ([1d031a4](https://github.com/ionic-team/capacitor/commit/1d031a4abec2c793079ba8897ad2e40c4cc6c7f9))
### Features
- **cli:** add experimental packageOptions ([`#8471`](https://github.com/ionic-team/capacitor/issues/8471)) ([258867b](https://github.com/ionic-team/capacitor/commit/258867b7bf37b1837b99b02ec9638e5a6df08d97))
- **cli:** capture ios_package_manager in telemetry ([`#8482`](https://github.com/ionic-team/capacitor/issues/8482)) ([b4b297a](https://github.com/ionic-team/capacitor/commit/b4b297a52f8732659662d5e5aaeff81c0f7d9835))
🧰 Tools
🪛 markdownlint-cli2 (0.22.1)

[warning] 15-15: Heading levels should only increment by one level at a time
Expected: h2; Actual: h3

(MD001, heading-increment)

🤖 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 `@cli/CHANGELOG.md` around lines 13 - 22, Change the 8.4.0 release heading in
the changelog from an h1 to an h2 so its “Bug Fixes” and “Features” h3
subsections follow the same heading hierarchy as other release sections.

Source: Linters/SAST tools

Comment thread cli/src/ios/update.ts
Comment on lines +62 to +85
await Promise.all(
validSPMPackages.map(async (plugin) => {
const iosPlatformVersion = await getCapacitorPackageVersion(config, config.ios.name);
const packageSwiftPath = join(plugin.rootPath, 'Package.swift');
let content = await readFile(packageSwiftPath, { encoding: 'utf-8' });
const regex = new RegExp(
'url:\\s*"https://github.com/ionic-team/capacitor-swift-pm\\.git",\\s*from:\\s*"([^"]+)"',
);
const version = content.match(regex)?.[1];
const majorCapVersion = major(iosPlatformVersion);
if (version && major(version) != majorCapVersion) {
const preCapVersion = prerelease(iosPlatformVersion);
const forceVersion = preCapVersion ? iosPlatformVersion : `${majorCapVersion}.0.0`;
content = setAllStringIn(
content,
`url: "https://github.com/ionic-team/capacitor-swift-pm.git",`,
`)`,
` from: "${forceVersion}"`,
);
await writeFile(packageSwiftPath, content);
logger.warn(`${plugin.id} is built for Capacitor ${major(version)}, it might cause issues`);
}
}),
);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win

Hoist getCapacitorPackageVersion outside the per-plugin loop.

iosPlatformVersion doesn't depend on plugin, yet it's re-fetched (an async file/package lookup) for every SPM plugin inside validSPMPackages.map(...). With many plugins this is redundant I/O for an identical result.

♻️ Proposed fix
     const validSPMPackages = await checkPluginsForPackageSwift(config, plugins);
+    const iosPlatformVersion = await getCapacitorPackageVersion(config, config.ios.name);
     await Promise.all(
       validSPMPackages.map(async (plugin) => {
-        const iosPlatformVersion = await getCapacitorPackageVersion(config, config.ios.name);
         const packageSwiftPath = join(plugin.rootPath, 'Package.swift');
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
await Promise.all(
validSPMPackages.map(async (plugin) => {
const iosPlatformVersion = await getCapacitorPackageVersion(config, config.ios.name);
const packageSwiftPath = join(plugin.rootPath, 'Package.swift');
let content = await readFile(packageSwiftPath, { encoding: 'utf-8' });
const regex = new RegExp(
'url:\\s*"https://github.com/ionic-team/capacitor-swift-pm\\.git",\\s*from:\\s*"([^"]+)"',
);
const version = content.match(regex)?.[1];
const majorCapVersion = major(iosPlatformVersion);
if (version && major(version) != majorCapVersion) {
const preCapVersion = prerelease(iosPlatformVersion);
const forceVersion = preCapVersion ? iosPlatformVersion : `${majorCapVersion}.0.0`;
content = setAllStringIn(
content,
`url: "https://github.com/ionic-team/capacitor-swift-pm.git",`,
`)`,
` from: "${forceVersion}"`,
);
await writeFile(packageSwiftPath, content);
logger.warn(`${plugin.id} is built for Capacitor ${major(version)}, it might cause issues`);
}
}),
);
const validSPMPackages = await checkPluginsForPackageSwift(config, plugins);
const iosPlatformVersion = await getCapacitorPackageVersion(config, config.ios.name);
await Promise.all(
validSPMPackages.map(async (plugin) => {
const packageSwiftPath = join(plugin.rootPath, 'Package.swift');
let content = await readFile(packageSwiftPath, { encoding: 'utf-8' });
const regex = new RegExp(
'url:\\s*"https://github.com/ionic-team/capacitor-swift-pm\\.git",\\s*from:\\s*"([^"]+)"',
);
const version = content.match(regex)?.[1];
const majorCapVersion = major(iosPlatformVersion);
if (version && major(version) != majorCapVersion) {
const preCapVersion = prerelease(iosPlatformVersion);
const forceVersion = preCapVersion ? iosPlatformVersion : `${majorCapVersion}.0.0`;
content = setAllStringIn(
content,
`url: "https://github.com/ionic-team/capacitor-swift-pm.git",`,
`)`,
` from: "${forceVersion}"`,
);
await writeFile(packageSwiftPath, content);
logger.warn(`${plugin.id} is built for Capacitor ${major(version)}, it might cause issues`);
}
}),
);
🤖 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 `@cli/src/ios/update.ts` around lines 62 - 85, Move the single await
getCapacitorPackageVersion(config, config.ios.name) call outside the
validSPMPackages.map callback, storing its result before Promise.all; reuse that
iosPlatformVersion for every plugin while preserving the existing version
comparison and update logic.

Comment on lines +27 to +45
<key>UIApplicationSceneManifest</key>
<dict>
<key>UIApplicationSupportsMultipleScenes</key>
<false/>
<key>UISceneConfigurations</key>
<dict>
<key>UIWindowSceneSessionRoleApplication</key>
<array>
<dict>
<key>UISceneConfigurationName</key>
<string>Default Configuration</string>
<key>UISceneDelegateClassName</key>
<string>$(PRODUCT_MODULE_NAME).SceneDelegate</string>
<key>UISceneStoryboardFile</key>
<string>Main</string>
</dict>
</array>
</dict>
</dict>

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Consider adding UISceneClassName explicitly.

Apple's default templates and reference implementations for UIApplicationSceneManifest typically include an explicit UISceneClassName (UIWindowScene) entry alongside UISceneDelegateClassName. It defaults to UIWindowScene when omitted, so this shouldn't break anything for a single-window app, but adding it explicitly matches the documented/idiomatic pattern and avoids ambiguity.

📝 Suggested addition
 			<dict>
 					<key>UISceneConfigurationName</key>
 					<string>Default Configuration</string>
+					<key>UISceneClassName</key>
+					<string>UIWindowScene</string>
 					<key>UISceneDelegateClassName</key>
 					<string>$(PRODUCT_MODULE_NAME).SceneDelegate</string>
 					<key>UISceneStoryboardFile</key>
 					<string>Main</string>
 				</dict>
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<key>UIApplicationSceneManifest</key>
<dict>
<key>UIApplicationSupportsMultipleScenes</key>
<false/>
<key>UISceneConfigurations</key>
<dict>
<key>UIWindowSceneSessionRoleApplication</key>
<array>
<dict>
<key>UISceneConfigurationName</key>
<string>Default Configuration</string>
<key>UISceneDelegateClassName</key>
<string>$(PRODUCT_MODULE_NAME).SceneDelegate</string>
<key>UISceneStoryboardFile</key>
<string>Main</string>
</dict>
</array>
</dict>
</dict>
<key>UIApplicationSceneManifest</key>
<dict>
<key>UIApplicationSupportsMultipleScenes</key>
<false/>
<key>UISceneConfigurations</key>
<dict>
<key>UIWindowSceneSessionRoleApplication</key>
<array>
<dict>
<key>UISceneConfigurationName</key>
<string>Default Configuration</string>
<key>UISceneClassName</key>
<string>UIWindowScene</string>
<key>UISceneDelegateClassName</key>
<string>$(PRODUCT_MODULE_NAME).SceneDelegate</string>
<key>UISceneStoryboardFile</key>
<string>Main</string>
</dict>
</array>
</dict>
</dict>
🤖 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 `@ios-spm-template/App/App/Info.plist` around lines 27 - 45, Add an explicit
UISceneClassName entry with UIWindowScene to the application scene configuration
alongside UISceneDelegateClassName in UIApplicationSceneManifest, preserving the
existing single-window configuration.

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.

7 participants