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

iOS集成Kotlin Multiplatform库时遇MissingResourceException问题

解决方案:KMP库资源打包进XCFramework(SPM兼容)

一、原生Compose资源打包配置

如果要直接用JetBrains Compose的资源系统解决问题,需要在KMP库的Gradle配置中明确指定资源目录,并确保XCFramework打包时包含这些资源:

1. Gradle资源配置

在库的build.gradle.kts中,给iOS相关SourceSet添加资源目录,并在Framework配置中声明资源包含规则:

kotlin {
    // 声明iOS目标
    iosX64()
    iosArm64()
    iosSimulatorArm64()

    sourceSets {
        val commonMain by getting {
            // 共享资源目录
            resources.srcDir("src/commonMain/resources")
        }
        val iosMain by getting {
            // iOS专属资源目录(可选)
            resources.srcDir("src/iosMain/resources")
        }
    }

    targets.withType<org.jetbrains.kotlin.gradle.plugin.mpp.Framework> {
        baseName = "YourSharedLibrary"
        isStatic = true // SPM更适配静态框架

        binaries.all {
            // 配置资源打包规则,按需调整include路径
            resources {
                from("src/commonMain/resources") {
                    include("drawable/**")
                    include("strings/**")
                }
                from("src/iosMain/resources")
            }
        }
    }
}

2. iOS端资源初始化

iOS项目中,在创建Compose视图前必须初始化资源,否则会抛出MissingResourceException:

import YourSharedLibrary

// 在创建Compose视图前执行
ResourcesKt.initializeResources()

// 加载Compose组件
let composeVC = ComposeUIViewController {
    YourSharedComposable()
}

二、SPM兼容的替代方案:moko-resources(支持库场景)

你之前的调研有误——moko-resources完全支持KMP库开发,且能自动处理跨平台资源打包,无需依赖CocoaPods:

1. 库中配置moko-resources

在build.gradle.kts中添加插件和依赖:

plugins {
    id("dev.icerock.mobile.multiplatform-resources") version "0.23.0"
}

kotlin {
    // ... iOS目标配置

    sourceSets {
        val commonMain by getting {
            dependencies {
                implementation("dev.icerock.moko:resources:0.23.0")
                implementation("dev.icerock.moko:resources-compose:0.23.0") // 配合Compose使用
            }
        }
    }
}

multiplatformResources {
    // 指定资源的包名,需与代码包名一致
    multiplatformResourcesPackage = "com.your.library.package"
}

2. 库中使用资源

用moko-resources的API替代原生Compose资源调用:

import dev.icerock.moko.resources.compose.painterResource
import dev.icerock.moko.resources.DrawableResource

// 直接引用资源(moko会自动生成资源索引)
val icMyHealth = DrawableResource(id = R.drawable.ic_my_health)

// Compose中使用
@Composable
fun MyHealthIcon() {
    Image(
        painter = painterResource(icMyHealth),
        contentDescription = "My health icon"
    )
}

3. 打包与SPM导入

执行assembleXCFramework后,生成的XCFramework会自动包含所有资源文件,iOS项目直接通过SPM导入该框架即可,无需额外配置资源拷贝步骤。

关键注意事项

  • 资源文件命名需符合跨平台规范:避免特殊字符,vector drawable需兼容Compose的iOS渲染逻辑
  • 静态框架(isStatic = true)更适配SPM,资源会被打包进Framework的Resources目录,无需手动拷贝
  • 若使用动态框架,需确保iOS项目的Copy Bundle Resources阶段包含Framework的资源

内容的提问来源于stack exchange,提问作者Kai

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 17:32:52