我正在构建一个第三方框架,该框架由一个KMM框架组成,我使用embedAndSignAppleFrameworkForXcode渐变任务将其嵌入并封装在主iOS框架中。这对开发来说是一种魅力,然而,当将具有此框架的应用程序部署到Apple AppStore时,我们得到的信息是:
"无效捆绑包。捆绑包…包含不允许的嵌套捆绑包。">
奇怪的是,这在模拟器上甚至在设备上都能很好地工作。这似乎纯粹是AppStore的限制。我知道解决这个问题的明显方法是将KMM框架部署为完全独立的公共模块,然后强制应用程序将其作为单独的依赖项加载。
有没有其他已知的方法来处理这个问题,这样我就可以将KMM框架作为主要iOS框架的私有依赖项?
我找到的解决方案是放弃embedAndSignAppleFrameworkForXcode
gradle任务,而是编写自己的任务,构建一个静态胖框架并将其链接,但不嵌入它。
从导入FatFrameworkTask和Framework:开始
import org.jetbrains.kotlin.gradle.tasks.FatFrameworkTask
import org.jetbrains.kotlin.gradle.plugin.mpp.Framework
然后在kotlin指令中,创建一个新的FatFrameworkTask,该任务最终将从XCode:运行
tasks.register<FatFrameworkTask>("linkFrameworkForXcode") {
println("LinkFrameworkForXcode")
group = "build"
val configuration = (System.getenv("CONFIGURATION")
val platform = System.getenv("PLATFORM_NAME")
val archList = System.getenv("ARCHS").split(" ")
println("Configuration $configuration")
println("Platform $platform")
println("Architecture $archList")
val targetMap = mapOf(
"iphonesimulatorx86_64" to <replace with iosX64 target>,
"iphonesimulatorarm64" to <replace with iosSimulatorArm64 target>,
"iphoneosarm64" to <replace with iosArm64 target>,
"iphoneosarm32" to <replace with iosArm32 target>)
val frameworks = mutableListOf<Framework>()
for (arch in archList) {
val nativeTarget = targetMap["$platform$arch"]
if (nativeTarget != null) {
frameworks.add(nativeTarget.binaries.getFramework(configuration))
} else {
println ("Error: No mapping for architecture $platform $arch")
}
}
destinationDir = buildDir.resolve("xcode-frameworks/$configuration")
println("Destination: $destinationDir")
from(frameworks)
}
对于targetMap
,请确保将尖括号替换为您为kmm项目创建的iOS目标的参考。这将确保Xcode请求的任何/所有目标在构建时根据需要合并到一个胖框架中。
既然我们不想嵌入kmm框架,我们应该将框架设置为静态的。在二进制文件块中:
binaries {
framework {
isStatic = true
}
}
接下来,打开Xcode项目的构建设置。设置其他链接器标志:-framework shared
。这里共享的是您的框架的名称,它在KMM模块的build.gradle(.kts(文件中配置。此外,在生成设置中,设置框架搜索路径:$(SRCROOT)/../shared/build/xcode-frameworks/$(CONFIGURATION)
。确保根据需要更改路径以指向KMM模块的构建文件夹。
最后,在构建阶段中添加一个新的"运行脚本"阶段。这应该出现在"将二进制与库链接"阶段之前。使用这个调用渐变并运行我们刚刚创建的任务:
cd <path-to-kmm-project>
./gradlew :shared:linkFrameworkForXcode
在清理和构建之后,你应该有一个与你的KMM模块链接的框架,并准备在应用程序中部署到AppStore。