You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为Kotlin多平台iOS模块添加Swift库依赖?求示例项目

How to Add Swift Library Dependencies to iOS Module in Kotlin Multiplatform Project

I get it—adding Java dependencies for Android in KMP is straightforward, but figuring out Swift library integration for iOS can be tricky. The key here is to use CocoaPods as the bridge between your Kotlin Multiplatform project and Swift libraries like SwiftSoup. Below is a complete, runnable configuration and step-by-step breakdown to solve your problem.

Step 1: Update Plugins to Include CocoaPods

First, you need to add the Kotlin CocoaPods plugin to your project. This lets Gradle manage CocoaPods dependencies for your iOS target seamlessly.

Step 2: Configure iOS Target with CocoaPods

Modify your iOS target setup to enable CocoaPods, and declare the SwiftSoup dependency directly in the configuration.

Step 3: Add Expect/Actual Wrappers (Critical!)

Kotlin Native can't directly call Swift code without a bridge. You'll need to define an expect interface in your common source set, then implement it with actual in the iOS source set to wrap SwiftSoup calls (and do the same for Android with Jsoup).

Full Modified build.gradle.kts

Here's your updated build script with all necessary changes:

import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget
val serializationVersion = "0.20.0"
val kotlinVersion = "1.3.72"
plugins {
    kotlin("multiplatform") version kotlinVersion
    kotlin("plugin.serialization") version kotlinVersion
    // Add CocoaPods plugin to handle Swift dependencies
    kotlin("native.cocoapods") version kotlinVersion
}
buildscript {
    dependencies {
        classpath("org.jetbrains.kotlin:kotlin-serialization:$kotlinVersion")
    }
}
repositories {
    jcenter()
    mavenCentral()
}
kotlin {
    // Configure CocoaPods for iOS
    cocoapods {
        summary = "Shared KMP library with HTML parsing capabilities"
        homepage = "https://github.com/your-repo-url"
        ios.deploymentTarget = "13.0"
        // Declare SwiftSoup dependency here
        pod("SwiftSoup") {
            version = "2.6.0" // Use the latest stable version available
        }
    }

    // iOS target configuration (adjusted for CocoaPods integration)
    val iOSTarget: (String, KotlinNativeTarget.() -> Unit) -> KotlinNativeTarget = 
        if (System.getenv("SDK_NAME")?.startsWith("iphoneos") == true) ::iosArm64 else ::iosX64
    iOSTarget("ios") {
        binaries {
            framework {
                baseName = "SharedCode"
            }
        }
    }
    jvm("android")
    sourceSets["commonMain"].dependencies {
        implementation("org.jetbrains.kotlin:kotlin-stdlib-common")
        implementation("org.jetbrains.kotlinx:kotlinx-serialization-runtime-common:$serializationVersion")
    }
    sourceSets["androidMain"].dependencies {
        implementation("org.jetbrains.kotlin:kotlin-stdlib")
        implementation("org.jsoup:jsoup:1.13.1")
        implementation("org.jetbrains.kotlinx:kotlinx-serialization-runtime:$serializationVersion")
    }
    sourceSets["iosMain"].dependencies {
        implementation("org.jetbrains.kotlinx:kotlinx-serialization-runtime-native:$serializationVersion")
    }
}
val packForXcode by tasks.creating(Sync::class) {
    group = "build"
    val mode = System.getenv("CONFIGURATION") ?: "DEBUG"
    val framework = kotlin.targets.getByName<KotlinNativeTarget>("ios").binaries.getFramework(mode)
    inputs.property("mode", mode)
    dependsOn(framework.linkTask)
    val targetDir = File(buildDir, "xcode-frameworks")
    from({ framework.outputDirectory })
    into(targetDir)
    doLast {
        val gradlew = File(targetDir, "gradlew")
        gradlew.writeText("#!/bin/bash\nexport 'JAVA_HOME=${System.getProperty(\"java.home\")}'\ncd '${rootProject.rootDir}'\n./gradlew \$@\n")
        gradlew.setExecutable(true)
    }
}
tasks.getByName("build").dependsOn(packForXcode)

Step 4: Implement Expect/Actual Wrappers

  1. Common Source Set (commonMain):
    Create an HtmlParser.kt file with the platform-agnostic declaration:
expect class HtmlParser {
    fun getDocumentTitle(html: String): String
}
  1. iOS Source Set (iosMain):
    Create the actual implementation that calls SwiftSoup via Kotlin-Swift interop:
import SwiftSoup

actual class HtmlParser {
    actual fun getDocumentTitle(html: String): String {
        return try {
            val doc = SwiftSoup.parse(html)
            doc.title()
        } catch (e: Exception) {
            "Failed to parse title: ${e.localizedDescription}"
        }
    }
}
  1. Android Source Set (androidMain):
    Implement the same interface using Jsoup:
import org.jsoup.Jsoup

actual class HtmlParser {
    actual fun getDocumentTitle(html: String): String {
        val doc = Jsoup.parse(html)
        return doc.title()
    }
}

How to Verify

  1. Sync your Gradle project. The CocoaPods plugin will generate a Podfile and fetch SwiftSoup automatically.
  2. For iOS: Open your Xcode project, and you'll see SwiftSoup listed in the Pods. You can call the HtmlParser from your shared Kotlin code in both Android and iOS targets.
  3. Test the parsing functionality in both platforms to confirm the libraries are working as expected.

内容的提问来源于stack exchange,提问作者Goran Horia Mihail

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 17:52:27