{"id":13342226,"url":"https://github.com/datvm/LukeMauiFilePicker","last_synced_at":"2025-03-12T00:31:06.530Z","repository":{"id":65799818,"uuid":"600099593","full_name":"datvm/LukeMauiFilePicker","owner":"datvm","description":"File Picker (open and save) for MAUI apps. Alternative to FilePicker which is currently broken. Also support Save Picker.","archived":false,"fork":false,"pushed_at":"2024-04-04T10:12:04.000Z","size":4107,"stargazers_count":13,"open_issues_count":0,"forks_count":2,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-07T16:46:41.252Z","etag":null,"topics":["android","csharp","dotnet","file-picker","ios","maccatalyst","maui","picker","windows","winui"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/datvm.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-02-10T15:28:06.000Z","updated_at":"2024-11-29T07:02:40.000Z","dependencies_parsed_at":"2024-10-24T03:53:39.927Z","dependency_job_id":"11f68490-3937-4328-9087-5ac7df933026","html_url":"https://github.com/datvm/LukeMauiFilePicker","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/datvm%2FLukeMauiFilePicker","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/datvm%2FLukeMauiFilePicker/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/datvm%2FLukeMauiFilePicker/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/datvm%2FLukeMauiFilePicker/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/datvm","download_url":"https://codeload.github.com/datvm/LukeMauiFilePicker/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243136265,"owners_count":20241987,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["android","csharp","dotnet","file-picker","ios","maccatalyst","maui","picker","windows","winui"],"created_at":"2024-07-29T19:28:08.779Z","updated_at":"2025-03-12T00:31:06.525Z","avatar_url":"https://github.com/datvm.png","language":"C#","readme":"This project is an attempt to temporarily fix dotnet/maui#11088 . This project also provides pickers experience across almost all platforms: WinUI, Android, iOS and Mac Catalyst. So far from my test, **no permission is needed** since you only have access to specific files that user picks.\n\nSee [demo project](./LukeMauiFilePicker.Demo/) with sample text editor app: **Opening a single file**, **Opening multiple files** (concatenate all the content) and **Saving into a file** (location and name picked by user).\n\n![Windows App](./imgs/win-app.png)\n\nThis article uses Windows screenshots. To see screenshots for other platforms, see [Screenshots on all platforms](#screenshots-on-all-platforms)\n\nWas it helpful for you? Please consider a donation ❤️ [PayPal](https://paypal.me/datvm).\n\n# Installation \u0026 Setup\n\n## Nuget Package\n\nInstall the [NuGet package `LukeMauiFilePicker`](https://www.nuget.org/packages/LukeMauiFilePicker) into your .NET MAUI project:\n\n```ps\ndotnet add package LukeMauiFilePicker\n```\n\n## Setup Dependency Injection\n\nIn your `Program.cs` file, add the following line to the `CreateMauiApp()` method:\n\n```cs\n// Add IFilePickerService service to your DI\nbuilder.Services.AddFilePicker();\n```\n\n\u003e **Note**  \n\u003e If you use Android Save Picker, you need to add the code below to register Activity Result flow.\n\n```cs\n// You need this if you use Android Save Picker\n// Optional Activity Result Request code, default is 2112 if not specified\nbuilder.ConfigureFilePicker(100);\n```\n\n\u003e **Warning**  \n\u003e If you do not call `ConfigureFilePicker()`, an `InvalidOperationException` will be thrown if you invoke Android Save Picker.\n\n# Usage\n\nThe following methods can be called from an `IFilePickerService` instance from your DI.\n\n## Open File Picker (Pick Single and Multiple Files)\n\n```cs\nTask\u003cIPickFile?\u003e PickFileAsync(string title, Dictionary\u003cDevicePlatform, IEnumerable\u003cstring\u003e\u003e? types);\nTask\u003cIEnumerable\u003cIPickFile\u003e?\u003e PickFilesAsync(string title, Dictionary\u003cDevicePlatform, IEnumerable\u003cstring\u003e\u003e? types, bool multiple);\n```\n\nPick a single file or multiple files. The `types` parameter is a dictionary of platform-specific file types. If you do not specify the `types` parameter, all file types are allowed.\n\n![Windows Open File Picker](./imgs/win-pick-multi.png)\nWindows Open Multiple Files Picker\n\n**Example:**\n\n```cs\n    static readonly Dictionary\u003cDevicePlatform, IEnumerable\u003cstring\u003e\u003e FileType = new()\n    {\n        {  DevicePlatform.Android, new[] { \"text/*\" } } ,\n        { DevicePlatform.iOS, new[] { \"public.json\", \"public.plain-text\" } },\n        { DevicePlatform.MacCatalyst, new[] { \"public.json\", \"public.plain-text\" } },\n        { DevicePlatform.WinUI, new[] { \".txt\", \".json\" } }\n    };\n\n    // Let user pick files (and handling cancelling)\n    var files = await picker.PickFilesAsync(\"Select a file\", FileType, true);\n    if (files is null || !files.Any()) { return; }\n\n    // Read the files\n    foreach (var f in files)\n    {\n        using var s = await f.OpenReadAsync();\n        using var reader = new StreamReader(s);\n\n        str.AppendLine(await reader.ReadToEndAsync());\n    }\n```\n\n\u003e **Note**  \n\u003e On some platforms that [official MAUI File picker](https://learn.microsoft.com/en-us/dotnet/maui/platform-integration/storage/file-picker) works, the library simply calls those APIs.\n\nThe `IPickFile` interface lets you know the `FileName` and openning a `Stream` to a file. Optionally, you can also get the original `FileResult` from MAUI API if this library doesn't have custom implementation for it.\n\n\u003e **Warning**  \n\u003e On some platforms, when user cancel (pressing Back button), `PickFilesAsync` returns an empty array instead of `null` so you need to check for `Any()` as well.\n\n\u003e **Note**  \n\u003e For iOS and Mac Catalyst, you can put in either `Identifier` (`public.json`), `MimeType` (`application/json`) or file `Extension` (`json`). The library attempt to call 3 create methods `CreateFromIdentifier`, `CreateFromMimeType`, `CreateFromExtension` one after another. If all 3 methods fail, `UTTypes.Item` is used.\n\n# Save File Picker\n\n```cs\nTask\u003cbool\u003e SaveFileAsync(SaveFileOptions options);\n```\n\nSave a file. The `SaveFileOptions` contains the following properties:\n\n- `string SuggestedFileName` (**Required**): The suggested file name.\n\n- `Stream Content` (**Required**): The content to write to. Note that this is required before user even pick a file because for iOS and Mac, it needs to be available before user picks a file.\n\n- `(string FileTypeName, List\u003cstring\u003e FileTypeExts) WindowsFileTypes`: Windows-specific file types. The `FileTypeName` is the name of the file type (can be any descriptive text), and `FileTypeExts` is a list of file extensions. If you do not specify this, the default is `All Files (*.*)`.\n\n- `string AndroidMimeType`: Android-specific MIME type. If you do not specify this, the default is `application/octet-stream`.\n\nThe method returns `bool` to indicate if the user successfully picked a file and saved the content.\n\n\u003e **Note**  \n\u003e There is no specific iOS and Mac Catalyst option but this feature works for them.\n\n![Windows Save File Picker](./imgs/win-save.png)\n\n**Example:**\n\n```cs\nvar bytes = Encoding.UTF8.GetBytes(TextEditor.Text ?? \"\");\nusing var memory = new MemoryStream(bytes);\n\nawait picker.SaveFileAsync(new(\"text.txt\", memory)\n{\n    AndroidMimeType = \"text/plain\",\n    WindowsFileTypes = (\"Text files\", new() { \".txt\", })\n});\n```\n\n\u003e **Warning**  \n\u003e As specified on [Setup Dependency Injection](#setup-dependency-injection), you need to call `ConfigureFilePicker()` to register Activity Result flow if you use Android Save Picker.\n\n# Screenshots on all platforms\n\n## App UI\n\n![Windows App](./imgs/win-app.png)\nWindows App\n\n![Android App](./imgs/and-ui.png)\nAndroid App\n\n![iOS App](./imgs/ios-ui.png)\niOS App\n\n![Mac Catalyst App](./imgs/mac-ui.png)\nMac Catalyst App\n\n## Open File Picker - Single File\n\n![Windows Open File Picker](./imgs/win-pick-single.png)\nWindows Open Single File Picker\n\n![Android Open File Picker](./imgs/and-pick-single.png)\nAndroid Open Single File Picker\n\n![iOS Open File Picker](./imgs/ios-pick-single.png)\niOS Open Single File Picker\n\n![Mac Catalyst Open File Picker](./imgs/mac-pick-single.png)\nMac Catalyst Open Single File Picker\n\n## Open File Picker - Multiple Files\n\n![Windows Open File Picker](./imgs/win-pick-multi.png)\nWindows Open Multiple Files Picker\n\n![Android Open File Picker](./imgs/and-pick-multi.png)\nAndroid Open Multiple Files Picker\n\n![iOS Open File Picker](./imgs/ios-pick-multi.png)\niOS Open Multiple Files Picker\n\n![Mac Catalyst Open File Picker](./imgs/mac-pick-multi.png)\nMac Catalyst Open Multiple Files Picker\n\n## Save File Picker\n\n![Windows Save File Picker](./imgs/win-save.png)\nWindows Save File Picker\n\n![Android Save File Picker](./imgs/and-save.png)\nAndroid Save File Picker\n\n![iOS Save File Picker](./imgs/ios-save.png)\niOS Save File Picker\n\n![Mac Catalyst Save File Picker](./imgs/mac-save.png)\nMac Catalyst Save File Picker\n","funding_links":["https://paypal.me/datvm"],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdatvm%2FLukeMauiFilePicker","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdatvm%2FLukeMauiFilePicker","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdatvm%2FLukeMauiFilePicker/lists"}