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

如何用Kotlin Multiplatform构建适配Android和iOS的图片资源框架?

跨平台资源框架iOS端实现验证与优化

你的iOS端实现思路整体方向正确,但在资源存放路径、代码细节和SPM分发配置上有几处关键调整点,确保资源能被主应用正确访问:

1. 资源存放路径修正

你提到的iosMain/res/xcassets/路径不正确,KMM项目中iOS资源的标准存放路径是:
iosMain/Resources/Assets.xcassets/

具体操作:

  • 在iosMain目录下创建Resources文件夹
  • 新建或放入Assets.xcassets资源目录,将HEIC图片添加到对应的Image Set中(每个Image Set的命名要和Android端的图片名一致,比如Android的home.webp对应iOS的Image Set命名为home,并将home.heic拖入该Set)
  • 按需为Image Set配置不同分辨率的变体(如1x、2x、3x),适配不同iOS设备

2. iOS端代码优化(关键:指定框架Bundle)

原代码中UIImage.imageNamed(this.name)存在隐患:主应用嵌入框架时,默认会从主应用的Bundle中查找资源,无法定位到框架内的资源。需要明确指定框架的Bundle:

/// iOS Main
actual typealias PlatformImage = UIImage

@Composable
internal actual fun ImageAsset.getPlatformImage(): PlatformImage? {
    // 替换成你框架中任意类的Class,用于定位框架Bundle
    val frameworkClass = YourFrameworkMarkerClass::class.java
    val frameworkBundle = NSBundle.bundleForClass(frameworkClass)
    // 从框架Bundle中加载图片
    return UIImage.imageNamed(name, bundle = frameworkBundle)
}

说明:

  • YourFrameworkMarkerClass可以是你框架中任意一个空类(比如专门创建一个FrameworkMarker类放在iosMain目录下),用于获取框架的Bundle实例
  • 该写法能确保主应用调用框架时,正确从框架自身的Bundle中读取HEIC资源

3. SPM分发的资源配置

由于你通过SPM分发iOS框架,需要在Package.swift中明确配置资源打包规则,否则资源不会被包含在分发的框架中:

let package = Package(
    name: "YourFrameworkName",
    platforms: [.iOS(.v11)], // HEIC最低支持iOS 11
    products: [
        .library(name: "YourFrameworkName", targets: ["YourFrameworkName"])
    ],
    targets: [
        .target(
            name: "YourFrameworkName",
            dependencies: [],
            resources: [
                // 处理并打包Assets.xcassets资源
                .process("Resources/Assets.xcassets")
            ]
        )
    ]
)

4. 额外优化建议

Android端代码小调整

你的Android代码可以简化并增加容错处理,避免资源找不到时崩溃:

/// Android Main
actual typealias PlatformImage = Painter

@Composable
internal actual fun ImageAsset.getPlatformImage(): PlatformImage? {
    val context = LocalContext.current
    val resourceId = context.resources.getIdentifier(name, "drawable", context.packageName)
    // 资源存在时才返回Painter,否则返回null
    return if (resourceId != 0) painterResource(id = resourceId) else null
}

兼容性提示

HEIC格式仅支持iOS 11及以上版本,如果你的框架需要兼容更低版本,建议添加PNG格式的 fallback 资源,并在代码中判断系统版本选择加载对应的资源。


内容的提问来源于stack exchange,提问作者Bawenang Rukmoko Pardian Putra

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.01 16:37:30