KMM项目iOS端无法读取共享模块本地JSON文件的问题
KMM跨平台读取共享JSON文件解决方案
一、资源文件正确放置
直接将JSON文件放在shared/src/commonMain/resources根目录下(比如sample2.json),不要嵌套iOSMain子目录,commonMain下的资源是跨平台共享的基础载体。
二、iOS端资源打包配置
在shared模块的build.gradle.kts中,为iOS框架添加资源打包规则,确保commonMain的JSON文件被正确拷贝到iOS bundle中:
kotlin { ios { binaries { framework { // 确保共享资源被包含进iOS框架 resources { from("src/commonMain/resources") { include("**/*.json") } } } } } }
三、修正iOS端读取代码
原代码使用NSBundle.mainBundle会指向iOS主App的bundle,而KMM共享模块的资源在框架自身的bundle中,需要修改为:
// 替换成你共享模块中的任意类(比如当前类) val targetClass = javaClass<YourSharedModuleClass>() val frameworkBundle = NSBundle.bundleForClass(targetClass) val filePath = frameworkBundle.pathForResource(name = "sample2", ofType = "json") ?: error("JSON文件未找到") val jsonContent = NSString.stringWithContentsOfFile(filePath, encoding = NSUTF8StringEncoding, error = null) ?: ""
四、推荐:跨平台通用读取方案
通过KMM的expect/actual机制封装通用读取方法,避免平台特定代码分散:
- commonMain中定义expect函数
expect fun readSharedJson(fileName: String): String?
- AndroidMain中实现
actual fun readSharedJson(fileName: String): String? { return try { val inputStream = javaClass.classLoader?.getResourceAsStream(fileName) inputStream?.bufferedReader()?.use { it.readText() } } catch (e: Exception) { e.printStackTrace() null } }
- iOSMain中实现
actual fun readSharedJson(fileName: String): String? { val name = fileName.substringBeforeLast(".") val ext = fileName.substringAfterLast(".", "") val frameworkBundle = NSBundle.bundleForClass(javaClass<YourSharedModuleClass>()) val path = frameworkBundle.pathForResource(name = name, ofType = ext) ?: return null return NSString.stringWithContentsOfFile(path, encoding = NSUTF8StringEncoding, error = null) }
之后在common代码中直接调用readSharedJson("sample2.json")即可跨平台读取。
五、Compose Resources修复方案
如果使用JetBrains官方的Compose Resources,需满足以下要求:
- 资源路径调整:将JSON文件放在
shared/src/commonMain/resources/composeResources目录下,比如files/sample2.json对应路径为composeResources/files/sample2.json - 确保依赖配置正确:在shared模块的
build.gradle.kts中添加:
plugins { id("org.jetbrains.compose") version "你的Compose版本号" } kotlin { sourceSets { commonMain { dependencies { implementation(compose.components.resources) } } } }
- 读取代码保持正确:
val jsonContent = Res.readBytes("files/sample2.json").decodeToString()
内容的提问来源于stack exchange,提问作者Priyanka Kadam
相关产品推荐
相关产品推荐

