I don't know of any examples. Your function would ...
# squarelibraries
j
I don't know of any examples. Your function would change to take a Path and a FileSystem and then it would perform whatever reading and parsing it needed. In the Android code you'd pass the asset file and the asset FileSystem was just merged into Okio this week and will be in a release soon
l
okay, now i’m experimenting with reading the file in the
android
module, but i’m still getting errors because of the file path This is the function i’m calling from
MainActivity
and none of the paths work:
Copy code
fun readFile() {
//        val path = "words.txt".toPath() // doesn't work
//        val path = "src/main/words.txt".toPath() // doesn't work
        val path = "android/src/main/words.txt".toPath() // doesn't work

        val csvContent = FileSystem.SYSTEM.read(path) {
            readUtf8()
        }
        Log.d("++csv:", csvContent)
    }
This is where
words.txt
is located:
j
that is not a place you can read from
you can put it into assets and read using the asset filesystem that's on master or the regular Android asset API if you're doing it all in the Android code anyway
l
I will just use the Android file system, and pass the data to sharedModule, then I will migrate the code to use asset filesystem once it’s released by okio. Thank you guys
j
I'm doing this in a multiplatform library, with each platform implementing a common
getAsset(asset: String): Source
interface, returning an Okio
Source
stream. For Android, assuming the common resources are in the apk bundle's assets, it's simply:
Copy code
applicationContext.assets.open(asset).source()
In order to get common test files in src/commonTest/resources in the Android apk bundle assets, I symlinked that path to src/androidInstrumentedTest/resources/assets. I've also implemented for JVM, iOS, macOS, Linux, and Windows as well. Native platforms require an additional gradle task to copy the files to the correct location in the bundle resources or runtime path.
j
Any pointers on bundling resources for Linux and Windows native apps? I’d love to bundle a Resources file system on every platform that supports em
j
There's a YouTrack issue for embedding resources directly in Kotlin/Native binaries, which would be great for producing self-contained applications. For Linux and Windows, I'm just referencing the resources relative to the CWD, which is the project path for tests:
Copy code
override fun getAsset(asset: String): Source {
    val target = when (Platform.osFamily) {
        OsFamily.LINUX -> "linux"
        OsFamily.WINDOWS -> "mingw"
        else -> error("Unsupported platform: ${Platform.osFamily}")
    } + Platform.cpuArchitecture.name.lowercase().replaceFirstChar(Char::titlecase)
    val path = "build/bin/$target/debugTest/$asset".toPath()
    return FileSystem.SYSTEM.source(path)
}
In order to get
commonTest
resources in that directory alongside the test binary, I use this gradle copy task:
Copy code
tasks.withType<KotlinNativeTest> {
    val dir = name.substring(0, name.lastIndex - 3)
    dependsOn(
        tasks.register<Copy>("copy${name.capitalized()}Resources") {
            from("src/commonTest/resources")
            into("build/bin/$dir/debugTest")
        }
    )
}
This is also necessary for native platform-specific resources. For an Android + iOS KMM app, I copy both
commonMain
and
iosMain
resources to the iOS
*.framework
directory with this gradle code, which handles frameworks, fat frameworks, and test binary scenarios for Darwin platforms. Something like this works to get resources from the bundle:
Copy code
override fun getAsset(asset: String): Source? {
    val dotIndex = asset.lastIndexOf('.')
    val name = asset.substring(0, dotIndex)
    val type = asset.substring(dotIndex + 1)
    val path = NSBundle.mainBundle
        .pathForResource(name, type)
        ?: return null
    return FileSystem.SYSTEM.source(path.toPath())
}
JVM is the only platform that bundles resources from both
jvm*
and
common*
source sets automatically. Accessing them is simply:
Copy code
override fun getAsset(asset: String): Source? =
    javaClass.getResource("/$asset")?.openStream()?.source()