解决 Kotlin MPP 中的第三方 cocoapod 依赖项

Resolving third party cocoapod dependencies in Kotlin MPP

我正在尝试设置一个用 Kotlin Multiplatform 编写的跟踪库来支持我们所有的移动客户端。

Android 的测试进展顺利(通过 gradle 集成扫雪机)。

我还设法通过 cocoapods 将 Snowplow 集成到 MPP 中。

kotlin {
    ...
    cocoapods {
        ...
        pod("SnowplowTracker") {
            version = "~> 1.3.0"
        }
    }

并在 X64 源集中写下 class:

import cocoapods.SnowplowTracker.*
import com.tracking.domain.model.*

class X64Tracker {

    private val tracker: SPTracker

    init {
        val emitter = SPEmitter.build {
            it?.setUrlEndpoint("our.staging.endpoint")
            it?.setProtocol(SPProtocol.SPProtocolHttps)
        }

        tracker = SPTracker.build {
            emitter?.let { spEmitter -> it?.setEmitter(spEmitter) }
            it?.setBase64Encoded(false)
            it?.setSubject(SPSubject(platformContext = true, andGeoContext = true))
            it?.setAppId("MPP.test")
            it?.setApplicationContext(true)
        }
    }

    fun trackSomething() {
        track(
            eventData = getEventData(
                name = "MPP_test_event",
                appArea = EventArea.Lifecycle,
                action = EventAction.Check,
                objectType = EventObjectType.Device,
                source = EventSource.Client,
                screenName = EventScreenName.Congratulations,
            ), contexts = emptyList()
        )
    }

    private fun track(eventData: SPSelfDescribingJson, contexts: List<SPSelfDescribingJson?>) {
        try {
            val yo = SPSelfDescribing.build {
                it?.setEventData(eventData)
                it?.setContexts(contexts.toMutableList())
            }

            tracker.track(yo)
        } catch (e: IllegalStateException) {
            print("snowplow was not yet initialized when the following event occurred: $eventData")
        }
    }

    private fun getEventData(
        name: String,
        appArea: EventArea,
        action: EventAction,
        objectType: EventObjectType,
        source: EventSource,
        screenName: EventScreenName,
    ) = SPSelfDescribingJson(
        SCHEMA_EVENT, mapOf(
            PROPERTY_EVENT_NAME to name,
            PROPERTY_APP_AREA to appArea.serializedName,
            PROPERTY_ACTION to action.serializedName,
            PROPERTY_OBJECT_TYPE to objectType.serializedName,
            PROPERTY_SOURCE to source.serializedName,
            PROPERTY_SCREEN_NAME to screenName.serializedName,
        )
    )

}

正在编译和构建我们的 .framework 文件。以下是我们的做法:

tasks.register<org.jetbrains.kotlin.gradle.tasks.FatFrameworkTask>("debugFatFramework") {
        baseName = frameworkName + "_sim"
        group = "Universal framework"
        description = "Builds a universal (fat) debug framework"
    
        from(iosX64.binaries.getFramework("DEBUG"))
    }
    
    tasks.register<org.jetbrains.kotlin.gradle.tasks.FatFrameworkTask>("releaseFatFramework") {
        baseName = frameworkName + "_arm"
        group = "Universal framework"
        description = "Builds a universal (release) debug framework"
    
        from(iosArm64.binaries.getFramework("RELEASE"))
    }

然后我们使用以下命令将其合并到一个 .xcframework 文件中:

xcrun xcodebuild -create-xcframework \
    -framework tracking_arm.framework \
    -framework tracking_sim.framework \
    -output tracking.xcframework

我们使用 Carthage 将其集成到我们的主应用程序中,但是当我尝试构建 iOS 项目时,出现以下错误:

Undefined symbols for architecture x86_64:
  "_OBJC_CLASS_$_SPSelfDescribing", referenced from:
      objc-class-ref in tracking_sim(result.o)
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

奇怪的是:无论我在 cocoapods 块中定义哪个版本的 Snowplow - 我的 class 中的语法都不需要更改。即使更新到 Snowplow 2.x 也不需要我去掉 SP 前缀。

我完全不确定如何继续,感谢您的帮助。

以下:

Undefined symbols for architecture x86_64:
  "_OBJC_CLASS_$_SPSelfDescribing", referenced from:
      objc-class-ref in kaiaTracking_sim(result.o)
ld: symbol(s) not found for architecture x86_64

表示链接器找不到 SPSelfDescribing。我假设 SPSelfDescribingSnowplowTracker 的一部分。您需要将 SnowplowTracker 添加到 iOS 应用。

如果您使用 Cocoapods 将 Kotlin 集成到您的 iOS 项目中,则生成的 podspec 将包括 SnowplowTracker 作为依赖项。

由于您没有使用 Cocoapods,因此您需要自己包含它。我们最近不得不为客户弄清楚迦太基。出于多种原因,我会 高度 建议转向 SPM 或 Cocoapods,但这是不同的讨论。要使用 Carthage 添加 SnowplowTracker,请将此添加到您的 Cartfile:

github "snowplow/snowplow-objc-tracker" ~> 1.3

然后当您更新 Carthage 时,将其添加到您的 iOS 项目中。链接器将能够找到它。

明确地说,Undefined symbols for architecture x86_64 错误并不是抱怨 Kotlin。是说找不到SnowplowTracker,需要添加到iOS项目中。