From 23ad7f8a4231a3b78abec32bb67bbd0c415b5011 Mon Sep 17 00:00:00 2001 From: "Github Workflow (on behalf of markemer)" Date: Thu, 7 May 2026 16:55:19 +0000 Subject: [PATCH 01/22] Release 8.3.2 --- CHANGELOG.md | 14 ++++++++++++++ android/CHANGELOG.md | 6 ++++++ android/package.json | 2 +- cli/CHANGELOG.md | 13 +++++++++++++ cli/package.json | 2 +- core/CHANGELOG.md | 4 ++++ core/package.json | 2 +- ios/CHANGELOG.md | 4 ++++ ios/package.json | 2 +- lerna.json | 2 +- 10 files changed, 46 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 95ee704f6..3851a6663 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,20 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [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) ### Bug Fixes diff --git a/android/CHANGELOG.md b/android/CHANGELOG.md index 5812a4832..ca3b6f0ef 100644 --- a/android/CHANGELOG.md +++ b/android/CHANGELOG.md @@ -3,6 +3,12 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [8.3.2](https://github.com/ionic-team/capacitor/compare/8.3.1...8.3.2) (2026-05-07) + +### Bug Fixes + +- **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) ### Bug Fixes diff --git a/android/package.json b/android/package.json index f55229c31..5ecf01e07 100644 --- a/android/package.json +++ b/android/package.json @@ -1,6 +1,6 @@ { "name": "@capacitor/android", - "version": "8.3.1", + "version": "8.3.2", "description": "Capacitor: Cross-platform apps with JavaScript and the web", "homepage": "https://capacitorjs.com", "author": "Ionic Team (https://ionic.io)", diff --git a/cli/CHANGELOG.md b/cli/CHANGELOG.md index ac66f222f..1cc5720a1 100644 --- a/cli/CHANGELOG.md +++ b/cli/CHANGELOG.md @@ -3,6 +3,19 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [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)) + ## [8.3.1](https://github.com/ionic-team/capacitor/compare/8.3.0...8.3.1) (2026-04-16) ### Bug Fixes diff --git a/cli/package.json b/cli/package.json index b9f5d1ccc..abc3774df 100644 --- a/cli/package.json +++ b/cli/package.json @@ -1,6 +1,6 @@ { "name": "@capacitor/cli", - "version": "8.3.1", + "version": "8.3.2", "description": "Capacitor: Cross-platform apps with JavaScript and the web", "homepage": "https://capacitorjs.com", "author": "Ionic Team (https://ionic.io)", diff --git a/core/CHANGELOG.md b/core/CHANGELOG.md index 60a9ca82b..08c8815c3 100644 --- a/core/CHANGELOG.md +++ b/core/CHANGELOG.md @@ -3,6 +3,10 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [8.3.2](https://github.com/ionic-team/capacitor/compare/8.3.1...8.3.2) (2026-05-07) + +**Note:** Version bump only for package @capacitor/core + ## [8.3.1](https://github.com/ionic-team/capacitor/compare/8.3.0...8.3.1) (2026-04-16) **Note:** Version bump only for package @capacitor/core diff --git a/core/package.json b/core/package.json index 54e8c7110..bc3bebc0f 100644 --- a/core/package.json +++ b/core/package.json @@ -1,6 +1,6 @@ { "name": "@capacitor/core", - "version": "8.3.1", + "version": "8.3.2", "description": "Capacitor: Cross-platform apps with JavaScript and the web", "homepage": "https://capacitorjs.com", "author": "Ionic Team (https://ionic.io)", diff --git a/ios/CHANGELOG.md b/ios/CHANGELOG.md index a16975c79..111b642ac 100644 --- a/ios/CHANGELOG.md +++ b/ios/CHANGELOG.md @@ -3,6 +3,10 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [8.3.2](https://github.com/ionic-team/capacitor/compare/8.3.1...8.3.2) (2026-05-07) + +**Note:** Version bump only for package @capacitor/ios + ## [8.3.1](https://github.com/ionic-team/capacitor/compare/8.3.0...8.3.1) (2026-04-16) ### Bug Fixes diff --git a/ios/package.json b/ios/package.json index 4f7200cad..0972ed946 100644 --- a/ios/package.json +++ b/ios/package.json @@ -1,6 +1,6 @@ { "name": "@capacitor/ios", - "version": "8.3.1", + "version": "8.3.2", "description": "Capacitor: Cross-platform apps with JavaScript and the web", "homepage": "https://capacitorjs.com", "author": "Ionic Team (https://ionic.io)", diff --git a/lerna.json b/lerna.json index 5f513f656..d0a1ebc02 100644 --- a/lerna.json +++ b/lerna.json @@ -11,6 +11,6 @@ "tagVersionPrefix": "" } }, - "version": "8.3.1", + "version": "8.3.2", "$schema": "node_modules/lerna/schemas/lerna-schema.json" } From b2d771926a180e60deea31992d7d4abcd5ca3bc7 Mon Sep 17 00:00:00 2001 From: jcesarmobile Date: Fri, 8 May 2026 18:44:22 +0200 Subject: [PATCH 02/22] fix(cli): copy plugin files in CocoaPods projects (#8467) --- cli/src/ios/update.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cli/src/ios/update.ts b/cli/src/ios/update.ts index 9fcd1c718..82ca85a88 100644 --- a/cli/src/ios/update.ts +++ b/cli/src/ios/update.ts @@ -564,7 +564,7 @@ async function copyPluginsNativeFiles(config: Config, cordovaPlugins: Plugin[]) const isSPM = (await config.ios.packageManager) === 'SPM'; for (const p of cordovaPlugins) { const platformTag = getPluginPlatform(p, platform); - if (platformTag.$?.package) { + if (isSPM && platformTag.$?.package) { continue; } const sourceFiles = getPlatformElement(p, platform, 'source-file'); From 76ff70e0e40bbbca63c5195c572f166e5ce82089 Mon Sep 17 00:00:00 2001 From: "Github Workflow (on behalf of markemer)" Date: Fri, 8 May 2026 17:08:40 +0000 Subject: [PATCH 03/22] Release 8.3.3 --- CHANGELOG.md | 6 ++++++ android/CHANGELOG.md | 4 ++++ android/package.json | 2 +- cli/CHANGELOG.md | 6 ++++++ cli/package.json | 2 +- core/CHANGELOG.md | 4 ++++ core/package.json | 2 +- ios/CHANGELOG.md | 4 ++++ ios/package.json | 2 +- lerna.json | 2 +- 10 files changed, 29 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3851a6663..d4ad41ff2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,12 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [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 diff --git a/android/CHANGELOG.md b/android/CHANGELOG.md index ca3b6f0ef..d4b2fc534 100644 --- a/android/CHANGELOG.md +++ b/android/CHANGELOG.md @@ -3,6 +3,10 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [8.3.3](https://github.com/ionic-team/capacitor/compare/8.3.2...8.3.3) (2026-05-08) + +**Note:** Version bump only for package @capacitor/android + ## [8.3.2](https://github.com/ionic-team/capacitor/compare/8.3.1...8.3.2) (2026-05-07) ### Bug Fixes diff --git a/android/package.json b/android/package.json index 5ecf01e07..07db8a26e 100644 --- a/android/package.json +++ b/android/package.json @@ -1,6 +1,6 @@ { "name": "@capacitor/android", - "version": "8.3.2", + "version": "8.3.3", "description": "Capacitor: Cross-platform apps with JavaScript and the web", "homepage": "https://capacitorjs.com", "author": "Ionic Team (https://ionic.io)", diff --git a/cli/CHANGELOG.md b/cli/CHANGELOG.md index 1cc5720a1..452ba4cc6 100644 --- a/cli/CHANGELOG.md +++ b/cli/CHANGELOG.md @@ -3,6 +3,12 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [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 diff --git a/cli/package.json b/cli/package.json index abc3774df..cd17f5d2f 100644 --- a/cli/package.json +++ b/cli/package.json @@ -1,6 +1,6 @@ { "name": "@capacitor/cli", - "version": "8.3.2", + "version": "8.3.3", "description": "Capacitor: Cross-platform apps with JavaScript and the web", "homepage": "https://capacitorjs.com", "author": "Ionic Team (https://ionic.io)", diff --git a/core/CHANGELOG.md b/core/CHANGELOG.md index 08c8815c3..26f5723fe 100644 --- a/core/CHANGELOG.md +++ b/core/CHANGELOG.md @@ -3,6 +3,10 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [8.3.3](https://github.com/ionic-team/capacitor/compare/8.3.2...8.3.3) (2026-05-08) + +**Note:** Version bump only for package @capacitor/core + ## [8.3.2](https://github.com/ionic-team/capacitor/compare/8.3.1...8.3.2) (2026-05-07) **Note:** Version bump only for package @capacitor/core diff --git a/core/package.json b/core/package.json index bc3bebc0f..373249f98 100644 --- a/core/package.json +++ b/core/package.json @@ -1,6 +1,6 @@ { "name": "@capacitor/core", - "version": "8.3.2", + "version": "8.3.3", "description": "Capacitor: Cross-platform apps with JavaScript and the web", "homepage": "https://capacitorjs.com", "author": "Ionic Team (https://ionic.io)", diff --git a/ios/CHANGELOG.md b/ios/CHANGELOG.md index 111b642ac..b9b7863b0 100644 --- a/ios/CHANGELOG.md +++ b/ios/CHANGELOG.md @@ -3,6 +3,10 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [8.3.3](https://github.com/ionic-team/capacitor/compare/8.3.2...8.3.3) (2026-05-08) + +**Note:** Version bump only for package @capacitor/ios + ## [8.3.2](https://github.com/ionic-team/capacitor/compare/8.3.1...8.3.2) (2026-05-07) **Note:** Version bump only for package @capacitor/ios diff --git a/ios/package.json b/ios/package.json index 0972ed946..bd4c0a320 100644 --- a/ios/package.json +++ b/ios/package.json @@ -1,6 +1,6 @@ { "name": "@capacitor/ios", - "version": "8.3.2", + "version": "8.3.3", "description": "Capacitor: Cross-platform apps with JavaScript and the web", "homepage": "https://capacitorjs.com", "author": "Ionic Team (https://ionic.io)", diff --git a/lerna.json b/lerna.json index d0a1ebc02..d64bfcd44 100644 --- a/lerna.json +++ b/lerna.json @@ -11,6 +11,6 @@ "tagVersionPrefix": "" } }, - "version": "8.3.2", + "version": "8.3.3", "$schema": "node_modules/lerna/schemas/lerna-schema.json" } From b7e167bbab47c57a5f72ff9e76a726ab7d8a1c1f Mon Sep 17 00:00:00 2001 From: "Alex J." Date: Tue, 12 May 2026 15:19:58 -0400 Subject: [PATCH 04/22] chore(cli): update telemetry endpoint (#8464) --- cli/src/ipc.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cli/src/ipc.ts b/cli/src/ipc.ts index 41894e53a..37c38110b 100644 --- a/cli/src/ipc.ts +++ b/cli/src/ipc.ts @@ -49,9 +49,9 @@ export async function receive(msg: IPCMessage): Promise { // This request is only made if telemetry is on. const req = request( { - hostname: 'api.ionicjs.com', + hostname: 'metrics-capacitor.outsystems.com', port: 443, - path: '/events/metrics', + path: '/metrics', method: 'POST', headers: { 'Content-Type': 'application/json', @@ -60,7 +60,7 @@ export async function receive(msg: IPCMessage): Promise { (response) => { debug('Sent %O metric to events service (status: %O)', data.name, response.statusCode); - if (response.statusCode !== 204) { + if (response.statusCode !== 202) { response.on('data', (chunk) => { debug('Bad response from events service. Request body: %O', chunk.toString()); }); From de1e506e48204f3d9a51bc911fafc341fd81fc36 Mon Sep 17 00:00:00 2001 From: "Github Workflow (on behalf of alexgerardojacinto)" Date: Tue, 12 May 2026 20:38:58 +0000 Subject: [PATCH 05/22] Release 8.3.4 --- CHANGELOG.md | 4 ++++ android/CHANGELOG.md | 4 ++++ android/package.json | 2 +- cli/CHANGELOG.md | 4 ++++ cli/package.json | 2 +- core/CHANGELOG.md | 4 ++++ core/package.json | 2 +- ios/CHANGELOG.md | 4 ++++ ios/package.json | 2 +- lerna.json | 2 +- 10 files changed, 25 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d4ad41ff2..a7f2b7713 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,10 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [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 diff --git a/android/CHANGELOG.md b/android/CHANGELOG.md index d4b2fc534..74d538d9f 100644 --- a/android/CHANGELOG.md +++ b/android/CHANGELOG.md @@ -3,6 +3,10 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [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/android + ## [8.3.3](https://github.com/ionic-team/capacitor/compare/8.3.2...8.3.3) (2026-05-08) **Note:** Version bump only for package @capacitor/android diff --git a/android/package.json b/android/package.json index 07db8a26e..8ae93f3f2 100644 --- a/android/package.json +++ b/android/package.json @@ -1,6 +1,6 @@ { "name": "@capacitor/android", - "version": "8.3.3", + "version": "8.3.4", "description": "Capacitor: Cross-platform apps with JavaScript and the web", "homepage": "https://capacitorjs.com", "author": "Ionic Team (https://ionic.io)", diff --git a/cli/CHANGELOG.md b/cli/CHANGELOG.md index 452ba4cc6..bba24688f 100644 --- a/cli/CHANGELOG.md +++ b/cli/CHANGELOG.md @@ -3,6 +3,10 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [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/cli + ## [8.3.3](https://github.com/ionic-team/capacitor/compare/8.3.2...8.3.3) (2026-05-08) ### Bug Fixes diff --git a/cli/package.json b/cli/package.json index cd17f5d2f..9df346b14 100644 --- a/cli/package.json +++ b/cli/package.json @@ -1,6 +1,6 @@ { "name": "@capacitor/cli", - "version": "8.3.3", + "version": "8.3.4", "description": "Capacitor: Cross-platform apps with JavaScript and the web", "homepage": "https://capacitorjs.com", "author": "Ionic Team (https://ionic.io)", diff --git a/core/CHANGELOG.md b/core/CHANGELOG.md index 26f5723fe..017293794 100644 --- a/core/CHANGELOG.md +++ b/core/CHANGELOG.md @@ -3,6 +3,10 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [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/core + ## [8.3.3](https://github.com/ionic-team/capacitor/compare/8.3.2...8.3.3) (2026-05-08) **Note:** Version bump only for package @capacitor/core diff --git a/core/package.json b/core/package.json index 373249f98..eef113a50 100644 --- a/core/package.json +++ b/core/package.json @@ -1,6 +1,6 @@ { "name": "@capacitor/core", - "version": "8.3.3", + "version": "8.3.4", "description": "Capacitor: Cross-platform apps with JavaScript and the web", "homepage": "https://capacitorjs.com", "author": "Ionic Team (https://ionic.io)", diff --git a/ios/CHANGELOG.md b/ios/CHANGELOG.md index b9b7863b0..87ee73bb4 100644 --- a/ios/CHANGELOG.md +++ b/ios/CHANGELOG.md @@ -3,6 +3,10 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [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/ios + ## [8.3.3](https://github.com/ionic-team/capacitor/compare/8.3.2...8.3.3) (2026-05-08) **Note:** Version bump only for package @capacitor/ios diff --git a/ios/package.json b/ios/package.json index bd4c0a320..a7b8d3133 100644 --- a/ios/package.json +++ b/ios/package.json @@ -1,6 +1,6 @@ { "name": "@capacitor/ios", - "version": "8.3.3", + "version": "8.3.4", "description": "Capacitor: Cross-platform apps with JavaScript and the web", "homepage": "https://capacitorjs.com", "author": "Ionic Team (https://ionic.io)", diff --git a/lerna.json b/lerna.json index d64bfcd44..1e53d6bdc 100644 --- a/lerna.json +++ b/lerna.json @@ -11,6 +11,6 @@ "tagVersionPrefix": "" } }, - "version": "8.3.3", + "version": "8.3.4", "$schema": "node_modules/lerna/schemas/lerna-schema.json" } From 731a82e554d9c1270241897228e934c38759bbbb Mon Sep 17 00:00:00 2001 From: jcesarmobile Date: Thu, 21 May 2026 17:39:31 +0200 Subject: [PATCH 06/22] chore: format java code (#8475) --- .../com/getcapacitor/BridgeWebChromeClient.java | 12 ++++++------ .../src/main/java/com/getcapacitor/FileUtils.java | 6 +++--- .../src/main/java/com/getcapacitor/Plugin.java | 4 ++-- .../cordova/MockCordovaWebViewImpl.java | 14 ++++++-------- .../com/getcapacitor/plugin/CapacitorHttp.java | 4 ++-- .../java/com/getcapacitor/ConfigBuildingTest.java | 6 +++--- 6 files changed, 22 insertions(+), 24 deletions(-) diff --git a/android/capacitor/src/main/java/com/getcapacitor/BridgeWebChromeClient.java b/android/capacitor/src/main/java/com/getcapacitor/BridgeWebChromeClient.java index 6ca1c8a83..58371a9ff 100644 --- a/android/capacitor/src/main/java/com/getcapacitor/BridgeWebChromeClient.java +++ b/android/capacitor/src/main/java/com/getcapacitor/BridgeWebChromeClient.java @@ -246,14 +246,14 @@ public boolean onJsPrompt(WebView view, String url, String message, String defau public void onGeolocationPermissionsShowPrompt(String origin, GeolocationPermissions.Callback callback) { super.onGeolocationPermissionsShowPrompt(origin, callback); Logger.debug("onGeolocationPermissionsShowPrompt: DOING IT HERE FOR ORIGIN: " + origin); - final String[] geoPermissions = { Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION }; + final String[] geoPermissions = {Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION}; if (!PermissionHelper.hasPermissions(bridge.getContext(), geoPermissions)) { permissionListener = (isGranted) -> { if (isGranted) { callback.invoke(origin, true, false); } else { - final String[] coarsePermission = { Manifest.permission.ACCESS_COARSE_LOCATION }; + final String[] coarsePermission = {Manifest.permission.ACCESS_COARSE_LOCATION}; if ( Build.VERSION.SDK_INT >= Build.VERSION_CODES.S && PermissionHelper.hasPermissions(bridge.getContext(), coarsePermission) @@ -294,7 +294,7 @@ public boolean onShowFileChooser( filePathCallback.onReceiveValue(null); } }; - final String[] camPermission = { Manifest.permission.CAMERA }; + final String[] camPermission = {Manifest.permission.CAMERA}; permissionLauncher.launch(camPermission); } } else { @@ -305,7 +305,7 @@ public boolean onShowFileChooser( } private boolean isMediaCaptureSupported() { - String[] permissions = { Manifest.permission.CAMERA }; + String[] permissions = {Manifest.permission.CAMERA}; return ( PermissionHelper.hasPermissions(bridge.getContext(), permissions) || !PermissionHelper.hasDefinedPermission(bridge.getContext(), Manifest.permission.CAMERA) @@ -343,7 +343,7 @@ private boolean showImageCapturePicker(final ValueCallback filePathCallba activityListener = (activityResult) -> { Uri[] result = null; if (activityResult.getResultCode() == Activity.RESULT_OK) { - result = new Uri[] { imageFileUri }; + result = new Uri[] {imageFileUri}; } filePathCallback.onReceiveValue(result); }; @@ -362,7 +362,7 @@ private boolean showVideoCapturePicker(final ValueCallback filePathCallba activityListener = (activityResult) -> { Uri[] result = null; if (activityResult.getResultCode() == Activity.RESULT_OK) { - result = new Uri[] { activityResult.getData().getData() }; + result = new Uri[] {activityResult.getData().getData()}; } filePathCallback.onReceiveValue(result); }; diff --git a/android/capacitor/src/main/java/com/getcapacitor/FileUtils.java b/android/capacitor/src/main/java/com/getcapacitor/FileUtils.java index ce09e7c2f..0fdf64feb 100644 --- a/android/capacitor/src/main/java/com/getcapacitor/FileUtils.java +++ b/android/capacitor/src/main/java/com/getcapacitor/FileUtils.java @@ -118,7 +118,7 @@ else if (isMediaDocument(uri)) { } final String selection = "_id=?"; - final String[] selectionArgs = new String[] { split[1] }; + final String[] selectionArgs = new String[] {split[1]}; return getDataColumn(context, contentUri, selection, selectionArgs); } @@ -195,7 +195,7 @@ private static String getDataColumn(Context context, Uri uri, String selection, String path = null; Cursor cursor = null; final String column = "_data"; - final String[] projection = { column }; + final String[] projection = {column}; try { cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, null); @@ -292,7 +292,7 @@ private static String getPathToNonPrimaryVolume(Context context, String tag) { } private static String sanitizeFilename(String displayName) { - String[] badCharacters = new String[] { "..", "/" }; + String[] badCharacters = new String[] {"..", "/"}; String[] segments = displayName.split("/"); String fileName = segments[segments.length - 1]; for (String suspString : badCharacters) { diff --git a/android/capacitor/src/main/java/com/getcapacitor/Plugin.java b/android/capacitor/src/main/java/com/getcapacitor/Plugin.java index 19c8b8b3a..e55d933cc 100644 --- a/android/capacitor/src/main/java/com/getcapacitor/Plugin.java +++ b/android/capacitor/src/main/java/com/getcapacitor/Plugin.java @@ -465,7 +465,7 @@ protected void requestAllPermissions(@NonNull PluginCall call, @NonNull String c * @param callbackName the name of the callback to run when the permission request is complete */ protected void requestPermissionForAlias(@NonNull String alias, @NonNull PluginCall call, @NonNull String callbackName) { - requestPermissionForAliases(new String[] { alias }, call, callbackName); + requestPermissionForAliases(new String[] {alias}, call, callbackName); } /** @@ -583,7 +583,7 @@ public void pluginRequestAllPermissions() { */ @Deprecated public void pluginRequestPermission(String permission, int requestCode) { - ActivityCompat.requestPermissions(getActivity(), new String[] { permission }, requestCode); + ActivityCompat.requestPermissions(getActivity(), new String[] {permission}, requestCode); } /** diff --git a/android/capacitor/src/main/java/com/getcapacitor/cordova/MockCordovaWebViewImpl.java b/android/capacitor/src/main/java/com/getcapacitor/cordova/MockCordovaWebViewImpl.java index 1115429d7..020c1457a 100644 --- a/android/capacitor/src/main/java/com/getcapacitor/cordova/MockCordovaWebViewImpl.java +++ b/android/capacitor/src/main/java/com/getcapacitor/cordova/MockCordovaWebViewImpl.java @@ -70,14 +70,12 @@ public CapacitorEvalBridgeMode(WebView webView, CordovaInterface cordova) { @Override public void onNativeToJsMessageAvailable(final NativeToJsMessageQueue queue) { - cordova - .getActivity() - .runOnUiThread(() -> { - String js = queue.popAndEncodeAsJs(); - if (js != null) { - webView.evaluateJavascript(js, null); - } - }); + cordova.getActivity().runOnUiThread(() -> { + String js = queue.popAndEncodeAsJs(); + if (js != null) { + webView.evaluateJavascript(js, null); + } + }); } } diff --git a/android/capacitor/src/main/java/com/getcapacitor/plugin/CapacitorHttp.java b/android/capacitor/src/main/java/com/getcapacitor/plugin/CapacitorHttp.java index 46bc17417..7d5ab337e 100644 --- a/android/capacitor/src/main/java/com/getcapacitor/plugin/CapacitorHttp.java +++ b/android/capacitor/src/main/java/com/getcapacitor/plugin/CapacitorHttp.java @@ -18,8 +18,8 @@ @CapacitorPlugin( permissions = { - @Permission(strings = { Manifest.permission.WRITE_EXTERNAL_STORAGE }, alias = "HttpWrite"), - @Permission(strings = { Manifest.permission.READ_EXTERNAL_STORAGE }, alias = "HttpRead") + @Permission(strings = {Manifest.permission.WRITE_EXTERNAL_STORAGE}, alias = "HttpWrite"), + @Permission(strings = {Manifest.permission.READ_EXTERNAL_STORAGE}, alias = "HttpRead") } ) public class CapacitorHttp extends Plugin { diff --git a/android/capacitor/src/test/java/com/getcapacitor/ConfigBuildingTest.java b/android/capacitor/src/test/java/com/getcapacitor/ConfigBuildingTest.java index 1af51039d..ae12edb02 100644 --- a/android/capacitor/src/test/java/com/getcapacitor/ConfigBuildingTest.java +++ b/android/capacitor/src/test/java/com/getcapacitor/ConfigBuildingTest.java @@ -42,7 +42,7 @@ public void setup() { config = new CapConfig.Builder(context) .setAllowMixedContent(true) - .setAllowNavigation(new String[] { "http://www.google.com" }) + .setAllowNavigation(new String[] {"http://www.google.com"}) .setAndroidScheme("test") .setCaptureInput(true) .setLoggingEnabled(true) @@ -64,7 +64,7 @@ public void setup() { @Test public void getCoreConfigValues() { assertTrue(config.isMixedContentAllowed()); - assertArrayEquals(new String[] { "http://www.google.com" }, config.getAllowNavigation()); + assertArrayEquals(new String[] {"http://www.google.com"}, config.getAllowNavigation()); assertEquals("test", config.getAndroidScheme()); assertTrue(config.isInputCaptured()); assertTrue(config.isLoggingEnabled()); @@ -97,7 +97,7 @@ public void getPluginInt() { @Test public void getPluginArray() { - String[] comparison = new String[] { "5", "6", "7", "8" }; + String[] comparison = new String[] {"5", "6", "7", "8"}; String[] testArray = config.getPluginConfiguration(TEST_PLUGIN_NAME).getArray("var5"); assertArrayEquals(comparison, testArray); } From bc745364129853769ca2fcfc3cc2a6c7624ee513 Mon Sep 17 00:00:00 2001 From: jcesarmobile Date: Thu, 21 May 2026 18:04:37 +0200 Subject: [PATCH 07/22] chore: format java code (#8477) --- .../java/com/getcapacitor/BridgeWebChromeClient.java | 12 ++++++------ .../src/main/java/com/getcapacitor/FileUtils.java | 6 +++--- .../src/main/java/com/getcapacitor/Plugin.java | 4 ++-- .../java/com/getcapacitor/plugin/CapacitorHttp.java | 4 ++-- .../java/com/getcapacitor/ConfigBuildingTest.java | 6 +++--- 5 files changed, 16 insertions(+), 16 deletions(-) diff --git a/android/capacitor/src/main/java/com/getcapacitor/BridgeWebChromeClient.java b/android/capacitor/src/main/java/com/getcapacitor/BridgeWebChromeClient.java index 58371a9ff..6ca1c8a83 100644 --- a/android/capacitor/src/main/java/com/getcapacitor/BridgeWebChromeClient.java +++ b/android/capacitor/src/main/java/com/getcapacitor/BridgeWebChromeClient.java @@ -246,14 +246,14 @@ public boolean onJsPrompt(WebView view, String url, String message, String defau public void onGeolocationPermissionsShowPrompt(String origin, GeolocationPermissions.Callback callback) { super.onGeolocationPermissionsShowPrompt(origin, callback); Logger.debug("onGeolocationPermissionsShowPrompt: DOING IT HERE FOR ORIGIN: " + origin); - final String[] geoPermissions = {Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION}; + final String[] geoPermissions = { Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION }; if (!PermissionHelper.hasPermissions(bridge.getContext(), geoPermissions)) { permissionListener = (isGranted) -> { if (isGranted) { callback.invoke(origin, true, false); } else { - final String[] coarsePermission = {Manifest.permission.ACCESS_COARSE_LOCATION}; + final String[] coarsePermission = { Manifest.permission.ACCESS_COARSE_LOCATION }; if ( Build.VERSION.SDK_INT >= Build.VERSION_CODES.S && PermissionHelper.hasPermissions(bridge.getContext(), coarsePermission) @@ -294,7 +294,7 @@ public boolean onShowFileChooser( filePathCallback.onReceiveValue(null); } }; - final String[] camPermission = {Manifest.permission.CAMERA}; + final String[] camPermission = { Manifest.permission.CAMERA }; permissionLauncher.launch(camPermission); } } else { @@ -305,7 +305,7 @@ public boolean onShowFileChooser( } private boolean isMediaCaptureSupported() { - String[] permissions = {Manifest.permission.CAMERA}; + String[] permissions = { Manifest.permission.CAMERA }; return ( PermissionHelper.hasPermissions(bridge.getContext(), permissions) || !PermissionHelper.hasDefinedPermission(bridge.getContext(), Manifest.permission.CAMERA) @@ -343,7 +343,7 @@ private boolean showImageCapturePicker(final ValueCallback filePathCallba activityListener = (activityResult) -> { Uri[] result = null; if (activityResult.getResultCode() == Activity.RESULT_OK) { - result = new Uri[] {imageFileUri}; + result = new Uri[] { imageFileUri }; } filePathCallback.onReceiveValue(result); }; @@ -362,7 +362,7 @@ private boolean showVideoCapturePicker(final ValueCallback filePathCallba activityListener = (activityResult) -> { Uri[] result = null; if (activityResult.getResultCode() == Activity.RESULT_OK) { - result = new Uri[] {activityResult.getData().getData()}; + result = new Uri[] { activityResult.getData().getData() }; } filePathCallback.onReceiveValue(result); }; diff --git a/android/capacitor/src/main/java/com/getcapacitor/FileUtils.java b/android/capacitor/src/main/java/com/getcapacitor/FileUtils.java index 0fdf64feb..ce09e7c2f 100644 --- a/android/capacitor/src/main/java/com/getcapacitor/FileUtils.java +++ b/android/capacitor/src/main/java/com/getcapacitor/FileUtils.java @@ -118,7 +118,7 @@ else if (isMediaDocument(uri)) { } final String selection = "_id=?"; - final String[] selectionArgs = new String[] {split[1]}; + final String[] selectionArgs = new String[] { split[1] }; return getDataColumn(context, contentUri, selection, selectionArgs); } @@ -195,7 +195,7 @@ private static String getDataColumn(Context context, Uri uri, String selection, String path = null; Cursor cursor = null; final String column = "_data"; - final String[] projection = {column}; + final String[] projection = { column }; try { cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, null); @@ -292,7 +292,7 @@ private static String getPathToNonPrimaryVolume(Context context, String tag) { } private static String sanitizeFilename(String displayName) { - String[] badCharacters = new String[] {"..", "/"}; + String[] badCharacters = new String[] { "..", "/" }; String[] segments = displayName.split("/"); String fileName = segments[segments.length - 1]; for (String suspString : badCharacters) { diff --git a/android/capacitor/src/main/java/com/getcapacitor/Plugin.java b/android/capacitor/src/main/java/com/getcapacitor/Plugin.java index e55d933cc..19c8b8b3a 100644 --- a/android/capacitor/src/main/java/com/getcapacitor/Plugin.java +++ b/android/capacitor/src/main/java/com/getcapacitor/Plugin.java @@ -465,7 +465,7 @@ protected void requestAllPermissions(@NonNull PluginCall call, @NonNull String c * @param callbackName the name of the callback to run when the permission request is complete */ protected void requestPermissionForAlias(@NonNull String alias, @NonNull PluginCall call, @NonNull String callbackName) { - requestPermissionForAliases(new String[] {alias}, call, callbackName); + requestPermissionForAliases(new String[] { alias }, call, callbackName); } /** @@ -583,7 +583,7 @@ public void pluginRequestAllPermissions() { */ @Deprecated public void pluginRequestPermission(String permission, int requestCode) { - ActivityCompat.requestPermissions(getActivity(), new String[] {permission}, requestCode); + ActivityCompat.requestPermissions(getActivity(), new String[] { permission }, requestCode); } /** diff --git a/android/capacitor/src/main/java/com/getcapacitor/plugin/CapacitorHttp.java b/android/capacitor/src/main/java/com/getcapacitor/plugin/CapacitorHttp.java index 7d5ab337e..46bc17417 100644 --- a/android/capacitor/src/main/java/com/getcapacitor/plugin/CapacitorHttp.java +++ b/android/capacitor/src/main/java/com/getcapacitor/plugin/CapacitorHttp.java @@ -18,8 +18,8 @@ @CapacitorPlugin( permissions = { - @Permission(strings = {Manifest.permission.WRITE_EXTERNAL_STORAGE}, alias = "HttpWrite"), - @Permission(strings = {Manifest.permission.READ_EXTERNAL_STORAGE}, alias = "HttpRead") + @Permission(strings = { Manifest.permission.WRITE_EXTERNAL_STORAGE }, alias = "HttpWrite"), + @Permission(strings = { Manifest.permission.READ_EXTERNAL_STORAGE }, alias = "HttpRead") } ) public class CapacitorHttp extends Plugin { diff --git a/android/capacitor/src/test/java/com/getcapacitor/ConfigBuildingTest.java b/android/capacitor/src/test/java/com/getcapacitor/ConfigBuildingTest.java index ae12edb02..1af51039d 100644 --- a/android/capacitor/src/test/java/com/getcapacitor/ConfigBuildingTest.java +++ b/android/capacitor/src/test/java/com/getcapacitor/ConfigBuildingTest.java @@ -42,7 +42,7 @@ public void setup() { config = new CapConfig.Builder(context) .setAllowMixedContent(true) - .setAllowNavigation(new String[] {"http://www.google.com"}) + .setAllowNavigation(new String[] { "http://www.google.com" }) .setAndroidScheme("test") .setCaptureInput(true) .setLoggingEnabled(true) @@ -64,7 +64,7 @@ public void setup() { @Test public void getCoreConfigValues() { assertTrue(config.isMixedContentAllowed()); - assertArrayEquals(new String[] {"http://www.google.com"}, config.getAllowNavigation()); + assertArrayEquals(new String[] { "http://www.google.com" }, config.getAllowNavigation()); assertEquals("test", config.getAndroidScheme()); assertTrue(config.isInputCaptured()); assertTrue(config.isLoggingEnabled()); @@ -97,7 +97,7 @@ public void getPluginInt() { @Test public void getPluginArray() { - String[] comparison = new String[] {"5", "6", "7", "8"}; + String[] comparison = new String[] { "5", "6", "7", "8" }; String[] testArray = config.getPluginConfiguration(TEST_PLUGIN_NAME).getArray("var5"); assertArrayEquals(comparison, testArray); } From 93c72de40a2ec4c78b33659250cb08340083088e Mon Sep 17 00:00:00 2001 From: Robin Genz Date: Thu, 21 May 2026 18:54:21 +0200 Subject: [PATCH 08/22] feat: add method getDouble to plugin config (#7638) Co-authored-by: jcesarmobile --- .../java/com/getcapacitor/PluginConfig.java | 11 ++++++++++ .../java/com/getcapacitor/util/JSONUtils.java | 20 +++++++++++++++++++ ios/Capacitor/Capacitor/PluginConfig.swift | 7 +++++++ 3 files changed, 38 insertions(+) diff --git a/android/capacitor/src/main/java/com/getcapacitor/PluginConfig.java b/android/capacitor/src/main/java/com/getcapacitor/PluginConfig.java index 0f00fc530..1d21ae90e 100644 --- a/android/capacitor/src/main/java/com/getcapacitor/PluginConfig.java +++ b/android/capacitor/src/main/java/com/getcapacitor/PluginConfig.java @@ -65,6 +65,17 @@ public int getInt(String configKey, int defaultValue) { return JSONUtils.getInt(config, configKey, defaultValue); } + /** + * Get a double value for a plugin in the Capacitor config. + * + * @param configKey The key of the value to retrieve + * @param defaultValue A default value to return if the key does not exist in the config + * @return The value from the config, if key exists. Default value returned if not + */ + public double getDouble(String configKey, double defaultValue) { + return JSONUtils.getDouble(config, configKey, defaultValue); + } + /** * Get a string array value for a plugin in the Capacitor config. * diff --git a/android/capacitor/src/main/java/com/getcapacitor/util/JSONUtils.java b/android/capacitor/src/main/java/com/getcapacitor/util/JSONUtils.java index 1d2fc2078..f24e5aa0b 100644 --- a/android/capacitor/src/main/java/com/getcapacitor/util/JSONUtils.java +++ b/android/capacitor/src/main/java/com/getcapacitor/util/JSONUtils.java @@ -75,6 +75,26 @@ public static int getInt(JSONObject jsonObject, String key, int defaultValue) { return defaultValue; } + /** + * Get a double value from the given JSON object. + * + * @param jsonObject A JSON object to search + * @param key A key to fetch from the JSON object + * @param defaultValue A default value to return if the key cannot be found + * @return The value at the given key in the JSON object, or the default value + */ + public static double getDouble(JSONObject jsonObject, String key, double defaultValue) { + String k = getDeepestKey(key); + try { + JSONObject o = getDeepestObject(jsonObject, key); + return o.getDouble(k); + } catch (JSONException ignore) { + // value was not found + } + + return defaultValue; + } + /** * Get a JSON object value from the given JSON object. * diff --git a/ios/Capacitor/Capacitor/PluginConfig.swift b/ios/Capacitor/Capacitor/PluginConfig.swift index f2461e102..8d73bc1de 100644 --- a/ios/Capacitor/Capacitor/PluginConfig.swift +++ b/ios/Capacitor/Capacitor/PluginConfig.swift @@ -30,6 +30,13 @@ import Foundation return defaultValue } + @objc public func getDouble(_ configKey: String, _ defaultValue: Double) -> Double { + if let val = (self.config)[keyPath: KeyPath(configKey)] as? Double { + return val + } + return defaultValue + } + public func getArray(_ configKey: String, _ defaultValue: JSArray? = nil) -> JSArray? { if let val = (self.config)[keyPath: KeyPath(configKey)] as? JSArray { return val From e456de083e19644f484bec5a5359cb67960ac8bc Mon Sep 17 00:00:00 2001 From: Joey Pender Date: Fri, 22 May 2026 13:39:38 -0500 Subject: [PATCH 09/22] fix(SystemBars): make `safe-area-inset-x` available on API <= 34 (#8424) --- .../com/getcapacitor/plugin/SystemBars.java | 29 ++++++++++--------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/android/capacitor/src/main/java/com/getcapacitor/plugin/SystemBars.java b/android/capacitor/src/main/java/com/getcapacitor/plugin/SystemBars.java index b335b4b1c..76e74207c 100644 --- a/android/capacitor/src/main/java/com/getcapacitor/plugin/SystemBars.java +++ b/android/capacitor/src/main/java/com/getcapacitor/plugin/SystemBars.java @@ -164,13 +164,18 @@ private Insets calcSafeAreaInsets(WindowInsetsCompat insets) { } private void initSafeAreaCSSVariables() { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.VANILLA_ICE_CREAM && insetHandlingEnabled) { + WindowInsetsCompat insets; + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.VANILLA_ICE_CREAM) { View v = (View) this.getBridge().getWebView().getParent(); - WindowInsetsCompat insets = ViewCompat.getRootWindowInsets(v); - if (insets != null) { - Insets safeAreaInsets = calcSafeAreaInsets(insets); - injectSafeAreaCSS(safeAreaInsets.top, safeAreaInsets.right, safeAreaInsets.bottom, safeAreaInsets.left); - } + insets = ViewCompat.getRootWindowInsets(v); + } else { + insets = WindowInsetsCompat.CONSUMED; + } + + if (insets != null) { + Insets safeAreaInsets = calcSafeAreaInsets(insets); + injectSafeAreaCSS(safeAreaInsets.top, safeAreaInsets.right, safeAreaInsets.bottom, safeAreaInsets.left); } } @@ -186,10 +191,8 @@ private void initWindowInsetsListener() { // We need to correct for a possible shown IME v.setPadding(0, 0, 0, keyboardVisible ? imeInsets.bottom : 0); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.VANILLA_ICE_CREAM && hasViewportCover && insetHandlingEnabled) { - Insets safeAreaInsets = calcSafeAreaInsets(insets); - injectSafeAreaCSS(safeAreaInsets.top, safeAreaInsets.right, safeAreaInsets.bottom, safeAreaInsets.left); - } + Insets safeAreaInsets = calcSafeAreaInsets(insets); + injectSafeAreaCSS(safeAreaInsets.top, safeAreaInsets.right, safeAreaInsets.bottom, safeAreaInsets.left); return new WindowInsetsCompat.Builder(insets) .setInsets( @@ -221,10 +224,8 @@ private void initWindowInsetsListener() { .setInsets(WindowInsetsCompat.Type.systemBars() | WindowInsetsCompat.Type.displayCutout(), Insets.of(0, 0, 0, 0)) .build(); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.VANILLA_ICE_CREAM && hasViewportCover && insetHandlingEnabled) { - Insets safeAreaInsets = calcSafeAreaInsets(newInsets); - injectSafeAreaCSS(safeAreaInsets.top, safeAreaInsets.right, safeAreaInsets.bottom, safeAreaInsets.left); - } + Insets safeAreaInsets = calcSafeAreaInsets(newInsets); + injectSafeAreaCSS(safeAreaInsets.top, safeAreaInsets.right, safeAreaInsets.bottom, safeAreaInsets.left); return newInsets; }); From 258867b7bf37b1837b99b02ec9638e5a6df08d97 Mon Sep 17 00:00:00 2001 From: jcesarmobile Date: Tue, 26 May 2026 12:00:02 +0200 Subject: [PATCH 10/22] feat(cli): add experimental packageOptions (#8471) --- cli/src/declarations.ts | 20 ++++++++++++++++++++ cli/src/ios/update.ts | 3 +++ cli/src/util/spm.ts | 21 ++++++++++++++++++--- 3 files changed, 41 insertions(+), 3 deletions(-) diff --git a/cli/src/declarations.ts b/cli/src/declarations.ts index 6c8645406..bda7ff0c0 100644 --- a/cli/src/declarations.ts +++ b/cli/src/declarations.ts @@ -559,6 +559,13 @@ export interface CapacitorConfig { * @since 8.3.0 */ packageTraits?: { [pluginId: string]: string[] }; + /** + * Define options to apply to the package. + * The key is the plugin ID (e.g. `@capacitor-community/device`) + * + * @since 8.4.0 + */ + packageOptions?: { [pluginId: string]: PackageOptions }; }; }; }; @@ -799,3 +806,16 @@ export interface PluginsConfig { animation?: 'FADE' | 'NONE'; }; } + +export interface PackageOptions { + /** + * Create a symlink to the plugin folder instead of pointing to the plugin path. + * Useful when plugin names conflict. + */ + symlink?: boolean; + /** + * Useful to avoid target name conflicts in dependencies + * [see](https://docs.swift.org/swiftpm/documentation/packagemanagerdocs/modulealiasing/) + */ + moduleAliases?: { [target: string]: string }; +} diff --git a/cli/src/ios/update.ts b/cli/src/ios/update.ts index 82ca85a88..b060e59a8 100644 --- a/cli/src/ios/update.ts +++ b/cli/src/ios/update.ts @@ -639,6 +639,9 @@ async function copyPluginsNativeFiles(config: Config, cordovaPlugins: Plugin[]) async function removePluginsNativeFiles(config: Config) { await remove(config.ios.cordovaPluginsDirAbs); + if ((await config.ios.packageManager) === 'SPM') { + await remove(join(config.ios.nativeProjectDirAbs, 'CapApp-SPM', 'symlinks')); + } await extractTemplate(config.cli.assets.ios.cordovaPluginsTemplateArchiveAbs, config.ios.cordovaPluginsDirAbs); } diff --git a/cli/src/util/spm.ts b/cli/src/util/spm.ts index 7d15787ce..2ef26bcda 100644 --- a/cli/src/util/spm.ts +++ b/cli/src/util/spm.ts @@ -1,4 +1,4 @@ -import { pathExists, existsSync, readFileSync, writeFileSync, remove, move, mkdtemp } from 'fs-extra'; +import { ensureSymlink, pathExists, existsSync, readFileSync, writeFileSync, remove, move, mkdtemp } from 'fs-extra'; import { tmpdir } from 'os'; import { join, relative, resolve } from 'path'; import type { PlistObject } from 'plist'; @@ -100,6 +100,7 @@ export async function generatePackageText(config: Config, plugins: Plugin[]): Pr const iosPlatformVersion = await getCapacitorPackageVersion(config, config.ios.name); const iosVersion = getMajoriOSVersion(config); const packageTraits = config.app.extConfig.experimental?.ios?.spm?.packageTraits ?? {}; + const packageOptions = config.app.extConfig.experimental?.ios?.spm?.packageOptions ?? {}; const swiftToolsVersion = config.app.extConfig.experimental?.ios?.spm?.swiftToolsVersion ?? '5.9'; let packageSwiftText = `// swift-tools-version: ${swiftToolsVersion} @@ -132,7 +133,13 @@ let package = Package( packageSwiftText += `,\n .package(name: "${plugin.name}", path: "../../capacitor-cordova-ios-plugins/sources/${plugin.name}")`; } } else { - const relPath = relative(config.ios.nativeXcodeProjDirAbs, plugin.rootPath); + const options = packageOptions[plugin.id]; + const symlink = options?.symlink; + const symlinkFolder = join('symlinks', plugin.name); + const relPath = symlink ? symlinkFolder : relative(config.ios.nativeXcodeProjDirAbs, plugin.rootPath); + if (symlink) { + await ensureSymlink(plugin.rootPath, resolve(config.ios.nativeProjectDirAbs, 'CapApp-SPM', symlinkFolder)); + } const traits = packageTraits[plugin.id]; const traitsSuffix = traits?.length ? `, traits: [${traits @@ -156,7 +163,15 @@ let package = Package( .product(name: "Cordova", package: "capacitor-swift-pm")`; for (const plugin of plugins) { - let pluginText = `,\n .product(name: "${plugin.ios?.name}", package: "${plugin.ios?.name}")`; + const aliases = Object.entries(packageOptions[plugin.id]?.moduleAliases ?? {}); + const aliasText = aliases?.length + ? `, moduleAliases: [${aliases + .map(([target, replacement]) => { + return `"${target}": "${replacement}"`; + }) + .join(', ')}]` + : ''; + let pluginText = `,\n .product(name: "${plugin.ios?.name}", package: "${plugin.ios?.name}"${aliasText})`; if (getPluginType(plugin, config.ios.name) === PluginType.Cordova) { const platformTag = getPluginPlatform(plugin, config.ios.name); if (platformTag.$?.package) { From b4b297a52f8732659662d5e5aaeff81c0f7d9835 Mon Sep 17 00:00:00 2001 From: "Alex J." Date: Wed, 27 May 2026 14:49:32 -0400 Subject: [PATCH 11/22] feat(cli): capture ios_package_manager in telemetry (#8482) --- cli/src/telemetry.ts | 25 +++++++++++++++- cli/test/telemetry.spec.ts | 60 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 84 insertions(+), 1 deletion(-) create mode 100644 cli/test/telemetry.spec.ts diff --git a/cli/src/telemetry.ts b/cli/src/telemetry.ts index 8e0d847ac..593397502 100644 --- a/cli/src/telemetry.ts +++ b/cli/src/telemetry.ts @@ -1,8 +1,9 @@ import { Command } from 'commander'; import Debug from 'debug'; +import { pathExists } from 'fs-extra'; import c from './colors'; -import type { Config } from './definitions'; +import type { Config, PackageManager } from './definitions'; import { send } from './ipc'; import { output } from './log'; import { readConfig, writeConfig } from './sysconfig'; @@ -26,6 +27,7 @@ export interface CommandMetricData { error: string | null; node_version: string; os: string; + ios_package_manager: PackageManager | 'unknown'; } export interface Metric { @@ -80,9 +82,12 @@ export function telemetryAction(config: Config, action: CommanderAction): Comman error: error ? (error.message ? error.message : String(error)) : null, node_version: process.version, os: config.cli.os, + ios_package_manager: await getIOSPackageManager(config), ...Object.fromEntries(versions), }; + debug('metric payload: %O', data); + if (isInteractive()) { let sysconfig = await readConfig(); @@ -126,6 +131,24 @@ export async function sendMetric( } } +/** + * Resolve the iOS dependency manager for telemetry. Returns 'unknown' for + * non-iOS projects or when detection throws, so callers never have to handle + * errors from this signal. + */ +export async function getIOSPackageManager(config: Config): Promise { + try { + if (!(await pathExists(config.ios.platformDirAbs))) { + return 'unknown'; + } + + return await config.ios.packageManager; + } catch (e) { + debug('Could not resolve iOS package manager for telemetry: %O', e); + return 'unknown'; + } +} + /** * Get a unique anonymous identifier for this app. */ diff --git a/cli/test/telemetry.spec.ts b/cli/test/telemetry.spec.ts new file mode 100644 index 000000000..412048527 --- /dev/null +++ b/cli/test/telemetry.spec.ts @@ -0,0 +1,60 @@ +import { pathExists } from 'fs-extra'; + +import type { Config, IOSConfig } from '../src/definitions'; +import { getIOSPackageManager } from '../src/telemetry'; + +jest.mock('fs-extra', () => ({ + pathExists: jest.fn(), +})); + +const mockedPathExists = pathExists as unknown as jest.Mock; + +function makeConfig(ios: Partial): Config { + return { ios } as unknown as Config; +} + +describe('getIOSPackageManager', () => { + beforeEach(() => { + mockedPathExists.mockReset(); + }); + + it('returns "unknown" when the iOS platform directory does not exist', async () => { + mockedPathExists.mockResolvedValueOnce(false); + + const result = await getIOSPackageManager( + makeConfig({ + platformDirAbs: '/tmp/no-such-dir/ios', + packageManager: Promise.resolve('SPM'), + }), + ); + + expect(result).toBe('unknown'); + expect(mockedPathExists).toHaveBeenCalledWith('/tmp/no-such-dir/ios'); + }); + + it('returns the resolved package manager when iOS is present', async () => { + mockedPathExists.mockResolvedValueOnce(true); + + const result = await getIOSPackageManager( + makeConfig({ + platformDirAbs: '/tmp/app/ios', + packageManager: Promise.resolve('SPM'), + }), + ); + + expect(result).toBe('SPM'); + }); + + it('returns "unknown" when packageManager resolution throws', async () => { + mockedPathExists.mockResolvedValueOnce(true); + + const result = await getIOSPackageManager( + makeConfig({ + platformDirAbs: '/tmp/app/ios', + packageManager: Promise.reject(new Error('boom')), + }), + ); + + expect(result).toBe('unknown'); + }); +}); From 1d031a4abec2c793079ba8897ad2e40c4cc6c7f9 Mon Sep 17 00:00:00 2001 From: jcesarmobile Date: Thu, 28 May 2026 15:00:43 +0200 Subject: [PATCH 12/22] fix(cli): revert live reload config on failure (#8485) --- cli/src/tasks/run.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cli/src/tasks/run.ts b/cli/src/tasks/run.ts index 2abdb9cd2..439c29209 100644 --- a/cli/src/tasks/run.ts +++ b/cli/src/tasks/run.ts @@ -116,6 +116,9 @@ export async function runCommand( await sleepForever(); } } catch (e: any) { + if (options.liveReload) { + await CapLiveReloadHelper.revertCapConfigForLiveReload(); + } if (!isFatal(e)) { fatal(e.stack ?? e); } From f1077ef9645b1ada2dd2635e3c3220612bdb4da6 Mon Sep 17 00:00:00 2001 From: jcesarmobile Date: Fri, 29 May 2026 11:02:23 +0200 Subject: [PATCH 13/22] chore: fix typo in declarations.ts (#8488) --- cli/src/declarations.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cli/src/declarations.ts b/cli/src/declarations.ts index bda7ff0c0..1103b6585 100644 --- a/cli/src/declarations.ts +++ b/cli/src/declarations.ts @@ -604,7 +604,7 @@ export interface CapacitorConfig { * Configure the local scheme on Android. * * Custom schemes on Android are unable to change the URL path as of Webview 117. Changing this value from anything other than `http` or `https` can result in your - * application unable to resolve routing. If you must change this for some reason, consider using a hash-based url strategy, but there are no guarentees that this + * application unable to resolve routing. If you must change this for some reason, consider using a hash-based url strategy, but there are no guarantees that this * will continue to work long term as allowing non-standard schemes to modify query parameters and url fragments is only allowed for compatibility reasons. * https://ionic.io/blog/capacitor-android-customscheme-issue-with-chrome-117 * From d4ad7ffe39daf66e0cfc63af9028d5c05543bde7 Mon Sep 17 00:00:00 2001 From: Joey Pender Date: Mon, 1 Jun 2026 10:31:48 -0500 Subject: [PATCH 14/22] fix(SystemBars): respect `insetsHandling` disable (#8481) --- .../com/getcapacitor/plugin/SystemBars.java | 54 ++++++++++++------- 1 file changed, 35 insertions(+), 19 deletions(-) diff --git a/android/capacitor/src/main/java/com/getcapacitor/plugin/SystemBars.java b/android/capacitor/src/main/java/com/getcapacitor/plugin/SystemBars.java index 76e74207c..29b76e2f2 100644 --- a/android/capacitor/src/main/java/com/getcapacitor/plugin/SystemBars.java +++ b/android/capacitor/src/main/java/com/getcapacitor/plugin/SystemBars.java @@ -16,6 +16,7 @@ import androidx.core.view.WindowInsetsCompat; import androidx.core.view.WindowInsetsControllerCompat; import androidx.webkit.WebViewCompat; +import com.getcapacitor.Logger; import com.getcapacitor.Plugin; import com.getcapacitor.PluginCall; import com.getcapacitor.PluginMethod; @@ -32,6 +33,7 @@ public class SystemBars extends Plugin { static final String BAR_STATUS_BAR = "StatusBar"; static final String BAR_GESTURE_BAR = "NavigationBar"; + // TODO: In Cap 9, add an additional option "full" static final String INSETS_HANDLING_CSS = "css"; static final String INSETS_HANDLING_DISABLE = "disable"; @@ -53,7 +55,7 @@ function capacitorSystemBarsCheckMetaViewport() { capacitorSystemBarsCheckMetaViewport(); """; - private boolean insetHandlingEnabled = true; + private String insetsHandling = INSETS_HANDLING_CSS; private boolean hasViewportCover = false; private String currentStatusBarStyle = STYLE_DEFAULT; @@ -94,9 +96,15 @@ private void initSystemBars() { String style = getConfig().getString("style", STYLE_DEFAULT).toUpperCase(Locale.US); boolean hidden = getConfig().getBoolean("hidden", false); - String insetsHandling = getConfig().getString("insetsHandling", "css"); - if (insetsHandling.equals(INSETS_HANDLING_DISABLE)) { - insetHandlingEnabled = false; + 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; } initWindowInsetsListener(); @@ -146,13 +154,15 @@ public void setAnimation(final PluginCall call) { @JavascriptInterface public void onDOMReady() { - getActivity().runOnUiThread(() -> { - this.bridge.getWebView().evaluateJavascript(viewportMetaJSFunction, (res) -> { - hasViewportCover = res.equals("true"); + if (INSETS_HANDLING_CSS.equals(insetsHandling)) { + getActivity().runOnUiThread(() -> { + this.bridge.getWebView().evaluateJavascript(viewportMetaJSFunction, (res) -> { + hasViewportCover = res.equals("true"); - getBridge().getWebView().requestApplyInsets(); + getBridge().getWebView().requestApplyInsets(); + }); }); - }); + } } private Insets calcSafeAreaInsets(WindowInsetsCompat insets) { @@ -164,22 +174,28 @@ private Insets calcSafeAreaInsets(WindowInsetsCompat insets) { } private void initSafeAreaCSSVariables() { - WindowInsetsCompat insets; + if (INSETS_HANDLING_CSS.equals(insetsHandling)) { + WindowInsetsCompat insets; - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.VANILLA_ICE_CREAM) { - View v = (View) this.getBridge().getWebView().getParent(); - insets = ViewCompat.getRootWindowInsets(v); - } else { - insets = WindowInsetsCompat.CONSUMED; - } + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.VANILLA_ICE_CREAM) { + View v = (View) this.getBridge().getWebView().getParent(); + insets = ViewCompat.getRootWindowInsets(v); + } else { + insets = WindowInsetsCompat.CONSUMED; + } - if (insets != null) { - Insets safeAreaInsets = calcSafeAreaInsets(insets); - injectSafeAreaCSS(safeAreaInsets.top, safeAreaInsets.right, safeAreaInsets.bottom, safeAreaInsets.left); + if (insets != null) { + Insets safeAreaInsets = calcSafeAreaInsets(insets); + injectSafeAreaCSS(safeAreaInsets.top, safeAreaInsets.right, safeAreaInsets.bottom, safeAreaInsets.left); + } } } private void initWindowInsetsListener() { + if (INSETS_HANDLING_DISABLE.equals(insetsHandling)) { + return; + } + ViewCompat.setOnApplyWindowInsetsListener((View) getBridge().getWebView().getParent(), (v, insets) -> { boolean shouldPassthroughInsets = getWebViewMajorVersion() >= WEBVIEW_VERSION_WITH_SAFE_AREA_FIX && hasViewportCover; From 4c6c3219afb5223211e857457e46283c37eb9424 Mon Sep 17 00:00:00 2001 From: Minh Vu Date: Mon, 1 Jun 2026 21:04:08 +0200 Subject: [PATCH 15/22] fix(android): show only the requested system bar (#8480) Co-authored-by: Joey Pender Co-authored-by: Pedro Bilro Co-authored-by: Mark Anderson --- .../com/getcapacitor/plugin/SystemBars.java | 14 ++-- .../getcapacitor/plugin/SystemBarsTest.java | 73 +++++++++++++++++++ 2 files changed, 81 insertions(+), 6 deletions(-) create mode 100644 android/capacitor/src/test/java/com/getcapacitor/plugin/SystemBarsTest.java diff --git a/android/capacitor/src/main/java/com/getcapacitor/plugin/SystemBars.java b/android/capacitor/src/main/java/com/getcapacitor/plugin/SystemBars.java index 29b76e2f2..fd7137094 100644 --- a/android/capacitor/src/main/java/com/getcapacitor/plugin/SystemBars.java +++ b/android/capacitor/src/main/java/com/getcapacitor/plugin/SystemBars.java @@ -304,19 +304,21 @@ private void setHidden(boolean hide, String bar) { WindowInsetsControllerCompat windowInsetsControllerCompat = WindowCompat.getInsetsController(window, window.getDecorView()); if (hide) { - if (bar.isEmpty() || bar.equals(BAR_STATUS_BAR)) { + if (bar.isEmpty()) { + windowInsetsControllerCompat.hide(WindowInsetsCompat.Type.systemBars()); + } else if (bar.equals(BAR_STATUS_BAR)) { windowInsetsControllerCompat.hide(WindowInsetsCompat.Type.statusBars()); - } - if (bar.isEmpty() || bar.equals(BAR_GESTURE_BAR)) { + } else if (bar.equals(BAR_GESTURE_BAR)) { windowInsetsControllerCompat.hide(WindowInsetsCompat.Type.navigationBars()); } return; } - if (bar.isEmpty() || bar.equals(BAR_STATUS_BAR)) { + if (bar.isEmpty()) { windowInsetsControllerCompat.show(WindowInsetsCompat.Type.systemBars()); - } - if (bar.isEmpty() || bar.equals(BAR_GESTURE_BAR)) { + } else if (bar.equals(BAR_STATUS_BAR)) { + windowInsetsControllerCompat.show(WindowInsetsCompat.Type.statusBars()); + } else if (bar.equals(BAR_GESTURE_BAR)) { windowInsetsControllerCompat.show(WindowInsetsCompat.Type.navigationBars()); } } diff --git a/android/capacitor/src/test/java/com/getcapacitor/plugin/SystemBarsTest.java b/android/capacitor/src/test/java/com/getcapacitor/plugin/SystemBarsTest.java new file mode 100644 index 000000000..f72373a88 --- /dev/null +++ b/android/capacitor/src/test/java/com/getcapacitor/plugin/SystemBarsTest.java @@ -0,0 +1,73 @@ +package com.getcapacitor.plugin; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.mockStatic; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import android.view.View; +import android.view.Window; +import androidx.appcompat.app.AppCompatActivity; +import androidx.core.view.WindowCompat; +import androidx.core.view.WindowInsetsCompat; +import androidx.core.view.WindowInsetsControllerCompat; +import com.getcapacitor.Bridge; +import java.lang.reflect.Method; +import org.junit.Test; +import org.mockito.MockedStatic; + +public class SystemBarsTest { + + @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 = 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; + } +} From 36b729d10380687bf5eab2cfa8affcbd1655541b Mon Sep 17 00:00:00 2001 From: Mark Anderson Date: Mon, 1 Jun 2026 15:11:51 -0400 Subject: [PATCH 16/22] chore: Decrease timeout for CI jobs from 60 to 30 minutes (#8476) Co-authored-by: jcesarmobile --- .github/workflows/ci.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8664a402d..56fce5389 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -18,7 +18,7 @@ concurrency: jobs: setup: runs-on: ubuntu-latest - timeout-minutes: 60 + timeout-minutes: 30 steps: - name: Get Latest uses: actions/setup-node@v6 @@ -32,7 +32,7 @@ jobs: key: ${{ runner.OS }}-dependencies-cache-${{ hashFiles('**/package.json') }} lint: runs-on: macos-15 - timeout-minutes: 60 + timeout-minutes: 30 steps: - uses: actions/setup-node@v6 with: @@ -48,7 +48,7 @@ jobs: - run: npm run lint test-cli: runs-on: macos-15 - timeout-minutes: 60 + timeout-minutes: 30 needs: - setup - lint @@ -69,7 +69,7 @@ jobs: working-directory: ./cli test-core: runs-on: ubuntu-latest - timeout-minutes: 60 + timeout-minutes: 30 needs: - setup - lint @@ -90,7 +90,7 @@ jobs: working-directory: ./core test-ios: runs-on: macos-15 - timeout-minutes: 60 + timeout-minutes: 30 needs: - setup - lint @@ -118,7 +118,7 @@ jobs: run: sh ./scripts/native-podspec.sh lint test-android: runs-on: ubuntu-latest - timeout-minutes: 60 + timeout-minutes: 30 needs: - setup - lint From 41fd9deb6df07ef83ae390d16824e8bcbefef517 Mon Sep 17 00:00:00 2001 From: "Github Workflow (on behalf of markemer)" Date: Tue, 2 Jun 2026 15:56:03 +0000 Subject: [PATCH 17/22] Release 8.4.0 --- CHANGELOG.md | 15 +++++++++++++++ android/CHANGELOG.md | 12 ++++++++++++ android/package.json | 4 ++-- cli/CHANGELOG.md | 11 +++++++++++ cli/package.json | 2 +- core/CHANGELOG.md | 4 ++++ core/package.json | 2 +- ios/CHANGELOG.md | 6 ++++++ ios/package.json | 4 ++-- lerna.json | 2 +- 10 files changed, 55 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a7f2b7713..cd4fe5f5a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,21 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [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 diff --git a/android/CHANGELOG.md b/android/CHANGELOG.md index 74d538d9f..df7ce545e 100644 --- a/android/CHANGELOG.md +++ b/android/CHANGELOG.md @@ -3,6 +3,18 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [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)) + ## [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/android diff --git a/android/package.json b/android/package.json index 8ae93f3f2..af3f4f556 100644 --- a/android/package.json +++ b/android/package.json @@ -1,6 +1,6 @@ { "name": "@capacitor/android", - "version": "8.3.4", + "version": "8.4.0", "description": "Capacitor: Cross-platform apps with JavaScript and the web", "homepage": "https://capacitorjs.com", "author": "Ionic Team (https://ionic.io)", @@ -23,7 +23,7 @@ "verify": "./gradlew clean lint build test -b capacitor/build.gradle" }, "peerDependencies": { - "@capacitor/core": "^8.3.0" + "@capacitor/core": "^8.4.0" }, "publishConfig": { "access": "public" diff --git a/cli/CHANGELOG.md b/cli/CHANGELOG.md index bba24688f..ee48a8d5f 100644 --- a/cli/CHANGELOG.md +++ b/cli/CHANGELOG.md @@ -3,6 +3,17 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [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)) + ## [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/cli diff --git a/cli/package.json b/cli/package.json index 9df346b14..1f987d33a 100644 --- a/cli/package.json +++ b/cli/package.json @@ -1,6 +1,6 @@ { "name": "@capacitor/cli", - "version": "8.3.4", + "version": "8.4.0", "description": "Capacitor: Cross-platform apps with JavaScript and the web", "homepage": "https://capacitorjs.com", "author": "Ionic Team (https://ionic.io)", diff --git a/core/CHANGELOG.md b/core/CHANGELOG.md index 017293794..1de9522ff 100644 --- a/core/CHANGELOG.md +++ b/core/CHANGELOG.md @@ -3,6 +3,10 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [8.4.0](https://github.com/ionic-team/capacitor/compare/8.3.4...8.4.0) (2026-06-02) + +**Note:** Version bump only for package @capacitor/core + ## [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/core diff --git a/core/package.json b/core/package.json index eef113a50..b22aef174 100644 --- a/core/package.json +++ b/core/package.json @@ -1,6 +1,6 @@ { "name": "@capacitor/core", - "version": "8.3.4", + "version": "8.4.0", "description": "Capacitor: Cross-platform apps with JavaScript and the web", "homepage": "https://capacitorjs.com", "author": "Ionic Team (https://ionic.io)", diff --git a/ios/CHANGELOG.md b/ios/CHANGELOG.md index 87ee73bb4..eac0a4a1c 100644 --- a/ios/CHANGELOG.md +++ b/ios/CHANGELOG.md @@ -3,6 +3,12 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [8.4.0](https://github.com/ionic-team/capacitor/compare/8.3.4...8.4.0) (2026-06-02) + +### 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.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/ios diff --git a/ios/package.json b/ios/package.json index a7b8d3133..a58c02090 100644 --- a/ios/package.json +++ b/ios/package.json @@ -1,6 +1,6 @@ { "name": "@capacitor/ios", - "version": "8.3.4", + "version": "8.4.0", "description": "Capacitor: Cross-platform apps with JavaScript and the web", "homepage": "https://capacitorjs.com", "author": "Ionic Team (https://ionic.io)", @@ -25,7 +25,7 @@ "xc:build:CapacitorCordova": "cd CapacitorCordova && xcodebuild && cd .." }, "peerDependencies": { - "@capacitor/core": "^8.3.0" + "@capacitor/core": "^8.4.0" }, "publishConfig": { "access": "public" diff --git a/lerna.json b/lerna.json index 1e53d6bdc..b2efb400d 100644 --- a/lerna.json +++ b/lerna.json @@ -11,6 +11,6 @@ "tagVersionPrefix": "" } }, - "version": "8.3.4", + "version": "8.4.0", "$schema": "node_modules/lerna/schemas/lerna-schema.json" } From 28bb2c687069dfdd6aa7abc866004a1c6388d103 Mon Sep 17 00:00:00 2001 From: jcesarmobile Date: Tue, 2 Jun 2026 21:31:41 +0200 Subject: [PATCH 18/22] fix(cli): patch Capacitor SPM dependency version in plugins (#8492) Co-authored-by: Mark Anderson --- cli/src/ios/update.ts | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/cli/src/ios/update.ts b/cli/src/ios/update.ts index b060e59a8..1f4bc87d0 100644 --- a/cli/src/ios/update.ts +++ b/cli/src/ios/update.ts @@ -1,5 +1,6 @@ import { copy, remove, pathExists, readFile, realpath, writeFile } from 'fs-extra'; import { basename, dirname, join, relative } from 'path'; +import { major } from 'semver'; import c from '../colors'; import { checkPlatformVersions, getCapacitorPackageVersion, runTask } from '../common'; @@ -58,6 +59,28 @@ async function updatePluginFiles(config: Config, plugins: Plugin[], deployment: await generateCordovaPackageFiles(cordovaPlugins, config); const validSPMPackages = await checkPluginsForPackageSwift(config, plugins); + 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) { + content = setAllStringIn( + content, + `url: "https://github.com/ionic-team/capacitor-swift-pm.git",`, + `)`, + ` from: "${majorCapVersion}.0.0"`, + ); + await writeFile(packageSwiftPath, content); + logger.warn(`${plugin.id} is built for Capacitor ${major(version)}, it might cause issues`); + } + }), + ); await generatePackageFile(config, validSPMPackages.concat(cordovaPlugins)); } else { From 6048e90171afa0229a3c25b52a23c377c6bb804c Mon Sep 17 00:00:00 2001 From: jcesarmobile Date: Mon, 15 Jun 2026 12:11:19 +0200 Subject: [PATCH 19/22] fix(cli): make SPM dependency patch work on prereleases (#8508) --- cli/src/ios/update.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/cli/src/ios/update.ts b/cli/src/ios/update.ts index 1f4bc87d0..3ab793c25 100644 --- a/cli/src/ios/update.ts +++ b/cli/src/ios/update.ts @@ -1,6 +1,6 @@ import { copy, remove, pathExists, readFile, realpath, writeFile } from 'fs-extra'; import { basename, dirname, join, relative } from 'path'; -import { major } from 'semver'; +import { major, prerelease } from 'semver'; import c from '../colors'; import { checkPlatformVersions, getCapacitorPackageVersion, runTask } from '../common'; @@ -70,11 +70,13 @@ async function updatePluginFiles(config: Config, plugins: Plugin[], deployment: 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: "${majorCapVersion}.0.0"`, + ` from: "${forceVersion}"`, ); await writeFile(packageSwiftPath, content); logger.warn(`${plugin.id} is built for Capacitor ${major(version)}, it might cause issues`); From 7217b5215a175eededf607a216e0cab2a8450a34 Mon Sep 17 00:00:00 2001 From: "Github Workflow (on behalf of jcesarmobile)" Date: Fri, 19 Jun 2026 09:01:59 +0000 Subject: [PATCH 20/22] Release 8.4.1 --- CHANGELOG.md | 7 +++++++ android/CHANGELOG.md | 4 ++++ android/package.json | 2 +- cli/CHANGELOG.md | 7 +++++++ cli/package.json | 2 +- core/CHANGELOG.md | 4 ++++ core/package.json | 2 +- ios/CHANGELOG.md | 4 ++++ ios/package.json | 2 +- lerna.json | 2 +- 10 files changed, 31 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cd4fe5f5a..db3954562 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,13 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [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 diff --git a/android/CHANGELOG.md b/android/CHANGELOG.md index df7ce545e..5bc9de9f6 100644 --- a/android/CHANGELOG.md +++ b/android/CHANGELOG.md @@ -3,6 +3,10 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [8.4.1](https://github.com/ionic-team/capacitor/compare/8.4.0...8.4.1) (2026-06-19) + +**Note:** Version bump only for package @capacitor/android + # [8.4.0](https://github.com/ionic-team/capacitor/compare/8.3.4...8.4.0) (2026-06-02) ### Bug Fixes diff --git a/android/package.json b/android/package.json index af3f4f556..7354f3b2c 100644 --- a/android/package.json +++ b/android/package.json @@ -1,6 +1,6 @@ { "name": "@capacitor/android", - "version": "8.4.0", + "version": "8.4.1", "description": "Capacitor: Cross-platform apps with JavaScript and the web", "homepage": "https://capacitorjs.com", "author": "Ionic Team (https://ionic.io)", diff --git a/cli/CHANGELOG.md b/cli/CHANGELOG.md index ee48a8d5f..df61fcbaa 100644 --- a/cli/CHANGELOG.md +++ b/cli/CHANGELOG.md @@ -3,6 +3,13 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [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 diff --git a/cli/package.json b/cli/package.json index 1f987d33a..7a77d11e9 100644 --- a/cli/package.json +++ b/cli/package.json @@ -1,6 +1,6 @@ { "name": "@capacitor/cli", - "version": "8.4.0", + "version": "8.4.1", "description": "Capacitor: Cross-platform apps with JavaScript and the web", "homepage": "https://capacitorjs.com", "author": "Ionic Team (https://ionic.io)", diff --git a/core/CHANGELOG.md b/core/CHANGELOG.md index 1de9522ff..1003c8ceb 100644 --- a/core/CHANGELOG.md +++ b/core/CHANGELOG.md @@ -3,6 +3,10 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [8.4.1](https://github.com/ionic-team/capacitor/compare/8.4.0...8.4.1) (2026-06-19) + +**Note:** Version bump only for package @capacitor/core + # [8.4.0](https://github.com/ionic-team/capacitor/compare/8.3.4...8.4.0) (2026-06-02) **Note:** Version bump only for package @capacitor/core diff --git a/core/package.json b/core/package.json index b22aef174..f821cfd9d 100644 --- a/core/package.json +++ b/core/package.json @@ -1,6 +1,6 @@ { "name": "@capacitor/core", - "version": "8.4.0", + "version": "8.4.1", "description": "Capacitor: Cross-platform apps with JavaScript and the web", "homepage": "https://capacitorjs.com", "author": "Ionic Team (https://ionic.io)", diff --git a/ios/CHANGELOG.md b/ios/CHANGELOG.md index eac0a4a1c..dfcf383ff 100644 --- a/ios/CHANGELOG.md +++ b/ios/CHANGELOG.md @@ -3,6 +3,10 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [8.4.1](https://github.com/ionic-team/capacitor/compare/8.4.0...8.4.1) (2026-06-19) + +**Note:** Version bump only for package @capacitor/ios + # [8.4.0](https://github.com/ionic-team/capacitor/compare/8.3.4...8.4.0) (2026-06-02) ### Features diff --git a/ios/package.json b/ios/package.json index a58c02090..a6a78c23d 100644 --- a/ios/package.json +++ b/ios/package.json @@ -1,6 +1,6 @@ { "name": "@capacitor/ios", - "version": "8.4.0", + "version": "8.4.1", "description": "Capacitor: Cross-platform apps with JavaScript and the web", "homepage": "https://capacitorjs.com", "author": "Ionic Team (https://ionic.io)", diff --git a/lerna.json b/lerna.json index b2efb400d..be3666942 100644 --- a/lerna.json +++ b/lerna.json @@ -11,6 +11,6 @@ "tagVersionPrefix": "" } }, - "version": "8.4.0", + "version": "8.4.1", "$schema": "node_modules/lerna/schemas/lerna-schema.json" } From b789b683f04863e65c66d630890f00561c0d5b7a Mon Sep 17 00:00:00 2001 From: Mark Anderson Date: Mon, 22 Jun 2026 15:42:23 -0400 Subject: [PATCH 21/22] chore: run `npm run fmt` to fix lint errors (#8516) --- .../java/com/getcapacitor/BridgeWebChromeClient.java | 4 ++-- .../src/main/java/com/getcapacitor/FileUtils.java | 2 +- .../java/com/getcapacitor/WebViewLocalServer.java | 12 ++++++------ .../getcapacitor/plugin/CapacitorCookieManager.java | 6 +++--- .../getcapacitor/plugin/util/HttpRequestHandler.java | 4 ++-- 5 files changed, 14 insertions(+), 14 deletions(-) diff --git a/android/capacitor/src/main/java/com/getcapacitor/BridgeWebChromeClient.java b/android/capacitor/src/main/java/com/getcapacitor/BridgeWebChromeClient.java index 6ca1c8a83..ec7867369 100644 --- a/android/capacitor/src/main/java/com/getcapacitor/BridgeWebChromeClient.java +++ b/android/capacitor/src/main/java/com/getcapacitor/BridgeWebChromeClient.java @@ -282,7 +282,7 @@ public boolean onShowFileChooser( boolean captureEnabled = fileChooserParams.isCaptureEnabled(); boolean capturePhoto = captureEnabled && acceptTypes.contains("image/*"); final boolean captureVideo = captureEnabled && acceptTypes.contains("video/*"); - if ((capturePhoto || captureVideo)) { + if (capturePhoto || captureVideo) { if (isMediaCaptureSupported()) { showMediaCaptureOrFilePicker(filePathCallback, fileChooserParams, captureVideo); } else { @@ -447,7 +447,7 @@ public boolean onConsoleMessage(ConsoleMessage consoleMessage) { } public boolean isValidMsg(String msg) { - return !(msg.contains("%cresult %c") || (msg.contains("%cnative %c")) || msg.equalsIgnoreCase("console.groupEnd")); + return !(msg.contains("%cresult %c") || msg.contains("%cnative %c") || msg.equalsIgnoreCase("console.groupEnd")); } private Uri createImageFileUri() throws IOException { diff --git a/android/capacitor/src/main/java/com/getcapacitor/FileUtils.java b/android/capacitor/src/main/java/com/getcapacitor/FileUtils.java index ce09e7c2f..cec171946 100644 --- a/android/capacitor/src/main/java/com/getcapacitor/FileUtils.java +++ b/android/capacitor/src/main/java/com/getcapacitor/FileUtils.java @@ -218,7 +218,7 @@ private static String getCopyFilePath(Uri uri, Context context) { Cursor cursor = context.getContentResolver().query(uri, null, null, null, null); int nameIndex = cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME); cursor.moveToFirst(); - String name = (cursor.getString(nameIndex)); + String name = cursor.getString(nameIndex); String fileName = sanitizeFilename(name); File file = new File(context.getFilesDir(), fileName); try { diff --git a/android/capacitor/src/main/java/com/getcapacitor/WebViewLocalServer.java b/android/capacitor/src/main/java/com/getcapacitor/WebViewLocalServer.java index a39483de9..0c5480079 100755 --- a/android/capacitor/src/main/java/com/getcapacitor/WebViewLocalServer.java +++ b/android/capacitor/src/main/java/com/getcapacitor/WebViewLocalServer.java @@ -221,7 +221,7 @@ private boolean isErrorUrl(Uri uri) { } private boolean isMainUrl(Uri loadingUrl) { - return (bridge.getServerUrl() == null && loadingUrl.getHost().equalsIgnoreCase(bridge.getHost())); + return bridge.getServerUrl() == null && loadingUrl.getHost().equalsIgnoreCase(bridge.getHost()); } private boolean isAllowedUrl(Uri loadingUrl) { @@ -722,31 +722,31 @@ private InputStream getInputStream() { @Override public int available() throws IOException { InputStream is = getInputStream(); - return (is != null) ? is.available() : -1; + return is != null ? is.available() : -1; } @Override public int read() throws IOException { InputStream is = getInputStream(); - return (is != null) ? is.read() : -1; + return is != null ? is.read() : -1; } @Override public int read(byte[] b) throws IOException { InputStream is = getInputStream(); - return (is != null) ? is.read(b) : -1; + return is != null ? is.read(b) : -1; } @Override public int read(byte[] b, int off, int len) throws IOException { InputStream is = getInputStream(); - return (is != null) ? is.read(b, off, len) : -1; + return is != null ? is.read(b, off, len) : -1; } @Override public long skip(long n) throws IOException { InputStream is = getInputStream(); - return (is != null) ? is.skip(n) : 0; + return is != null ? is.skip(n) : 0; } } diff --git a/android/capacitor/src/main/java/com/getcapacitor/plugin/CapacitorCookieManager.java b/android/capacitor/src/main/java/com/getcapacitor/plugin/CapacitorCookieManager.java index cf4ab6326..472323bbc 100644 --- a/android/capacitor/src/main/java/com/getcapacitor/plugin/CapacitorCookieManager.java +++ b/android/capacitor/src/main/java/com/getcapacitor/plugin/CapacitorCookieManager.java @@ -192,12 +192,12 @@ public void flush() { @Override public void put(URI uri, Map> responseHeaders) { // make sure our args are valid - if ((uri == null) || (responseHeaders == null)) return; + if (uri == null || responseHeaders == null) return; // go over the headers for (String headerKey : responseHeaders.keySet()) { // ignore headers which aren't cookie related - if ((headerKey == null) || !(headerKey.equalsIgnoreCase("Set-Cookie2") || headerKey.equalsIgnoreCase("Set-Cookie"))) continue; + if (headerKey == null || !(headerKey.equalsIgnoreCase("Set-Cookie2") || headerKey.equalsIgnoreCase("Set-Cookie"))) continue; // process each of the headers for (String headerValue : Objects.requireNonNull(responseHeaders.get(headerKey))) { @@ -215,7 +215,7 @@ public void put(URI uri, Map> responseHeaders) { @Override public Map> get(URI uri, Map> requestHeaders) { // make sure our args are valid - if ((uri == null) || (requestHeaders == null)) throw new IllegalArgumentException("Argument is null"); + if (uri == null || requestHeaders == null) throw new IllegalArgumentException("Argument is null"); // save our url once String url = uri.toString(); diff --git a/android/capacitor/src/main/java/com/getcapacitor/plugin/util/HttpRequestHandler.java b/android/capacitor/src/main/java/com/getcapacitor/plugin/util/HttpRequestHandler.java index b47d57cf1..69278bc63 100644 --- a/android/capacitor/src/main/java/com/getcapacitor/plugin/util/HttpRequestHandler.java +++ b/android/capacitor/src/main/java/com/getcapacitor/plugin/util/HttpRequestHandler.java @@ -168,8 +168,8 @@ public HttpURLConnectionBuilder setUrlParams(JSObject params, boolean shouldEnco "://" + uri.getAuthority() + uri.getPath() + - ((!urlQuery.equals("")) ? "?" + urlQuery : "") + - ((uri.getFragment() != null) ? uri.getFragment() : ""); + (!urlQuery.equals("") ? "?" + urlQuery : "") + + (uri.getFragment() != null ? uri.getFragment() : ""); this.url = new URL(unEncodedUrlString); return this; From 3fc41b872b75c46b4d41fc20a74a3eb90ab9c9ec Mon Sep 17 00:00:00 2001 From: Mika Ruch Date: Thu, 25 Jun 2026 20:27:36 +0200 Subject: [PATCH 22/22] fix(ios): retain WKHTTPCookieStore observer so cookie sync works --- .../Capacitor/CAPBridgeViewController.swift | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/ios/Capacitor/Capacitor/CAPBridgeViewController.swift b/ios/Capacitor/Capacitor/CAPBridgeViewController.swift index a7285213d..8d8cf088d 100644 --- a/ios/Capacitor/Capacitor/CAPBridgeViewController.swift +++ b/ios/Capacitor/Capacitor/CAPBridgeViewController.swift @@ -10,6 +10,12 @@ import Cordova public fileprivate(set) var webView: WKWebView? + // WKHTTPCookieStore does not retain observers, so we hold a strong reference here + // (else it deallocs immediately and `cookiesDidChange` never fires) plus the store + // it was added to, so the observer can be removed in `deinit` as the docs require. + private var cookieObserver: CapacitorWKCookieObserver? + private weak var cookieObserverStore: WKHTTPCookieStore? + public var isStatusBarVisible = true public var statusBarStyle: UIStatusBarStyle = .default public var statusBarAnimation: UIStatusBarAnimation = .fade @@ -27,6 +33,12 @@ import Cordova return false }() + deinit { + if let cookieObserver = cookieObserver { + cookieObserverStore?.remove(cookieObserver) + } + } + override public final func loadView() { // load the configuration and set the logging flag let configDescriptor = instanceDescriptor() @@ -118,7 +130,11 @@ import Cordova */ open func webViewConfiguration(for instanceConfiguration: InstanceConfiguration) -> WKWebViewConfiguration { let webViewConfiguration = WKWebViewConfiguration() - webViewConfiguration.websiteDataStore.httpCookieStore.add(CapacitorWKCookieObserver()) + let cookieObserver = CapacitorWKCookieObserver() + let cookieStore = webViewConfiguration.websiteDataStore.httpCookieStore + cookieStore.add(cookieObserver) + self.cookieObserver = cookieObserver + self.cookieObserverStore = cookieStore webViewConfiguration.allowsInlineMediaPlayback = true webViewConfiguration.suppressesIncrementalRendering = false webViewConfiguration.allowsAirPlayForMediaPlayback = true