Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for MacOS & Windows Desktop #271

Closed
JayPerfetto opened this issue May 10, 2020 · 39 comments
Closed

Support for MacOS & Windows Desktop #271

JayPerfetto opened this issue May 10, 2020 · 39 comments
Labels
feature New feature help wanted Extra attention is needed suggestion New feature or request

Comments

@JayPerfetto
Copy link

I get a platform exception trying to use this in a flutter app deployed to MacOS, but it works on android and iOS. Are there any plans to extend support to native mac / desktop?

Thanks!

@JayPerfetto JayPerfetto added the suggestion New feature or request label May 10, 2020
@miguelpruivo
Copy link
Owner

This plugin already has Desktop support through Flutter Go. You may want to take a look.

As Flutter Desktop itself is on a really early stage, I don’t have plans for it right now and it’s a low priority feature. However, support for Flutter Web is being added in the next days.

Thanks!

@miguelpruivo
Copy link
Owner

Good news is I added support to file_picker_web (check the web-support branch) using Flutter's team approach for multiple platform support. This actually opens the possibility to easily add support to MacOS Desktop as well, so this actually may be a feature in a near future.

@miguelpruivo miguelpruivo added the feature-candidate This issue might result in a feature to be implemented label May 10, 2020
@beevelop
Copy link

@miguelpruivo Could you provide some hints, what would be necessary to add support for macOS? The NeoSEALs team is happy to provide a respective PR 🚀

@softmarshmallow
Copy link

nothing helpful, just reminder that it does not work with macos

flutter: [FilePicker] Unsupported operation. Method not found. The exception thrown was: MissingPluginException(No implementation found for method any on channel miguelruivo.flutter.plugins.filepicker)
[ERROR:flutter/lib/ui/ui_dart_state.cc(166)] Unhandled Exception: MissingPluginException(No implementation found for method any on channel miguelruivo.flutter.plugins.filepicker)
#0      MethodChannel._invokeMethod (package:flutter/src/services/platform_channel.dart:157:7)
<asynchronous suspension>
#1      MethodChannel.invokeMethod (package:flutter/src/services/platform_channel.dart:332:12)
#2      FilePicker._getPath (package:file_picker/file_picker.dart:85:39)
#3      FilePicker.getFile (package:file_picker/file_picker.dart:50:15)
#4      importJson (package:schema_studio/utils/importer/import_json.dart:6:32)
#5      initMenubars.<anonymous closure> (package:schema_studio/utils/menubar.dart:14:17)
#6      MenuChannel._callbackHandler (package:menubar/src/menu_channel.dart:279:40)
#7      MethodChannel._handleAsMethodCall (package:flutter/src/services/platform_channel.dart:430:55)
#8      MethodChannel.setMethodCallHandler.<anonymous closure> (package:flutter/src/services/platform_channel.dart:383:33)
#9      _DefaultBinaryMessenger.handlePlatformMessage (package:flutter/src/services/binding.dart:258:33)
#10     _invoke3.<anonymous closure> (dart:ui/hooks.dart:296:15)
#11     _rootRun (dart:async/zone.dart:1190:13)
#12     _CustomZone.run (dart:async/zone.dart:1093:19)
#13     _CustomZone.runGuarded (dart:async/zone.dart:997:7)
#14     _invoke3 (dart:ui/hooks.dart:295:10)
#15     _dispatchPlatformMessage (dart:ui/hooks.dart:170:5)

@miguelpruivo
Copy link
Owner

Hi guys, it's pretty clear at this moment that this plugin doesn't support MacOS (only through Flutter go). Otherwise I'd have added it on supported features.

This might come in a feature, but for the time being, there are other priorities in the line.

Thank you!

@miguelpruivo
Copy link
Owner

Support for MacOS should now be an easy go since file_picker 2.0.0, because all platforms are now merged.

Looking forward it as soon as I have time, but feel free to issue a PR if you have any chance.

@Katekko
Copy link

Katekko commented Sep 28, 2020

Support for MacOS should now be an easy go since file_picker 2.0.0, because all platforms are now merged.

Looking forward it as soon as I have time, but feel free to issue a PR if you have any chance.

I'm testing now, but getting MissingPluginException

Do I need do something more to work on mac desktop?

@miguelpruivo
Copy link
Owner

miguelpruivo commented Sep 28, 2020

@Katekko it's not yet implemented.

For now, you can use Go implementation, which is supported by MacOS (and all other desktop platforms).

@Katekko
Copy link

Katekko commented Sep 28, 2020

@Katekko it's not yet implemented.

For now, you can use Go implementation, which is supported by MacOS (and all other desktop platforms).

I sorry.

So I just need follow the instructions on readme?

@miguelpruivo
Copy link
Owner

@Katekko yes, just follow this but you'll need to use file_picker: 1.13.3 as of now until #382 is resolved.

@miguelpruivo miguelpruivo changed the title Support for MacOS Desktop Support for MacOS & Windows Desktop Oct 5, 2020
@AliaksandrBadretdzinau
Copy link

AliaksandrBadretdzinau commented Oct 8, 2020

I have tested a sample application for selecting files in Flutter Windows desktop. Only "Select folder" function works (including a couple of fixes)

@vware
Copy link

vware commented Oct 15, 2020

Flutter support for desktop has matured a lot since may, are there any plans to support desktop OSs natively by now?

@miguelpruivo
Copy link
Owner

@vware might be a possibility yes. However currently I don’t have a windows machine so it won’t be easy to test it out on all three.

@vware
Copy link

vware commented Oct 15, 2020

thanks for the quick reply. just in case people look for a google-ish interim solution, there is a plugin that's part of the flutter desktop embedding effort:

file_chooser:
git:
url: git://github.com/google/flutter-desktop-embedding.git
path: plugins/file_chooser
ref: INSERT_HASH_HERE

@jlubeck
Copy link

jlubeck commented Dec 10, 2020

Just adding my support for this feature. I would love to help but have no idea how flutter plugins work. Is there anyway I can help?

@jlubeck
Copy link

jlubeck commented Dec 14, 2020

Was this supposed to be fixed by #382 or is that something else?

@miguelpruivo miguelpruivo added the help wanted Extra attention is needed label Jan 6, 2021
@rachmatg
Copy link

Try this on M1 based MacOS, it works, just got null path.

FilePickerResult result = await FilePicker.platform.pickFiles();
          if (result != null) {
            //File file = File(result.files.single.path);
            print(result.files.map((e) => e.path).toString());
            print(result.files.single.name);
          } else {
            // User canceled the picker
          }

@ErliSoares
Copy link

This feature would be very useful, I had to remove this package from my project and use filepicker_windows or file_picker_cross analyzing which, Flutter go limited me a lot.

@philenius
Copy link
Collaborator

philenius commented May 30, 2021

I can help with implementing a native desktop support without Flutter Go / Golang. In my case, Flutter Go / hover caused unstable / randomly crashing builds. I also experienced a lot of exceptions w.r.t. keyboard input which made me replace this plugin (flutter_file_picker) with my own implementation.
The approach for implementing native desktop support without Go isn't too difficult. I simply read the code of gen2brain/dlgs, on which flutter_file_picker is based, and implemented an equivalent code in Dart.

  • Windows: to open a file picker on Windows, one needs to call the Win32 API. The Win32 API can only be access via DLL libraries which are part of your Windows installation. To call functions in these DLLs, one must use foreign function interfaces (ffi). In this case, I used shell32.dll for picking directories and comdlg32.dll for picking files.
  • Linux: the implementation for Linux is based on a command line tool named qarma or zenity. The implementation simply invokes a shell command which itself opens a file picker dialog.
  • MacOS: same as for Linux. Only difference is that the command line tool is named osascript.

I have a working implementation for Windows and Linux. I cannot implement or test the MacOS version though.

@miguelpruivo are you interested in replacing the existing Go code with Dart code so that Go Flutter won't be needed anymore? If so, then I'd be happy to share my code and help to integrate it into your existing Flutter package. Please note, that my implementation has dependencies on the Dart packages ffi and path.

@softwaresinc
Copy link

I'd like to vote for this feature. hover is 2 years old and still alpha - not promising.
I could test the MacOS version.

@philenius
Copy link
Collaborator

@miguelpruivo is very busy so I decided to publish my own package file_picker_desktop which provides a native file picker dialog on Linux, macOS, and Windows without the dependency on Go Flutter: You can find the package here:

https://pub.dev/packages/file_picker_desktop

I tried to keep the API of my package as close as possible to the API of Miguel's package. So far, I have only published a pre-release 1.0.0-dev.1 because I couldn't test it on Apple hardware (I tested it manually on Linux and Windows).

@softwaresinc Could you please test the macOS version and give me feedback? The Git repository of my Dart package contains an example Flutter app for manually testing the file picker.

@Katekko
Copy link

Katekko commented Jul 15, 2021

@miguelpruivo is very busy so I decided to publish my own package file_picker_desktop which provides a native file picker dialog on Linux, macOS, and Windows without the dependency on Go Flutter: You can find the package here:

https://pub.dev/packages/file_picker_desktop

I tried to keep the API of my package as close as possible to the API of Miguel's package. So far, I have only published a pre-release 1.0.0-dev.1 because I couldn't test it on Apple hardware (I tested it manually on Linux and Windows).

@softwaresinc Could you please test the macOS version and give me feedback? The Git repository of my Dart package contains an example Flutter app for manually testing the file picker.

NIce job @philenius,
Did your package mantain for android and ios as well right?

@softwaresinc
Copy link

@Katekko I tested the file_picker_desktop on MacOS.
It did not work for me.
This line:
final String? fileSelectionResult = await runExecutableWithArguments
in file_picker_macos.dart
did not pop up a file picker and appeared to return (maybe asynchronously?) with null response.
(the /usr/bin/osascript was found correctly and arguments were set up)

@philenius
Copy link
Collaborator

@softwaresinc thank you for testing and reporting. I found the bug (the command line arguments for osascript were wrapped 2x in quotes which caused osascript to terminate immediately). I tested it on a friend's MacBook and released a new version. Thanks again.

@Katekko thank you. No, unfortunately my implementation only works on the desktop (Windows, macOS, and Linux). Ideally my code could be combined with Miguel's package so that people who want to support all platforms (without requiring Go Flutter) don't need the dependency on two separate packages.
According to the Flutter docs there are two types of packages:

  • Dart packages: my package is a Dart package because it is entirely written in Dart. With Dart packages, it is not possible to add platform-specific implementations in Kotlin/Java for Android or Swift/Objective-C for iOS. Although, one can use Platform.isLinux, Platform.isWindows, Platform.isMacOs to call different code depending on the current platform. But again, all code must be written in Dart.
  • Plugin packages: Miguel's package is a plugin package because it contains platform-specific implementations in the respective programming languages.

I haven't invested a lot of time but I tried and I couldn't figure out how to combine Miguel's plugin package with my implementation in Dart for Windows, macOS, and Linux.

@miguelpruivo
Copy link
Owner

@philenius thank you for your effort on this. Ideally and to keep things simple I’d rather add you as a maintainer of this package and merge the two together to provide a seamless experience across all platforms.

For now, until you have it all fully tested out it’s not a bad idea to have it as standalone package and then eventually deprecate it as soon as it’s merged with this one.

Currently I only have MacOS (and Windows through bootcamp) so I can’t fully test it.

Let me know your thoughts.

@philenius
Copy link
Collaborator

@miguelpruivo: I also think that merging my Dart implementation with your existing package would be a benefit for the Flutter community. Thank you for offering to cooperate on this. So, yes, I'd be happy to contribute my implementation!

Thanks to @softwaresinc I was able to fix the macOS implementation. As of right now, I'm not aware of any further bugs in my implementation. I also wrote unit tests and added a CI pipeline via GitHub Actions. Frankly, unit tests cannot test the actual invocation of the file picker GUI. Of course I've manually tested the Linux and Windows version (I've included an example app in my GitHub repo). To be on the safe side, I'd say let's wait a few weeks until more users have used my package.

I already figured out how to integrate my Dart code into your plugin package. We would have to extend the platforms map in pubspec.yaml and add linux, macos, and windows. But the problem is that Dart / Flutter then expects to find implementations in the respective programming language for each platform, that is in C for Linux, in C++ for Windows, and in Swift for macOS. By overwriting the key fileName, as you did with your implementation for the web, one can call Dart code no matter which platform.

...

flutter:
  plugin:
    platforms:
      android:
        package: com.mr.flutter.plugin.filepicker
        pluginClass: FilePickerPlugin
      ios:
        pluginClass: FilePickerPlugin
      linux:
        pluginClass: FilePickerPlugin
        fileName: _internal/file_picker_linux.dart
      macos:
        pluginClass: FilePickerPlugin
        fileName: _internal/file_picker_macos.dart
      web:
        pluginClass: FilePickerWeb
        fileName: _internal/file_picker_web.dart
      windows:
        pluginClass: FilePickerPlugin
        fileName: _internal/file_picker_windows.dart

@miguelpruivo
Copy link
Owner

@philenius that looks good to me. Is there any feature that you didn't manage to support on some platform or it was an easy port? I'm talking specifically of file type filters, multiple picks, picking directories and so on.

@smallqs
Copy link

smallqs commented Jul 27, 2021

Looking forward to the merger of "file_picker_desktop" and "file_picker"

@avbk
Copy link

avbk commented Jul 27, 2021

@philenius

To be on the safe side, I'd say let's wait a few weeks until more users have used my package.

I think the longer you wait the more people will rely on both packages and are forced to refactor their code in order to use the original package. Therefore I would love to see you integrating it sooner than later 😉

@philenius
Copy link
Collaborator

@miguelpruivo, luckily I copied your interfaces, classes, and enums (while giving credit of course).

There are only a few changes that I've made:

  • I removed the parameter allowCompression of the function pickFiles().
  • I didn't implement FilePickerStatus and therefore removed the parameter onFileLoading of the function pickFiles() (should be possible to implement though)
  • I didn't implement the function clearTemporaryFiles() because there are no temporary files on Linux, macOS, and Windows
  • I added the parameter dialogTitle to the functions pickFiles() and getDirectoryPath().

Other than that, everything works the same.

  • file type filters ✔️ (I copied your enum FileType and implemented the corresponding filter strings for all 3 platforms)
  • picking multiple files ✔️ (works on all platforms)
  • picking directories ✔️ (works on all platforms)

In summary, I just read the code of gen2brain/dlgs and re-implemented it in Dart. It was a rather simple port. Only, figuring out the implementation for Windows took me some nights.

You can try out my example app to verify that it works 😉 https://github.com/philenius/flutter_file_picker_desktop/tree/master/example

@avbk good point, let's get this done sooner than later 👍

@miguelpruivo
Copy link
Owner

@philenius much thank you for your effort. I'll take a look ASAP and merge it if it seems ok — after that you'll still be able to maintain it on this repo since all of the effort regarding the desktop platforms were yours.

@miguelpruivo miguelpruivo added feature New feature and removed feature-candidate This issue might result in a feature to be implemented labels Aug 10, 2021
@miguelpruivo
Copy link
Owner

@philenius on a first attempt seems to be working properly on MacOS. I'll merge it and update the docs accordingly. Then you can still maintain it. 🙂 I suggest you to deprecate your other published package to not confuse the users and prevent opening unnecessary issues.

Thank you very much.

@miguelpruivo
Copy link
Owner

@philenius version 4.0.0 is out with your plugin merged. 🎉 Feel free to discontinue it if you want and I'll give you maintainer permissions so you could still work on it if you want on this repo.

Thank you!

@bernaferrari
Copy link

I'm kind of confused with go-flutter still mentioned in the README and wiki.

@miguelpruivo
Copy link
Owner

Because it is still supported @bernaferrari.

@bernaferrari
Copy link

Can you mention why/when it is needed, what are the differences? Or if the new way is better, but it is still kept for compatibility.

@miguelpruivo
Copy link
Owner

@bernaferrari it's there for backward compatibility only, since there could be some devs that still use it. If you haven't use it yet, go for the native way, since it's already supported.

@alexmercerind
Copy link
Contributor

idk i use this on linux...
and see this on my console.

flutter: [MethodChannelFilePicker] Unsupported operation. Method not found. The exception thrown was: MissingPluginException(No implementation found for method any on channel miguelruivo.flutter.plugins.filepicker)
[ERROR:flutter/lib/ui/ui_dart_state.cc(199)] Unhandled Exception: MissingPluginException(No implementation found for method any on channel miguelruivo.flutter.plugins.filepicker)
#0      MethodChannel._invokeMethod (package:flutter/src/services/platform_channel.dart:156:7)
<asynchronous suspension>
#1      MethodChannel.invokeListMethod (package:flutter/src/services/platform_channel.dart:344:35)
<asynchronous suspension>
#2      FilePickerIO._getPath (package:file_picker/src/file_picker_io.dart:88:33)
<asynchronous suspension>
#3      IndexingState.build.<anonymous closure> (package:harmonoid/interface/settings/indexing.dart:172:15)
<asynchronous suspension>

is this something anyone aware of? or am i doing something wrong?

i literally just called

String? path = await FilePicker.platform.getDirectoryPath();

@philenius
Copy link
Collaborator

@alexmercerind which version of file_picker are you using? Starting from 4.x.y, this plugin doesn't require Go / go-flutter anymore. This error should only be possible with file_picker 3.x.y and older.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature New feature help wanted Extra attention is needed suggestion New feature or request
Projects
None yet
Development

No branches or pull requests