New file picker API
See original GitHub issueOur current file dialogs are desktop-centric and assume that the app has direct access to the file system, which is not the case for sandboxed environments.
While keeping the current API for desktop platforms, we need to design a new one that would work well with WebAssembly, macOS App Store apps, iOS and Android (possibly with UWP too, but I’m not sure how relevant it is since we don’t support XBox and HoloLens anyway).
Main differences of the API would be:
- the lack of direct access to the file system, so the API should provide
Stream
s instead of file paths - apps might need to implement extra functionality to conform with the OS guidelines (e. g. subscribe to file changes via NSFilePresenter in case of iOS
- directory access would be more complicated (e. g. https://developer.apple.com/documentation/uikit/view_controllers/providing_access_to_directories?language=objc), so we might want to skip it in the initial implementation
- some sandboxes allow to save a file “bookmark” that allows the app to access the same file after restart (see https://github.com/AvaloniaUI/Avalonia/pull/6540)
- more complicated required file type information rather than simply a file extension. For example iOS requires to specify a uniform type identifier that are not MIME-types (e. g.
com.adobe.pdf
,org.idpf.epub-container
,public.mp3
- sometimes it’s only possible to “export” a file. In case of WebAssembly saving file means creating an object URI from ReadableStream-backed Response object and waiting for browser to start a download), we can only report the intended file name and file type via a virtual
Content-Disposition
header. In case of iOS that would be the Share function - Some platforms (e. g. iOS) has different APIs for accessing documents (UIDocumentPickerViewController) and photos/videos (UIImagePickerController)
class FilePickerOpenOptions
{
string Title { get; set; }
string DefaultFileName { get; set; }
IList<FilePickerFileType> FileTypes { get; set; }
}
class FilePickerOpenOptions
{
string Title { get; set; }
string DefaultFileName { get; set; }
FilePickerFileType DefaultFileType {get; set; }
IList<FilePickerFileType> FileTypes { get; set; }
}
class FilePickerFileType
{
// For desktop
string Title { get; init; }
IReadOnlyList<string> Extensions {get; init; }
// For web
IReadOnlyList<string> MimeTypes {get; init; }
// For Apple platforms
IReadOnlyList<string> AppleUniformTypeIdentifiers {get; init; }
}
// We should provide some built-in types for common file types
class FilePickerFileTypes
{
static FilePickerFileType Pdf {get;} = new FilePickerFileType
{
Title = "PDF document",
Extensions = new [] {"pdf"},
AppleUniformTypeIdentifiers = new[] {"com.adobe.pdf"},
MimeTypes = new [] { "application/pdf" }
};
}
interface IFilePicker
{
bool CanOpen { get; }
Task<IFilePickerFile> OpenAsync(FilePickerOptions options);
bool CanSave { get; }
Task<IFilePickerFile> SaveAsync(FilePickerOptions options);
bool CanExport { get; }
Task Export(FilePickerOptions options, Func<Stream, FilePickerFileType, Task> writer);
IFilePickerBookmark OpenBookmark(string bookmark);
}
interface IFilePickerWriteContext
{
Stream Stream {get;}
FilePickerFileType FileType {get;}
}
interface IFilePickerBookmark : IDisposable
{
bool CanOpenRead {get;}
bool CanOpenWrite {get;}
Task<Stream> OpenRead();
Task<Stream> OpenWrite();
}
interface IFilePickerFile : IDisposable
{
Stream Stream {get;}
bool CanBookmark{get;}
Task<string> SaveBookmark();
}
Issue Analytics
- State:
- Created 2 years ago
- Reactions:3
- Comments:12 (12 by maintainers)
Top Results From Across the Web
The Google Picker API | Google Drive
The Google Picker is a "File Open" dialog for information stored on Google Drive. The Google Picker has these features: A similar look-and-feel...
Read more >Display the Google Picker | Google Drive
The Google Picker is a "File Open" dialog for information stored on Google servers. You can use the Google Picker API to allow...
Read more >Window: showOpenFilePicker() method - Web APIs | MDN
The showOpenFilePicker() method of the Window interface shows a file picker that allows a user to select a file or multiple files and...
Read more >Complete Google Drive File Picker example
This is an example of how to use the Google Drive file picker and Google Drive API to retrieve files from Google Drive...
Read more >File Picker
File Picker. The File Picker is an open-source, plug-and-play, component that connects to many cloud storage APIs and offers easy file uploads and...
Read more >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
I think a good design to start defining the API surface is Windows.Storage and Windows.Storage.Pickers.
we can deifine like code this:
The mapping is done via IStorageProvider and IContentTypeMeta. IStorageProvider deals with the creation of the appropriate concrete types of IStorageItem with the respective metadata.
The fact that she is dead does not mean that we cannot learn from good things. It is not necessary to re-invent the wheel every time. Uno supports macOS/iOS/Android/WASM/Linux(GTK/Framebuffer) using UWP API design.
Your design seems to me very connected to the macOS world.
Having two models for file system access is confusing to the developer. If I make a desktop app I have to use Avalonia.Dialogs. *, If the app has to run in a sandbox I have to use IFilePicker.