How to read file with okio inside commanMain module in a Kotlin Multiplatform Project?
Asked Answered
E

1

13

I am trying to read/write files in the commonMain module.

I created a new Kotlin Multiplatform App for Android and iOS using the Android Studio Wizard. (New -> New Project ... -> Koltin Multiplatform App)

Then I added okio as dependency to common in the shared/build.gradle.kts file.

    sourceSets {
        val okio = "3.3.0"
        val commonMain by getting {
            dependencies {
                implementation("com.squareup.okio:okio:$okio")
            }
        }
        ...

In the module commonMain I cannot access FileSystem.SYSTEM (Unresolved Reference: SYSTEM) and therefore not read or write any files.

In the module iOSMain and androidMain I can access FileSystem.SYSTEM. Is this expected behaviour? This would require me to write an expected/actual mapping for all okio apis. Or is there an other way?

Or do I need to configure my project differently to be able to access FileSystem.SYSTEM inside the commonMain-Module?

shared/build.gradle

plugins {
    kotlin("multiplatform")
    kotlin("native.cocoapods")
    id("com.android.library")
}

kotlin {
    android()
    iosX64()
    iosArm64()
    iosSimulatorArm64()

    cocoapods {
        summary = "Some description for the Shared Module"
        homepage = "Link to the Shared Module homepage"
        version = "1.0"
        ios.deploymentTarget = "14.1"
        podfile = project.file("../iosApp/Podfile")
        framework {
            baseName = "shared"
        }
    }
    
    sourceSets {
        val okio = "3.3.0"
        val commonMain by getting {
            dependencies {
                implementation("com.squareup.okio:okio:$okio")
            }
        }
        val commonTest by getting {
            dependencies {
                implementation(kotlin("test"))
            }
        }
        val androidMain by getting
        val androidTest by getting
        val iosX64Main by getting
        val iosArm64Main by getting
        val iosSimulatorArm64Main by getting
        val iosMain by creating {
            dependsOn(commonMain)
            iosX64Main.dependsOn(this)
            iosArm64Main.dependsOn(this)
            iosSimulatorArm64Main.dependsOn(this)
        }
        val iosX64Test by getting
        val iosArm64Test by getting
        val iosSimulatorArm64Test by getting
        val iosTest by creating {
            dependsOn(commonTest)
            iosX64Test.dependsOn(this)
            iosArm64Test.dependsOn(this)
            iosSimulatorArm64Test.dependsOn(this)
        }
    }
}

android {
    namespace = "de.pixel.kmmpodstryout"
    compileSdk = 32
    defaultConfig {
        minSdk = 21
        targetSdk = 32
    }
}

Greetings.kt in commonMain from the sample app generated by the wizard:

package de.pixel.kmmpodstryout

import okio.FileSystem
import okio.Path.Companion.toPath

class Greeting {
    private val platform: Platform = getPlatform()

    fun greet(): String {
        val path = "helloworld.txt".toPath()

        FileSystem.SYSTEM <--- "Unresolved Reference SYSTEM"

        return "Hello, ${platform.name} ${readFile()}!"
    }
}
Elicia answered 13/1, 2023 at 10:21 Comment(2)
Because SYSTEM isn't available on all platforms, I think you need to inject it into your KMP "graph" from each platform.Saucy
Super easy with an expect/actual top level function getFilesystemMalcolm
E
0

The FileSystem.SYSTEM is only available in the platform specific folders. To use it in commonMain you can use the expect/actual mechanism.

  1. Create a FileSystemPlatform.kt in commonMain This contains the following code:

    expect val fileSystem: FileSystem

  2. Create implementations for the platforms (in this case iOS and Android). These files are names FileSystemPlatform.ios.kt and FileSystemPlatform.android.kt. Both these files have the following content:

    actual val fileSystem: FileSystem = FileSystem.SYSTEM

  3. Now you can use the fileSystem variable in the whole commonMain module.

Excrescence answered 2/3 at 11:51 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.