kotlin/kotlin-agent-skillsApache-2.06 files

Kotlin Tooling Cocoapods Spm Migration

Migrate KMP projects from CocoaPods (kotlin("native.cocoapods")) to Swift Package Manager (swiftPMDependencies DSL) — replaces pod() with swiftPackage(), transforms cocoapods.* imports to swiftPMImport.*, and reconfigures the Xcode project.

Specification
Skill ID
kotlin/kotlin-agent-skills/kotlin-tooling-cocoapods-spm-migration
Publisher
kotlin
Repository
kotlin-agent-skills
Installs
0
Files
6
License
Apache-2.0
Synced
Sep 23, 2026
How to use it

Open any RiverX project, open the Skills panel in the chat, and search for this identifier. The files are fetched from the source repository at install time.

kotlin/kotlin-agent-skills/kotlin-tooling-cocoapods-spm-migrationInstalls these files
  • SKILL.md
  • references/cocoapods-extras-patterns.md
  • references/common-pods-mapping.md
  • references/dsl-reference.md
  • references/migration-report-template.md
  • references/troubleshooting.md

What this skill tells the agent

CocoaPods to SwiftPM Migration for KMP

Migrate Kotlin Multiplatform projects from kotlin("native.cocoapods") to swiftPMDependencies {} DSL.

Requirements

  • Kotlin: 2.4.0-Beta2 or later (first public release with swiftPMDependencies support, available on Maven Central)
  • Xcode: 16.4 or 26.0+
  • iOS Deployment Target: 16.0+ recommended

Migration Overview

IMPORTANT: Keep the cocoapods {} block and plugin active until Phase 6. The migration adds swiftPMDependencies {} alongside the existing CocoaPods setup first, reconfigures Xcode, and only then removes CocoaPods.

PhaseAction
1Analyze existing CocoaPods configuration
2Update Gradle configuration (repos, Kotlin version)
3Add swiftPMDependencies {} alongside existing cocoapods {}
4Transform Kotlin imports
5Reconfigure iOS project and deintegrate CocoaPods
6Remove CocoaPods plugin from Gradle
7Verify Gradle build and Xcode project build
8Write MIGRATION_REPORT.md

Phase 1: Pre-Migration Analysis

1.0 Verify the project builds

Before starting migration, identify the module to migrate and confirm it compiles successfully.

  1. Find the module that uses CocoaPods — look for build.gradle.kts files containing cocoapods: ``bash grep -rl "cocoapods" --include="build.gradle.kts" . ` Extract the module name from the path (e.g., ./shared/build.gradle.kts → module name is shared). Note: multiple modules may use CocoaPods — record all of them. Typically only the module that produces the framework linked into the iOS app needs swiftPMDependencies`; the others only need CocoaPods removed (Phase 6).
  1. Compile Kotlin code — run the Kotlin compilation task for that module to verify the Kotlin source compiles: ``bash ./gradlew :moduleName:compileKotlinIosSimulatorArm64 ` Replace moduleName with the directory name of the module (e.g., :shared:compileKotlinIosSimulatorArm64). This is faster than a full build` (which also runs release linkage) and sufficient to verify Kotlin code correctness.
  1. Build the iOS app (optional) — try to locate the Xcode project and build it to confirm the full app compiles: ``bash # Find the Xcode project find . -name "*.xcworkspace" -not -path "*/Pods/*" -maxdepth 2 # Build (replace scheme name with the actual app scheme) cd /path/to/iosApp xcodebuild -workspace *.xcworkspace -scheme "<AppScheme>" -destination 'generic/platform=iOS Simulator' ARCHS=arm64 `` If the user wants to skip the Xcode build or no Xcode project is found, proceed without it — the Kotlin compilation from step 2 is sufficient to continue.
  1. If the Kotlin compilation fails, ask the user to either:
  • Provide the correct Gradle command to verify the module builds, or
  • Confirm the module is in a working state and it's safe to proceed

If the user confirms without providing a build command, record that the pre-migration build could not be verified and warn about this at the end of migration (Phase 7).

1.0a Confirm Kotlin version with Swift Import support

Read the current Kotlin version from gradle/libs.versions.toml (or build.gradle.kts).

If the project already uses Kotlin 2.4.0-Beta2 or later → record the version and skip Phase 2.1 (no version change needed).

If the project uses an older Kotlin version → Phase 2.1 will upgrade it to 2.4.0-Beta2 (the first public release with swiftPMDependencies support, available on Maven Central — no custom repository needed). Warn the user: "⚠️ Kotlin version jump — upgrading across minor versions can introduce breaking changes unrelated to this migration. Recommended: update first, verify it builds, then re-run this migration." If the user confirms, proceed.

1.1 Check for deprecated CocoaPods workaround property

Search gradle.properties for the deprecated property:

kotlin.apple.deprecated.allowUsingEmbedAndSignWithCocoaPodsDependencies=true

This property was a workaround (see KT-64096) for projects using embedAndSign alongside CocoaPods dependencies. It suppresses an error about unsupported configurations that can cause runtime crashes or symbol duplication. After migrating to SwiftPM import, this property is no longer needed and must be removed in Phase 6. Record its presence if found.

1.2 Check for EmbedAndSign disablers

Search all build.gradle.kts files for code that disables EmbedAndSign tasks (e.g., TaskGraph.whenReady filters, tasks.matching blocks). This is a CocoaPods-era workaround that breaks the migration because integrateEmbedAndSign (needed in Phase 5) gets disabled too. Record any such code — it must be removed in Phase 6, and may need to be removed earlier. See troubleshooting.md § "integrateEmbedAndSign Skipped" for patterns.

1.3 Check for third-party KMP libraries with bundled cinterop klibs

Some KMP libraries ship pre-built cinterop klibs with cocoapods.* package namespaces. After migration, the swiftPMDependencies cinterop generator detects these existing bindings and skips generating new bindings for those Clang modules to avoid duplicates. This means cocoapods.* imports for those modules must be kept as-is — they resolve to the third-party library's bundled klib, not to actual CocoaPods.

*Known libraries with bundled `cocoapods.` klibs:**

LibraryMaven artifactBundled klib namespaceClasses provided
KMPNotifierio.github.mirzemehdi:kmpnotifiercocoapods.FirebaseMessagingFIRMessaging, FIRMessagingAPNSTokenType, etc.

How to detect: Search Gradle dependency declarations for known libraries, then cross-reference their bundled namespaces against the import cocoapods.* statements found in step 4. Mark any matches — these imports will NOT be transformed in Phase 4.

If unsure whether a third-party KMP library bundles cinterop klibs, check if it has a linkOnly = true pod dependency in the project — this is a strong indicator that the library provides its own klib for those classes.

To inspect klib contents and verify bundled bindings, see troubleshooting.md § "Third-Party KMP Libraries with Bundled Klibs".

Find and record:

  1. CocoaPods configuration - Search for cocoapods in build.gradle.kts files
  2. Pod dependencies - Extract pod names, versions from cocoapods {} blocks
  3. Framework configuration - Record baseName, isStatic, deployment target from cocoapods.framework {}
  4. linkOnly pods - Record pods declared with linkOnly = true. These have two common patterns:
  • KMP wrapper libraries (e.g., dev.gitlive:firebase-*): the wrapper provides Kotlin APIs, and the pod is only linked. See common-pods-mapping.md for implications.
  • Multi-module projects: the consuming module declares linkOnly = true because a child module already provides cinterop bindings for that pod. In SwiftPM, the swiftPackage() declaration should go only in the child module that uses the pod directly. The consuming module must NOT redeclare the same packages — it only needs a swiftPMDependencies {} block without those packages (or an empty one if all pods were linkOnly). Import namespace implication: when the consuming module imports SPM classes that come from a child module's swiftPMDependencies, the import path uses the child module's group and name as the namespace (see Phase 4 Import Namespace Formula).

Use this skill in a project

Open any RiverX project, search the Skills panel for kotlin/kotlin-agent-skills/kotlin-tooling-cocoapods-spm-migration, and install it in one click.

Use this skill