Skip to content

Pick and save Files, Medias and Folder for Kotlin Multiplatform / KMP and Compose Multiplatform / CMP

License

Notifications You must be signed in to change notification settings

vinceglb/FileKit

Repository files navigation

FileKit for Kotlin Multiplatform and Compose Multiplatform

FileKit

Files, Medias, Folder Picker and File saver library for Kotlin Multiplatform and Compose Multiplatform

FileKit Kotlin Maven Version Badge Android Badge iOS Badge JVM Badge JS

Picker Kotlin is a library that allows you to pick and save files in a simple way. On each platform, it uses the native file picker API to provide a consistent experience.

πŸš€ Quick Start

Pick a file, a directory or save a file in common code:

// Pick a file
val file = FileKit.pickFile()

// Pick a directory
val directory = FileKit.pickDirectory()

// Save a file
val file = FileKit.saveFile(
    extension = "txt",
    bytes = "Hello, World!".encodeToByteArray()
)

Get file information in common code:

val filePath = file?.path
val fileName = file?.name
val bytes = file?.readBytes()

Compose Multiplatform integration made simple:

// Pick files from Compose
val launcher = rememberFilePickerLauncher(PickerMode.Multiple) { files ->
    // Handle picked files
}

// Use the pickerLauncher
Button(onClick = { launcher.launch() }) {
    Text("Pick files")
}

FileKit Preview

πŸ“¦ Installation

repositories {
    mavenCentral()
}

dependencies {
    // Enables FileKit without Compose dependencies
    implementation("io.github.vinceglb:filekit-core:0.4.2")

    // Enables FileKit with Composable utilities
    implementation("io.github.vinceglb:filekit-compose:0.4.2")
}

⚑ Initialization

Using FileKit Core methods on Android requires an initialization:

  • FileKit.pickFile()
  • FileKit.pickDirectory()
  • FileKit.saveFile()

In this case, only if using Android, you need to initialize FileKit in your ComponentActivity:

// MainActivity.kt
class MainActivity : ComponentActivity() {
    override fun onCreate() {
        super.onCreate()
        FileKit.init(this)
    }
}

In all other cases, you can use FileKit without initialization.

πŸ“„ File Picker

Picker types

You can pick different types of files with PickerType:

  • Image: Pick an image file.
  • Video: Pick a video file.
  • ImageAndVideo: Pick an image or a video file.
  • File: Pick any file. It is the default type. It's possible to specify a list of extensions.
val imageType = PickerType.Image
val videoType = PickerType.Video
val imageAndVideoType = PickerType.ImageAndVideo
val fileType = PickerType.File(extensions = listOf("pdf", "docx"))

Picker modes

You can pick files in different modes with PickerMode. The mode will change the output type. Single is the default mode.

val singleMode = PickerMode.Single
val multipleMode = PickerMode.Multiple

Launch the picker

You can launch the picker with FileKit.pickFile or rememberFilePickerLauncher:

// FileKit Core
val file = FileKit.pickFile(
    type = PickerType.Image,
    mode = PickerMode.Single,
    title = "Pick an image",
    initialDirectory = "/custom/initial/path"
)

// FileKit Compose
val launcher = rememberFilePickerLauncher(
    type = PickerSelectionType.ImageAndVideo,
    mode = PickerSelectionMode.Multiple,
    title = "Pick a media",
    initialDirectory = "/custom/initial/path"
) { files ->
    // Handle the picked files
}
launcher.launch()

πŸ“ Directory Picker

You can pick a directory with FileKit.pickDirectory or rememberDirectoryPickerLauncher:

// FileKit Core
val directory = FileKit.pickDirectory(
    title = "Pick a directory",
    initialDirectory = "/custom/initial/path"
)

// FileKit Compose
val launcher = rememberDirectoryPickerLauncher(
    title = "Pick a directory",
    initialDirectory = "/custom/initial/path"
) { directory ->
    // Handle the picked directory
}
launcher.launch()

The directory picker is available on all platforms, expect for WASM / JS. To check if the directory picker is available from the common code, you can use FileKit.isDirectoryPickerSupported().

val directoryModeSupported = FileKit.isDirectoryPickerSupported()

πŸ’Ύ Save File Picker

You can save a file with FileKit.saveFile or rememberFileSaverLauncher:

// FileKit Core
val file = FileKit.saveFile(
    baseName = "myTextFile",
    extension = "txt",
    initialDirectory = "/custom/initial/path",
    bytes = "Hello, World!".encodeToByteArray()
)

// FileKit Compose
val launcher = rememberFileSaverLauncher() { file ->
    // Handle the saved file
}
launcher.launch(
    baseName = "myTextFile",
    extension = "txt",
    initialDirectory = "/custom/initial/path",
    bytes = "Hello, World!".encodeToByteArray()
)

πŸ§‘β€πŸ’» PlatformFile and PlatformDirectory

The PlatformFile and PlatformDirectory classes are wrappers around the platform file system. It allows you to get the file name, path and read the file content in common code.

val platformFile: PlatformFile = ...

val filePath: String? = platformFile.path
val fileName: String = platformFile.name            // Base name with extension
val baseName: String = platformFile.baseName
val extension: String = platformFile.extension
val bytes: ByteArray = platformFile.readBytes()     // suspend function

val platformDirectory: PlatformDirectory = ...
val directoryPath: String? = platformDirectory.path

On each platform, you can get the original platform file:

// Android
val uri: Uri = platformFile.uri
val uri: Uri = platformDirectory.uri

// iOS / macOS
val nsUrl: NSURL = platformFile.nsUrl
val nsUrl: NSURL = platformDirectory.nsUrl

// JVM
val file: java.io.File = platformFile.file
val file: java.io.File = platformDirectory.file

// WASM / JS
val file: org.w3c.files.File = platformFile.file
val file: org.w3c.files.File = // PlatformDirectory not supported on WASM / JS

🌱 Sample projects

You can find 2 sample projects in the samples directory:

  • sample-core: A Kotlin Multiplatform project using FileKit in a shared viewModel targeting Android, JVM, WASM, JS, iOS Swift, macOS Swift and iOS Compose.
  • sample-compose: A Compose Multiplatform project using FileKit in a Composable targeting Android, iOS, JVM, WASM,

✨ Behind the scene

FileKit uses the native file picker API on each platform:

  • On Android, it uses PickVisualMedia, OpenDocument and OpenDocumentTree contracts.
  • On iOS, it uses both UIDocumentPickerViewController and PHPickerViewController APIs.
  • On macOS, it uses the NSOpenPanel API.
  • On JVM, it uses JNA to access the file system on Windows and macOS and Awt FileDialog on Linux.
  • On WASM / JS, it uses the input element with the file type.

Also, FileKit uses the bear minimum of dependencies to be as lightweight as possible.

FileKit Core uses the following libraries:

FileKit Compose uses the following libraries:

😎 Credits

FileKit is inspired by the following libraries:


Made with ❀️ by Vince