解决 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
。我假设 SPSelfDescribing
是 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 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
。我假设 SPSelfDescribing
是 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项目中。