Migrate¶
From saf 1.x¶
The old path-based class still ships as LegacySaf (deprecated, removed in
3.0.0). Migrate at your own pace:
// before
final saf = Saf('/storage/emulated/0/MyApp');
// after — unchanged 1.x behavior
final saf = LegacySaf('/storage/emulated/0/MyApp');
The new API is URI-based, not path-based. Start from pickDirectory() and
store the returned URIs (not filesystem paths):
final saf = Saf();
final dir = await saf.pickDirectory();
if (dir != null) {
final files = await saf.list(dir.uri);
}
What's better in 2.x¶
- No
isDirparameters — document type is resolved from the URI. - Typed exceptions instead of raw
PlatformException. - One-call
writeFileStreamfor large writes. - Recursive
walk()and progress callbacks on copy/move — new capabilities.
Coming from another SAF package?¶
saf 2.x covers the full Storage Access Framework surface in one package —
pickers, permissions, file management, streaming read/write, recursive walk,
and progress. The API is URI-based and uses conventional method names
(readFileBytes, writeFileBytes, list, stat, mkdirp, copyTo, …), so
moving over is largely mechanical. See the Recipes for the
equivalent of any operation.