kotlin - 解决 Kotlin MPP 中的第三方 cocoapod 依赖关系

标签 kotlin kotlin-multiplatform carthage xcframework snowplow

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

Android 测试进展顺利(通过 gradle 集成 Snowplow)。

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

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

并在 X64 源集中编写了以下类:

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 block 中定义哪个版本的 Snowplow - 我的类中的语法都不需要更改。即使更新到 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

这表明链接器找不到SPSelfDescription。我假设 SPSelfDescription 是 SnowplowTracker 的一部分。您需要将 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 项目中。

关于kotlin - 解决 Kotlin MPP 中的第三方 cocoapod 依赖关系,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68669421/

相关文章:

android - Coroutine Continuation 在内部是如何工作的?

ios - 意外的 CFBundleExecutable Key(仍然无法解决)

android - 为什么我不能使用 `MutableState` 作为属性委托(delegate)?

Kotlin commonMain 与 java.io.Serializable

ios - 没有单元返回类型的Kotlin多平台Lambda调用

kotlin - Okio native /多平台默认路径

macos - 如何从 OS X 卸载 Carthage?

ios - 如何在我的 iOS 应用程序中调试 carthage(自有)依赖项?

android - 理想的Android Studio Kotlin gitignore

java - Gradle 同步失败 : Could not load class 'org.jetbrains.kotlin.gradle.KotlinGradleModelImpl'