From ca71b82df14730199b469614f64fa996aa9ec9c4 Mon Sep 17 00:00:00 2001 From: Andre Destro Date: Tue, 11 Aug 2026 16:43:09 +0100 Subject: [PATCH 1/3] docs: add Capacitor 9 app upgrade guide Covers app-level changes only (Cordova-optional, CLI, Android/iOS breaking changes, upgrade steps, plugin summary). Deprecated-API removal tables and the plugin-author guide are tracked separately (RMET-4728, RMET-5321). RMET-5320 --- docs/main/updating/9-0.md | 261 ++++++++++++++++++++++++++++++++++++++ sidebars.js | 1 + 2 files changed, 262 insertions(+) create mode 100644 docs/main/updating/9-0.md diff --git a/docs/main/updating/9-0.md b/docs/main/updating/9-0.md new file mode 100644 index 00000000..d1a47d02 --- /dev/null +++ b/docs/main/updating/9-0.md @@ -0,0 +1,261 @@ +--- +title: Updating to 9.0 +description: Guide for updating Capacitor from v8 to v9 in your app +slug: /updating/9-0 +--- + +# Updating from Capacitor 8 to Capacitor 9 + +In this guide, you'll find steps to update your project to the current Capacitor 9 version as well as a list of breaking changes for our official plugins. + +:::note +This guide covers app-level changes. If you maintain a Capacitor plugin, see the "Updating plugins to 9.0" guide instead. +::: + +## Cordova support is now optional + +Capacitor's Cordova compatibility layer is now only included in your app when your project actually has a Cordova plugin installed. Previously, the native Cordova runtime (the `capacitor-cordova-android` Gradle module and plugins module on Android, and the `CapacitorCordova` CocoaPods pod / SPM product on iOS) was always bundled into every app, whether or not it used any Cordova plugins. + +Running `npx cap sync` (or `update`) now detects whether any installed plugin is a Cordova plugin and only wires in the Cordova runtime when one is found. If your project has no Cordova plugins, you'll notice: + +- On Android, the generated `settings.gradle` and app `build.gradle` no longer include the `capacitor-cordova-android` / `capacitor-cordova-android-plugins` modules. +- On iOS, `CapacitorCordova` is no longer added to your `Podfile` or `Package.swift`. + +There is currently no configuration option to force-include the Cordova runtime when no Cordova plugin is present. If your app's native code (or a plugin you maintain) directly references symbols from Capacitor's Cordova compatibility layer — for example `com.getcapacitor.cordova.CordovaPlugin` on Android, or anything from the `CapacitorCordova` pod/product on iOS — without having an actual Cordova plugin installed, those references will fail to resolve after upgrading. Add a Cordova plugin dependency (even a trivial one) if you need the layer present, or remove the direct reference. + +## Breaking changes in @capacitor/cli + +`cap run`'s separate live-reload flags (`--live-reload`/`-l`, `--host`, `--port`, `--https`) have been merged into a single `--url` flag. Instead of: + +```sh +npx cap run android -l --host 192.168.1.181 --port 5173 +``` + +pass the full URL your dev server printed (Vite, webpack, etc.) directly: + +```sh +npx cap run android --url http://192.168.1.181:5173 +``` + +## Breaking changes in @capacitor/android + +`minSdkVersion` is now `26` (Android 8.0), and `compileSdkVersion`/`targetSdkVersion` are now `37` (Android 17). + +AGP 9 no longer ships `proguard-android.txt` — any `build.gradle` that still references it fails at Gradle configuration time, even with `minifyEnabled false`: + +```groovy +// Before — hard build error on AGP 9 +proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' +// After +proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' +``` + +`androidx.core:core` 1.19.0 merges every extension function previously shipped in `core-ktx` into `core` itself, turning `core-ktx` into an empty compatibility artifact. If your app (or an old/community plugin it depends on) still explicitly pins `core-ktx` to a version older than `1.19.0`, you may hit a duplicate class error at build time; remove the explicit `core-ktx` version override. + +AGP 9 also bundles the Kotlin Gradle Plugin natively and removes the `jcenter()` repository helper entirely. These are unlikely to affect your app directly, but can break the build if you (or a legacy/community plugin) still apply Kotlin standalone or reference `jcenter()` — see [Update Kotlin and remove jcenter()](#update-kotlin-and-remove-jcenter) below. + +## Breaking changes in @capacitor/ios + +The minimum iOS deployment target is now `16.0` (previously `15.0`). + +If you're updating from Capacitor 8.4 or earlier, you also need to adopt the iOS UIScene lifecycle, which Xcode 27 requires — see [Updating to 8.5](/main/updating/8-5.md) for the full steps. Apps already on 8.5 have nothing further to do here. + +New iOS projects created with `npx cap add ios` now use `@main` instead of the deprecated `@UIApplicationMain` attribute on `AppDelegate`. This doesn't change existing apps automatically, but Swift 6 (bundled with Xcode 27) rejects the deprecated attribute — if your `AppDelegate.swift` still declares `@UIApplicationMain`, replace it with `@main`. + +## NodeJS 24+ + +Capacitor 9 requires NodeJS 24 or greater. (Latest LTS version is recommended.) + +## Using the CLI to Migrate + +Capacitor 9 hasn't reached general availability yet, so install the `next` version of the Capacitor CLI to your project (once 9.0.0 is generally available, use `@latest` instead): + +```sh +npm i -D @capacitor/cli@next +``` + +Once installed, simply run the following to have the CLI handle the migration for you. + +```sh +npx cap migrate +``` + +If any of the steps for the migration are not able to be completed, additional information will be made available in the output in the terminal. The steps for doing the migration manually are listed out below. + +## iOS + +The following guide describes how to upgrade your Capacitor 8 iOS project to Capacitor 9. + +### Upgrade Xcode + +Capacitor 9 requires Xcode 27 or newer. + +### Raise iOS Deployment Target + +Do the following for your Xcode project: select the **Project** within the project editor and open the **Build Settings** tab. Under the **Deployment** section, change **iOS Deployment Target** to **iOS 16.0**. Repeat the same steps for any app **Targets**. + +Then, if the project is using CocoaPods, open `ios/App/Podfile` and update the iOS version to 16.0: + +```ruby +platform :ios, '16.0' +``` + +:::note +CocoaPods Trunk is expected to become read-only later in 2026. If you haven't already, consider migrating your app to SPM, which is the default for new Capacitor projects. +::: + +## Android + +The following guide describes how to upgrade your Capacitor 8 Android project to Capacitor 9. + +### Upgrade Android Studio + +Capacitor 9 requires Android Studio 2025.3.3 or newer. + +Once it's updated, Android Studio can assist with some of the updates related to gradle. To start, run `Tools -> AGP Upgrade Assistant` and choose `9.2.1` as the version to update on dropdown. Then click `Run selected steps`. + +![APG Upgrade Assistant](../../../static/img/v6/docs/android/agp-upgrade-assistant.png) + +### Update Android Project Variables + +In your `variables.gradle` file, update your values to the following new minimums + +```groovy +minSdkVersion = 26 +compileSdkVersion = 37 +targetSdkVersion = 37 +androidxActivityVersion = '1.13.0' +androidxAppCompatVersion = '1.7.1' +androidxCoordinatorLayoutVersion = '1.3.0' +androidxCoreVersion = '1.19.0' +androidxFragmentVersion = '1.8.9' +coreSplashScreenVersion = '1.2.0' +androidxWebkitVersion = '1.16.0' +junitVersion = '4.13.2' +androidxJunitVersion = '1.3.0' +androidxEspressoCoreVersion = '3.7.0' +cordovaAndroidVersion = '15.0.0' +``` + +### Rename the default ProGuard file + +AGP 9 removed `proguard-android.txt`. In your `app/build.gradle`, replace it with `proguard-android-optimize.txt`, which also enables ProGuard optimizations: + +```diff +buildTypes { + release { + minifyEnabled false +- proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' ++ proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } +} +``` + +### Update Kotlin and remove jcenter() + +AGP 9 bundles the Kotlin Gradle Plugin natively (Kotlin `2.2.10`) instead of requiring it to be applied as a separate plugin. If your `build.gradle` still applies `kotlin-android` directly or declares a standalone `kotlin-stdlib`/`kotlin-gradle-plugin` dependency, remove them — keeping them alongside AGP 9's built-in Kotlin causes a duplicate-plugin build failure: + +```diff +buildscript { + dependencies { + classpath 'com.android.tools.build:gradle:9.2.1' +- classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.10" + } +} +-apply plugin: 'kotlin-android' + +dependencies { +- implementation "org.jetbrains.kotlin:kotlin-stdlib:1.9.10" +} +``` + +Gradle 9 also fully removes the `jcenter()` repository helper (redirected to Maven Central since 2024). Any `build.gradle` that still calls it fails at Gradle configuration time: + +```diff +repositories { + google() +- jcenter() ++ mavenCentral() +} +``` + +### Update google services plugin + +```diff +# build.gradle + + dependencies { + classpath 'com.android.tools.build:gradle:9.2.1' +- classpath 'com.google.gms:google-services:4.4.4' ++ classpath 'com.google.gms:google-services:4.5.0' + +``` + +### Update gradle plugin to 9.2.1 + +```diff +# build.gradle + + dependencies { +- classpath 'com.android.tools.build:gradle:8.13.0' ++ classpath 'com.android.tools.build:gradle:9.2.1' + +``` + +### Update gradle wrapper to 9.5.1 + +```diff +# gradle-wrapper.properties + +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +- distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.3-all.zip ++ distributionUrl=https\://services.gradle.org/distributions/gradle-9.5.1-all.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +``` + +## Plugins + +Plugins have been updated to version 9.0.0, make sure to update them to use latest version. + +The following plugin functionality has been modified or removed. Update your code accordingly. + +### Action Sheet + +- `androidxMaterialVersion` variable has been updated to `1.14.0`. + +### Browser + +- `androidxBrowserVersion` variable has been updated to `1.10.0`. + +### Barcode Scanner + +- Native Android dependencies have been updated to their latest versions. + +### Camera + +- Native Android dependencies have been updated to their latest versions. + +### Geolocation + +- Native Android dependencies have been updated to their latest versions. + +### Google Maps + +- `kotlinxCoroutinesVersion` variable has been updated to `1.11.0`. +- `googleMapsPlayServicesVersion` variable has been updated to `20.0.0`. +- `googleMapsUtilsVersion` variable has been updated to `5.0.0`. +- `googleMapsKtxVersion` and `googleMapsUtilsKtxVersion` variables have been updated to `6.0.1`. + +### InAppBrowser + +- Native Android dependencies have been updated to their latest versions. + +### Push Notifications + +The deprecated `alert` presentation option is no longer supported on iOS. Use `banner` and/or `list` instead. + +### Splash Screen + +The default value of `launchFadeOutDuration` on Android has changed from `200` to `0`, since the previous default could block UI changes made immediately after `SplashScreen.hide()`. If your app relies on the previous 200ms fade-out animation, set `launchFadeOutDuration: 200` explicitly in your Capacitor config. diff --git a/sidebars.js b/sidebars.js index e29ff7ec..5030da0b 100644 --- a/sidebars.js +++ b/sidebars.js @@ -32,6 +32,7 @@ module.exports = { label: 'Upgrade Guides', collapsed: false, items: [ + 'main/updating/9-0', 'main/updating/8-5', 'main/updating/8-0', 'main/updating/plugins/8-0', From ebfdea3e9480052ebd9c4244772eca91f08e9fa2 Mon Sep 17 00:00:00 2001 From: Andre Destro Date: Fri, 14 Aug 2026 10:44:56 +0100 Subject: [PATCH 2/3] docs: address PR review feedback on Cap9 app upgrade guide - Move "Using the CLI to Migrate" above the breaking-changes sections that cap migrate automates (Android/iOS), so readers try it first - Trim duplicated proguard/kotlin/jcenter details from the @capacitor/android summary, add a dedicated core-ktx-to-core section - Note npm 11 ships with Node 24 (vs npm 10 with Node 22) - Use the exact CocoaPods Trunk read-only date and link to the SPM guide - Document removing targetSdkVersion from the app's build.gradle - Fix the Kotlin removal example to start from 2.2.20, not 1.9.10 - Fill in and alphabetize per-plugin variable bumps (Barcode Scanner, Camera, Geolocation, InAppBrowser) instead of vague placeholders Addresses review comments from @OS-pedrogustavobilro on PR #589. --- docs/main/updating/9-0.md | 88 +++++++++++++++++++++++---------------- 1 file changed, 52 insertions(+), 36 deletions(-) diff --git a/docs/main/updating/9-0.md b/docs/main/updating/9-0.md index d1a47d02..8013e96c 100644 --- a/docs/main/updating/9-0.md +++ b/docs/main/updating/9-0.md @@ -37,34 +37,9 @@ pass the full URL your dev server printed (Vite, webpack, etc.) directly: npx cap run android --url http://192.168.1.181:5173 ``` -## Breaking changes in @capacitor/android - -`minSdkVersion` is now `26` (Android 8.0), and `compileSdkVersion`/`targetSdkVersion` are now `37` (Android 17). - -AGP 9 no longer ships `proguard-android.txt` — any `build.gradle` that still references it fails at Gradle configuration time, even with `minifyEnabled false`: - -```groovy -// Before — hard build error on AGP 9 -proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' -// After -proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' -``` - -`androidx.core:core` 1.19.0 merges every extension function previously shipped in `core-ktx` into `core` itself, turning `core-ktx` into an empty compatibility artifact. If your app (or an old/community plugin it depends on) still explicitly pins `core-ktx` to a version older than `1.19.0`, you may hit a duplicate class error at build time; remove the explicit `core-ktx` version override. - -AGP 9 also bundles the Kotlin Gradle Plugin natively and removes the `jcenter()` repository helper entirely. These are unlikely to affect your app directly, but can break the build if you (or a legacy/community plugin) still apply Kotlin standalone or reference `jcenter()` — see [Update Kotlin and remove jcenter()](#update-kotlin-and-remove-jcenter) below. - -## Breaking changes in @capacitor/ios - -The minimum iOS deployment target is now `16.0` (previously `15.0`). - -If you're updating from Capacitor 8.4 or earlier, you also need to adopt the iOS UIScene lifecycle, which Xcode 27 requires — see [Updating to 8.5](/main/updating/8-5.md) for the full steps. Apps already on 8.5 have nothing further to do here. - -New iOS projects created with `npx cap add ios` now use `@main` instead of the deprecated `@UIApplicationMain` attribute on `AppDelegate`. This doesn't change existing apps automatically, but Swift 6 (bundled with Xcode 27) rejects the deprecated attribute — if your `AppDelegate.swift` still declares `@UIApplicationMain`, replace it with `@main`. - ## NodeJS 24+ -Capacitor 9 requires NodeJS 24 or greater. (Latest LTS version is recommended.) +Capacitor 9 requires NodeJS 24 or greater. (Latest LTS version is recommended.) Node 24 also comes with npm 11 by default, as opposed to npm 10 with Node 22. ## Using the CLI to Migrate @@ -82,6 +57,20 @@ npx cap migrate If any of the steps for the migration are not able to be completed, additional information will be made available in the output in the terminal. The steps for doing the migration manually are listed out below. +## Breaking changes in @capacitor/android + +`minSdkVersion` is now `26` (Android 8.0), and `compileSdkVersion`/`targetSdkVersion` are now `37` (Android 17). + +AGP 9 no longer ships `proguard-android.txt`, `androidx.core:core` 1.19.0 folds `core-ktx` into itself, AGP 9 bundles the Kotlin Gradle Plugin natively, and Gradle 9 fully removes `jcenter()`. These rarely affect an app directly, unless you (or an old/community plugin) still reference the old proguard filename, pin an old `core-ktx` version, apply Kotlin standalone, or reference `jcenter()` — see [Rename the default ProGuard file](#rename-the-default-proguard-file), [Migrate core-ktx to core](#migrate-core-ktx-to-core), and [Update Kotlin and remove jcenter()](#update-kotlin-and-remove-jcenter) below. + +## Breaking changes in @capacitor/ios + +The minimum iOS deployment target is now `16.0` (previously `15.0`). + +If you're updating from Capacitor 8.4 or earlier, you also need to adopt the iOS UIScene lifecycle, which Xcode 27 requires — see [Updating to 8.5](/main/updating/8-5.md) for the full steps. Apps already on 8.5 have nothing further to do here. + +New iOS projects created with `npx cap add ios` now use `@main` instead of the deprecated `@UIApplicationMain` attribute on `AppDelegate`. This doesn't change existing apps automatically, but Swift 6 (bundled with Xcode 27) rejects the deprecated attribute — if your `AppDelegate.swift` still declares `@UIApplicationMain`, replace it with `@main`. + ## iOS The following guide describes how to upgrade your Capacitor 8 iOS project to Capacitor 9. @@ -101,7 +90,7 @@ platform :ios, '16.0' ``` :::note -CocoaPods Trunk is expected to become read-only later in 2026. If you haven't already, consider migrating your app to SPM, which is the default for new Capacitor projects. +CocoaPods Trunk is expected to become read-only on December 2, 2026. If you haven't already, consider [migrating your app to SPM](/main/ios/spm.md#using-spm-in-an-existing-capacitor-project), which is the default for new Capacitor projects. ::: ## Android @@ -137,6 +126,20 @@ androidxEspressoCoreVersion = '3.7.0' cordovaAndroidVersion = '15.0.0' ``` +### Remove targetSdkVersion from your app's build.gradle + +AGP 9 infers `targetSdkVersion` from `compileSdkVersion` when it isn't set explicitly. The Capacitor template no longer sets it in the app's `build.gradle` (it's kept in `variables.gradle` only for reference and for plugins that still read it). This isn't a mandatory change, but `cap migrate` does it, and it's worth keeping your app aligned with the template: + +```diff +defaultConfig { + applicationId "com.getcapacitor.app" + minSdkVersion rootProject.ext.minSdkVersion +- targetSdkVersion rootProject.ext.targetSdkVersion + versionCode 1 + versionName "1.0" +} +``` + ### Rename the default ProGuard file AGP 9 removed `proguard-android.txt`. In your `app/build.gradle`, replace it with `proguard-android-optimize.txt`, which also enables ProGuard optimizations: @@ -151,6 +154,17 @@ buildTypes { } ``` +### Migrate core-ktx to core + +`androidx.core:core` 1.19.0 merges every extension function previously shipped in `core-ktx` into `core` itself, turning `core-ktx` into an empty compatibility artifact. If your app (or an old/community plugin it depends on) still explicitly depends on `core-ktx` with a version older than `1.19.0`, you may hit a duplicate class error at build time; remove it, or depend on `core` instead: + +```diff +dependencies { +- implementation "androidx.core:core-ktx:1.17.0" ++ implementation "androidx.core:core:1.19.0" +} +``` + ### Update Kotlin and remove jcenter() AGP 9 bundles the Kotlin Gradle Plugin natively (Kotlin `2.2.10`) instead of requiring it to be applied as a separate plugin. If your `build.gradle` still applies `kotlin-android` directly or declares a standalone `kotlin-stdlib`/`kotlin-gradle-plugin` dependency, remove them — keeping them alongside AGP 9's built-in Kotlin causes a duplicate-plugin build failure: @@ -159,13 +173,13 @@ AGP 9 bundles the Kotlin Gradle Plugin natively (Kotlin `2.2.10`) instead of req buildscript { dependencies { classpath 'com.android.tools.build:gradle:9.2.1' -- classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.10" +- classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:2.2.20" } } -apply plugin: 'kotlin-android' dependencies { -- implementation "org.jetbrains.kotlin:kotlin-stdlib:1.9.10" +- implementation "org.jetbrains.kotlin:kotlin-stdlib:2.2.20" } ``` @@ -225,21 +239,23 @@ The following plugin functionality has been modified or removed. Update your cod - `androidxMaterialVersion` variable has been updated to `1.14.0`. -### Browser +### Barcode Scanner -- `androidxBrowserVersion` variable has been updated to `1.10.0`. +- `kotlinxCoroutinesVersion` variable has been updated to `1.11.0`. -### Barcode Scanner +### Browser -- Native Android dependencies have been updated to their latest versions. +- `androidxBrowserVersion` variable has been updated to `1.10.0`. ### Camera -- Native Android dependencies have been updated to their latest versions. +- `androidxExifInterfaceVersion` variable has been updated to `1.4.2`. +- `androidxMaterialVersion` variable has been updated to `1.14.0`. ### Geolocation -- Native Android dependencies have been updated to their latest versions. +- `playServicesLocationVersion` variable has been updated to `21.4.0`. +- `kotlinxCoroutinesVersion` variable has been updated to `1.11.0`. ### Google Maps @@ -250,7 +266,7 @@ The following plugin functionality has been modified or removed. Update your cod ### InAppBrowser -- Native Android dependencies have been updated to their latest versions. +- `androidxBrowserVersion` variable has been updated to `1.10.0`. ### Push Notifications From 2aa8f3b980a058abf122a6c1e9319788d8b5ac38 Mon Sep 17 00:00:00 2001 From: Andre Destro Date: Fri, 14 Aug 2026 12:40:27 +0100 Subject: [PATCH 3/3] docs: keep breaking-changes sections to non-automated changes only Per PR feedback: "Breaking changes in @capacitor/X" should only list what cap migrate doesn't already fix. Removes minSdk/compileSdk and the proguard rename from the Android section (fully covered by "Update Android Project Variables" / "Rename the default ProGuard file" below), and removes the deployment target / @main mentions from the iOS section (covered by "Raise iOS Deployment Target" and the new "Replace @UIApplicationMain with @main" step). Also trims the targetSdkVersion removal note down to a single sentence. --- docs/main/updating/9-0.md | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/docs/main/updating/9-0.md b/docs/main/updating/9-0.md index 8013e96c..4e3013d5 100644 --- a/docs/main/updating/9-0.md +++ b/docs/main/updating/9-0.md @@ -59,18 +59,12 @@ If any of the steps for the migration are not able to be completed, additional i ## Breaking changes in @capacitor/android -`minSdkVersion` is now `26` (Android 8.0), and `compileSdkVersion`/`targetSdkVersion` are now `37` (Android 17). - -AGP 9 no longer ships `proguard-android.txt`, `androidx.core:core` 1.19.0 folds `core-ktx` into itself, AGP 9 bundles the Kotlin Gradle Plugin natively, and Gradle 9 fully removes `jcenter()`. These rarely affect an app directly, unless you (or an old/community plugin) still reference the old proguard filename, pin an old `core-ktx` version, apply Kotlin standalone, or reference `jcenter()` — see [Rename the default ProGuard file](#rename-the-default-proguard-file), [Migrate core-ktx to core](#migrate-core-ktx-to-core), and [Update Kotlin and remove jcenter()](#update-kotlin-and-remove-jcenter) below. +`androidx.core:core` 1.19.0 folds `core-ktx` into itself, and AGP 9 bundles the Kotlin Gradle Plugin natively while Gradle 9 fully removes `jcenter()`. These rarely affect an app directly, unless you (or an old/community plugin) still pin an old `core-ktx` version, apply Kotlin standalone, or reference `jcenter()` — see [Migrate core-ktx to core](#migrate-core-ktx-to-core) and [Update Kotlin and remove jcenter()](#update-kotlin-and-remove-jcenter) below. ## Breaking changes in @capacitor/ios -The minimum iOS deployment target is now `16.0` (previously `15.0`). - If you're updating from Capacitor 8.4 or earlier, you also need to adopt the iOS UIScene lifecycle, which Xcode 27 requires — see [Updating to 8.5](/main/updating/8-5.md) for the full steps. Apps already on 8.5 have nothing further to do here. -New iOS projects created with `npx cap add ios` now use `@main` instead of the deprecated `@UIApplicationMain` attribute on `AppDelegate`. This doesn't change existing apps automatically, but Swift 6 (bundled with Xcode 27) rejects the deprecated attribute — if your `AppDelegate.swift` still declares `@UIApplicationMain`, replace it with `@main`. - ## iOS The following guide describes how to upgrade your Capacitor 8 iOS project to Capacitor 9. @@ -89,6 +83,16 @@ Then, if the project is using CocoaPods, open `ios/App/Podfile` and update the i platform :ios, '16.0' ``` +### Replace @UIApplicationMain with @main + +Swift 6 (bundled with Xcode 27) rejects the deprecated `@UIApplicationMain` attribute. If your `AppDelegate.swift` still declares it, replace it with `@main`: + +```diff +-@UIApplicationMain ++@main +class AppDelegate: UIResponder, UIApplicationDelegate { +``` + :::note CocoaPods Trunk is expected to become read-only on December 2, 2026. If you haven't already, consider [migrating your app to SPM](/main/ios/spm.md#using-spm-in-an-existing-capacitor-project), which is the default for new Capacitor projects. ::: @@ -128,7 +132,7 @@ cordovaAndroidVersion = '15.0.0' ### Remove targetSdkVersion from your app's build.gradle -AGP 9 infers `targetSdkVersion` from `compileSdkVersion` when it isn't set explicitly. The Capacitor template no longer sets it in the app's `build.gradle` (it's kept in `variables.gradle` only for reference and for plugins that still read it). This isn't a mandatory change, but `cap migrate` does it, and it's worth keeping your app aligned with the template: +AGP 9 infers `targetSdkVersion` from `compileSdkVersion` when it isn't set explicitly, therefore you can remove it: ```diff defaultConfig {