简体   繁体   中英

Access files in commonMain resources directory with OKIO - Kotlin Multiplatform

I wanted to include into my app (Kotlin Multiplatform Mobile) iOS + Android a.json file to be parsed and saved into Realm DB on the first launch using.initialData{}.

I use expect/actual pattern and try to access file in /resources/initialdata.json

I'm trying to use OKIO library (supposed to be ready to work with Kotlin Multiplatform): https://square.github.io/okio/recipes/

I have issues with accessing file from src/commonMain/resources what get is IO error path not found:

java.io.FileNotFoundException: src/resources/initialdata.json: open failed: ENOENT (No such file or directory)

Realm Config with.initialData looks as follows:

        val config =
            RealmConfiguration.Builder(schema = schema)
                .name("boardDb-local")
                .initialData{
                    val jsonString = FileResourceParser().parseInitialFile()

                    val list: List<Exercise> = Json.decodeFromString(jsonString)
                    
                    val realmList: RealmList<Exercise> = realmListOf().also { it.addAll(list)}
                    for (item in realmList) {
                            copyToRealm(item, UpdatePolicy.ALL)
                        }
                }
                .log(LogLevel.ALL)
                .schemaVersion(1)
                .build()  


//Class with method with platform specific logic to get a file from resources and parse it. 
expect class FileResourceParser() {
    fun parseInitialFile(): String
}



//and in androidMain Module logic to read the file using OKIO

actual class FileResourceParser {


    val json = FileSystem.SYSTEM.read("src/resources/initialdata.json".toPath()) {
        //Read UTF8 logic
    }
       //some other manipulation
        return json
       
    }
}

Question: who to define path to commonMain resource folder. I'm confused.

Thank you!

Okio is indeed multiplatform, but that doesn't mean it can access files from resources using regular paths like this. You shouldn't try to access resources by their path among your source files - they won't be here when you run your program elsewhere.

On JVM, such resources are placed in the compiled JAR, so you would need to access them via the regular Java facilities. For example, SomeClass::class.java.getResource("/some-file.txt") to access a file initially located in the source at src/commonMain/resources/some-file.txt , from a class located anywhere in src/jvmMain/kotlin/* . Maybe to read it from Okio you could use getResourceAsStream() instead and then convert the stream to whatever Okio provides.

On JS platform, you might need some extra webpack config + require() call to get them. See Embed resources in kotlin js

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM