Skip to content
This repository was archived by the owner on Feb 22, 2023. It is now read-only.

Commit b1797c2

Browse files
[file_selector] Switch to Pigeon for macOS (#6902)
* Initial pigeon definition * Update Dart, and add Dart test coverage * Update Swift and native tests * Version bump * Format * Revert SDK change
1 parent b9206bc commit b1797c2

File tree

12 files changed

+1042
-340
lines changed

12 files changed

+1042
-340
lines changed

packages/file_selector/file_selector_macos/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
## 0.9.0+4
2+
3+
* Converts platform channel to Pigeon.
4+
15
## 0.9.0+3
26

37
* Changes XTypeGroup initialization from final to const.

packages/file_selector/file_selector_macos/example/macos/RunnerTests/RunnerTests.swift

Lines changed: 66 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,13 @@ class exampleTests: XCTestCase {
4747
panelController.openURLs = [URL(fileURLWithPath: returnPath)]
4848

4949
let called = XCTestExpectation()
50-
let call = FlutterMethodCall(methodName: "openFile", arguments: [:])
51-
plugin.handle(call) { result in
52-
XCTAssertEqual((result as! [String]?)![0], returnPath)
50+
let options = OpenPanelOptions(
51+
allowsMultipleSelection: false,
52+
canChooseDirectories: false,
53+
canChooseFiles: true,
54+
baseOptions: SavePanelOptions())
55+
plugin.displayOpenPanel(options: options) { paths in
56+
XCTAssertEqual(paths[0], returnPath)
5357
called.fulfill()
5458
}
5559

@@ -72,16 +76,16 @@ class exampleTests: XCTestCase {
7276
panelController.openURLs = [URL(fileURLWithPath: returnPath)]
7377

7478
let called = XCTestExpectation()
75-
let call = FlutterMethodCall(
76-
methodName: "openFile",
77-
arguments: [
78-
"initialDirectory": "/some/dir",
79-
"suggestedName": "a name",
80-
"confirmButtonText": "Open it!",
81-
]
82-
)
83-
plugin.handle(call) { result in
84-
XCTAssertEqual((result as! [String]?)![0], returnPath)
79+
let options = OpenPanelOptions(
80+
allowsMultipleSelection: false,
81+
canChooseDirectories: false,
82+
canChooseFiles: true,
83+
baseOptions: SavePanelOptions(
84+
directoryPath: "/some/dir",
85+
nameFieldStringValue: "a name",
86+
prompt: "Open it!"))
87+
plugin.displayOpenPanel(options: options) { paths in
88+
XCTAssertEqual(paths[0], returnPath)
8589
called.fulfill()
8690
}
8791

@@ -104,12 +108,12 @@ class exampleTests: XCTestCase {
104108
panelController.openURLs = returnPaths.map({ path in URL(fileURLWithPath: path) })
105109

106110
let called = XCTestExpectation()
107-
let call = FlutterMethodCall(
108-
methodName: "openFile",
109-
arguments: ["multiple": true]
110-
)
111-
plugin.handle(call) { result in
112-
let paths = (result as! [String]?)!
111+
let options = OpenPanelOptions(
112+
allowsMultipleSelection: true,
113+
canChooseDirectories: false,
114+
canChooseFiles: true,
115+
baseOptions: SavePanelOptions())
116+
plugin.displayOpenPanel(options: options) { paths in
113117
XCTAssertEqual(paths.count, returnPaths.count)
114118
XCTAssertEqual(paths[0], returnPaths[0])
115119
XCTAssertEqual(paths[1], returnPaths[1])
@@ -130,17 +134,17 @@ class exampleTests: XCTestCase {
130134
panelController.openURLs = [URL(fileURLWithPath: returnPath)]
131135

132136
let called = XCTestExpectation()
133-
let call = FlutterMethodCall(
134-
methodName: "openFile",
135-
arguments: [
136-
"acceptedTypes": [
137-
"extensions": ["txt", "json"],
138-
"UTIs": ["public.text", "public.image"],
139-
]
140-
]
141-
)
142-
plugin.handle(call) { result in
143-
XCTAssertEqual((result as! [String]?)![0], returnPath)
137+
let options = OpenPanelOptions(
138+
allowsMultipleSelection: true,
139+
canChooseDirectories: false,
140+
canChooseFiles: true,
141+
baseOptions: SavePanelOptions(
142+
allowedFileTypes: AllowedTypes(
143+
extensions: ["txt", "json"],
144+
mimeTypes: [],
145+
utis: ["public.text", "public.image"])))
146+
plugin.displayOpenPanel(options: options) { paths in
147+
XCTAssertEqual(paths[0], returnPath)
144148
called.fulfill()
145149
}
146150

@@ -158,9 +162,13 @@ class exampleTests: XCTestCase {
158162
panelController: panelController)
159163

160164
let called = XCTestExpectation()
161-
let call = FlutterMethodCall(methodName: "openFile", arguments: [:])
162-
plugin.handle(call) { result in
163-
XCTAssertNil(result)
165+
let options = OpenPanelOptions(
166+
allowsMultipleSelection: false,
167+
canChooseDirectories: false,
168+
canChooseFiles: true,
169+
baseOptions: SavePanelOptions())
170+
plugin.displayOpenPanel(options: options) { paths in
171+
XCTAssertEqual(paths.count, 0)
164172
called.fulfill()
165173
}
166174

@@ -178,9 +186,9 @@ class exampleTests: XCTestCase {
178186
panelController.saveURL = URL(fileURLWithPath: returnPath)
179187

180188
let called = XCTestExpectation()
181-
let call = FlutterMethodCall(methodName: "getSavePath", arguments: [:])
182-
plugin.handle(call) { result in
183-
XCTAssertEqual(result as! String?, returnPath)
189+
let options = SavePanelOptions()
190+
plugin.displaySavePanel(options: options) { path in
191+
XCTAssertEqual(path, returnPath)
184192
called.fulfill()
185193
}
186194

@@ -198,15 +206,11 @@ class exampleTests: XCTestCase {
198206
panelController.saveURL = URL(fileURLWithPath: returnPath)
199207

200208
let called = XCTestExpectation()
201-
let call = FlutterMethodCall(
202-
methodName: "getSavePath",
203-
arguments: [
204-
"initialDirectory": "/some/dir",
205-
"confirmButtonText": "Save it!",
206-
]
207-
)
208-
plugin.handle(call) { result in
209-
XCTAssertEqual(result as! String?, returnPath)
209+
let options = SavePanelOptions(
210+
directoryPath: "/some/dir",
211+
prompt: "Save it!")
212+
plugin.displaySavePanel(options: options) { path in
213+
XCTAssertEqual(path, returnPath)
210214
called.fulfill()
211215
}
212216

@@ -225,9 +229,9 @@ class exampleTests: XCTestCase {
225229
panelController: panelController)
226230

227231
let called = XCTestExpectation()
228-
let call = FlutterMethodCall(methodName: "getSavePath", arguments: [:])
229-
plugin.handle(call) { result in
230-
XCTAssertNil(result)
232+
let options = SavePanelOptions()
233+
plugin.displaySavePanel(options: options) { path in
234+
XCTAssertNil(path)
231235
called.fulfill()
232236
}
233237

@@ -245,9 +249,13 @@ class exampleTests: XCTestCase {
245249
panelController.openURLs = [URL(fileURLWithPath: returnPath)]
246250

247251
let called = XCTestExpectation()
248-
let call = FlutterMethodCall(methodName: "getDirectoryPath", arguments: [:])
249-
plugin.handle(call) { result in
250-
XCTAssertEqual(result as! String?, returnPath)
252+
let options = OpenPanelOptions(
253+
allowsMultipleSelection: false,
254+
canChooseDirectories: true,
255+
canChooseFiles: false,
256+
baseOptions: SavePanelOptions())
257+
plugin.displayOpenPanel(options: options) { paths in
258+
XCTAssertEqual(paths[0], returnPath)
251259
called.fulfill()
252260
}
253261

@@ -270,9 +278,13 @@ class exampleTests: XCTestCase {
270278
panelController: panelController)
271279

272280
let called = XCTestExpectation()
273-
let call = FlutterMethodCall(methodName: "getDirectoryPath", arguments: [:])
274-
plugin.handle(call) { result in
275-
XCTAssertNil(result)
281+
let options = OpenPanelOptions(
282+
allowsMultipleSelection: false,
283+
canChooseDirectories: true,
284+
canChooseFiles: false,
285+
baseOptions: SavePanelOptions())
286+
plugin.displayOpenPanel(options: options) { paths in
287+
XCTAssertEqual(paths.count, 0)
276288
called.fulfill()
277289
}
278290

packages/file_selector/file_selector_macos/lib/file_selector_macos.dart

Lines changed: 49 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,12 @@
33
// found in the LICENSE file.
44

55
import 'package:file_selector_platform_interface/file_selector_platform_interface.dart';
6-
import 'package:flutter/foundation.dart' show visibleForTesting;
7-
import 'package:flutter/services.dart';
86

9-
const MethodChannel _channel =
10-
MethodChannel('plugins.flutter.io/file_selector_macos');
7+
import 'src/messages.g.dart';
118

129
/// An implementation of [FileSelectorPlatform] for macOS.
1310
class FileSelectorMacOS extends FileSelectorPlatform {
14-
/// The MethodChannel that is being used by this implementation of the plugin.
15-
@visibleForTesting
16-
MethodChannel get channel => _channel;
11+
final FileSelectorApi _hostApi = FileSelectorApi();
1712

1813
/// Registers the macOS implementation.
1914
static void registerWith() {
@@ -26,16 +21,17 @@ class FileSelectorMacOS extends FileSelectorPlatform {
2621
String? initialDirectory,
2722
String? confirmButtonText,
2823
}) async {
29-
final List<String>? path = await _channel.invokeListMethod<String>(
30-
'openFile',
31-
<String, dynamic>{
32-
'acceptedTypes': _allowedTypeListFromTypeGroups(acceptedTypeGroups),
33-
'initialDirectory': initialDirectory,
34-
'confirmButtonText': confirmButtonText,
35-
'multiple': false,
36-
},
37-
);
38-
return path == null ? null : XFile(path.first);
24+
final List<String?> paths =
25+
await _hostApi.displayOpenPanel(OpenPanelOptions(
26+
allowsMultipleSelection: false,
27+
canChooseDirectories: false,
28+
canChooseFiles: true,
29+
baseOptions: SavePanelOptions(
30+
allowedFileTypes: _allowedTypesFromTypeGroups(acceptedTypeGroups),
31+
directoryPath: initialDirectory,
32+
prompt: confirmButtonText,
33+
)));
34+
return paths.isEmpty ? null : XFile(paths.first!);
3935
}
4036

4137
@override
@@ -44,16 +40,17 @@ class FileSelectorMacOS extends FileSelectorPlatform {
4440
String? initialDirectory,
4541
String? confirmButtonText,
4642
}) async {
47-
final List<String>? pathList = await _channel.invokeListMethod<String>(
48-
'openFile',
49-
<String, dynamic>{
50-
'acceptedTypes': _allowedTypeListFromTypeGroups(acceptedTypeGroups),
51-
'initialDirectory': initialDirectory,
52-
'confirmButtonText': confirmButtonText,
53-
'multiple': true,
54-
},
55-
);
56-
return pathList?.map((String path) => XFile(path)).toList() ?? <XFile>[];
43+
final List<String?> paths =
44+
await _hostApi.displayOpenPanel(OpenPanelOptions(
45+
allowsMultipleSelection: true,
46+
canChooseDirectories: false,
47+
canChooseFiles: true,
48+
baseOptions: SavePanelOptions(
49+
allowedFileTypes: _allowedTypesFromTypeGroups(acceptedTypeGroups),
50+
directoryPath: initialDirectory,
51+
prompt: confirmButtonText,
52+
)));
53+
return paths.map((String? path) => XFile(path!)).toList();
5754
}
5855

5956
@override
@@ -63,46 +60,42 @@ class FileSelectorMacOS extends FileSelectorPlatform {
6360
String? suggestedName,
6461
String? confirmButtonText,
6562
}) async {
66-
return _channel.invokeMethod<String>(
67-
'getSavePath',
68-
<String, dynamic>{
69-
'acceptedTypes': _allowedTypeListFromTypeGroups(acceptedTypeGroups),
70-
'initialDirectory': initialDirectory,
71-
'suggestedName': suggestedName,
72-
'confirmButtonText': confirmButtonText,
73-
},
74-
);
63+
return _hostApi.displaySavePanel(SavePanelOptions(
64+
allowedFileTypes: _allowedTypesFromTypeGroups(acceptedTypeGroups),
65+
directoryPath: initialDirectory,
66+
nameFieldStringValue: suggestedName,
67+
prompt: confirmButtonText,
68+
));
7569
}
7670

7771
@override
7872
Future<String?> getDirectoryPath({
7973
String? initialDirectory,
8074
String? confirmButtonText,
8175
}) async {
82-
return _channel.invokeMethod<String>(
83-
'getDirectoryPath',
84-
<String, dynamic>{
85-
'initialDirectory': initialDirectory,
86-
'confirmButtonText': confirmButtonText,
87-
},
88-
);
76+
final List<String?> paths =
77+
await _hostApi.displayOpenPanel(OpenPanelOptions(
78+
allowsMultipleSelection: false,
79+
canChooseDirectories: true,
80+
canChooseFiles: false,
81+
baseOptions: SavePanelOptions(
82+
directoryPath: initialDirectory,
83+
prompt: confirmButtonText,
84+
)));
85+
return paths.isEmpty ? null : paths.first;
8986
}
9087

9188
// Converts the type group list into a flat list of all allowed types, since
9289
// macOS doesn't support filter groups.
93-
Map<String, List<String>>? _allowedTypeListFromTypeGroups(
94-
List<XTypeGroup>? typeGroups) {
95-
const String extensionKey = 'extensions';
96-
const String mimeTypeKey = 'mimeTypes';
97-
const String utiKey = 'UTIs';
90+
AllowedTypes? _allowedTypesFromTypeGroups(List<XTypeGroup>? typeGroups) {
9891
if (typeGroups == null || typeGroups.isEmpty) {
9992
return null;
10093
}
101-
final Map<String, List<String>> allowedTypes = <String, List<String>>{
102-
extensionKey: <String>[],
103-
mimeTypeKey: <String>[],
104-
utiKey: <String>[],
105-
};
94+
final AllowedTypes allowedTypes = AllowedTypes(
95+
extensions: <String>[],
96+
mimeTypes: <String>[],
97+
utis: <String>[],
98+
);
10699
for (final XTypeGroup typeGroup in typeGroups) {
107100
// If any group allows everything, no filtering should be done.
108101
if (typeGroup.allowsAny) {
@@ -119,9 +112,9 @@ class FileSelectorMacOS extends FileSelectorPlatform {
119112
'"mimeTypes" must be non-empty for macOS if anything is '
120113
'non-empty.');
121114
}
122-
allowedTypes[extensionKey]!.addAll(typeGroup.extensions ?? <String>[]);
123-
allowedTypes[mimeTypeKey]!.addAll(typeGroup.mimeTypes ?? <String>[]);
124-
allowedTypes[utiKey]!.addAll(typeGroup.macUTIs ?? <String>[]);
115+
allowedTypes.extensions.addAll(typeGroup.extensions ?? <String>[]);
116+
allowedTypes.mimeTypes.addAll(typeGroup.mimeTypes ?? <String>[]);
117+
allowedTypes.utis.addAll(typeGroup.macUTIs ?? <String>[]);
125118
}
126119

127120
return allowedTypes;

0 commit comments

Comments
 (0)