Skip to main content
A file the user picked can become unreachable after a restart: Android revokes content:// access and sandboxed Apple apps lose their security scope. bookmarkData() turns a PlatformFile into bytes you can store, and PlatformFile.fromBookmarkData(bytes) gives the file back, with its access, on the next launch.

Usage

nonWebMain
Both functions are declared in nonWebMain. bookmarkData() is a suspend function. Bookmark bytes are platform-specific: don’t share them between operating systems or apps.

Restore a bookmark safely

A bookmark breaks when the user deletes the file, revokes your app’s access, or (on path-based platforms) moves it. Handle failure and ask the user to pick the file again. This helper stores one bookmark in your app’s files directory:
nonWebMain
resolveBookmarkData returns a BookmarkResolution with the file and two flags: Refreshing is best effort: the old bytes may still work, and bookmarkData() can fail if the file disappeared or macOS already revoked access. Use fromBookmarkData when you only need the file.

Platform notes

On Android, releaseBookmark() releases the persisted URI permission. Android limits how many URI permissions an app can persist, so release the ones you no longer need.

Set up the macOS App Sandbox

FileKit reads your app’s App Sandbox entitlement at runtime. When it is present, FileKit creates security-scoped bookmarks and reports a failure instead of falling back to a bookmark that can’t restore access.
1

Enable the sandbox and user-selected file access

Add these entitlements to the signed app:
entitlements.plist
2

Test the packaged app

Entitlements only apply to a signed build. Pick a file, quit, relaunch, and restore the bookmark.

Keep security-scoped access

On iOS and in sandboxed macOS apps, a file outside your container is readable only while its security-scoped access is active. FileKit starts and stops access around its own operations, and keeps it active until returned sources and sinks are closed. Derive files from the restored PlatformFile with /, resolve(), or list() so they share its access:
nonWebMain
A PlatformFile rebuilt from a path string or toKotlinxIoPath() loses that access, and so does one restored by PlatformFileSerializer, which stores only the path. Persist bookmark data instead. When you hand a file to another library, wrap the call in withScopedAccess. It calls startAccessingSecurityScopedResource() and stopAccessingSecurityScopedResource() for you, and is a no-op on platforms without security scopes:
Call releaseBookmark() once you are done with a restored bookmark and every file derived from it. Already-open sources and sinks still close cleanly, but new scoped operations then throw a FileKitException.
  • macOS bookmark format: new bookmarks on macOS (native and JVM) are wrapped in a versioned FileKit format. Unwrapped Kotlin/Native bookmarks and JVM path bytes written by earlier versions remain readable, and resolveBookmarkData reports shouldRefresh = true for them.
  • iOS security scope: restored bookmarks now keep the security-scoped URL for the bookmarked item and its descendants, including after a device restart. Stored bookmarks get this behavior without a migration.
  • iOS releaseBookmark(): it was a no-op in FileKit 0.15.0 and 0.16.0 and now releases access. Calling startAccessingSecurityScopedResource() on a released bookmark throws instead of returning false.
  • fromBookmarkData is not deprecated. resolveBookmarkData was added for refresh metadata.