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!
CodePudding user response:
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