[file_selector] Deprecates `macUTIs` (#3888)

Now that all in-repo consuming code has switch to `uniformTypeIdentifiers`, deprecate `macUTIs` (and minimize internal use of it in this package).

Fixes https://github.com/flutter/flutter/issues/103743
diff --git a/packages/file_selector/file_selector_platform_interface/CHANGELOG.md b/packages/file_selector/file_selector_platform_interface/CHANGELOG.md
index b66fa72..756e8cc 100644
--- a/packages/file_selector/file_selector_platform_interface/CHANGELOG.md
+++ b/packages/file_selector/file_selector_platform_interface/CHANGELOG.md
@@ -1,5 +1,6 @@
-## NEXT
+## 2.5.0
 
+* Deprecates `macUTIs` in favor of `uniformTypeIdentifiers`.
 * Aligns Dart and Flutter SDK constraints.
 
 ## 2.4.1
diff --git a/packages/file_selector/file_selector_platform_interface/lib/src/types/x_type_group/x_type_group.dart b/packages/file_selector/file_selector_platform_interface/lib/src/types/x_type_group/x_type_group.dart
index e12b431..0a556b3 100644
--- a/packages/file_selector/file_selector_platform_interface/lib/src/types/x_type_group/x_type_group.dart
+++ b/packages/file_selector/file_selector_platform_interface/lib/src/types/x_type_group/x_type_group.dart
@@ -14,9 +14,9 @@
     this.label,
     List<String>? extensions,
     this.mimeTypes,
-    List<String>? macUTIs,
     List<String>? uniformTypeIdentifiers,
     this.webWildCards,
+    @Deprecated('Use uniformTypeIdentifiers instead') List<String>? macUTIs,
   })  : _extensions = extensions,
         assert(uniformTypeIdentifiers == null || macUTIs == null,
             'Only one of uniformTypeIdentifiers or macUTIs can be non-null'),
@@ -47,8 +47,12 @@
       'label': label,
       'extensions': extensions,
       'mimeTypes': mimeTypes,
-      'macUTIs': macUTIs,
+      'uniformTypeIdentifiers': uniformTypeIdentifiers,
       'webWildCards': webWildCards,
+      // This is kept for backwards compatibility with anything that was
+      // relying on it, including implementers of `MethodChannelFileSelector`
+      // (since toJSON is used in the method channel parameter serialization).
+      'macUTIs': uniformTypeIdentifiers,
     };
   }
 
@@ -56,11 +60,12 @@
   bool get allowsAny {
     return (extensions?.isEmpty ?? true) &&
         (mimeTypes?.isEmpty ?? true) &&
-        (macUTIs?.isEmpty ?? true) &&
+        (uniformTypeIdentifiers?.isEmpty ?? true) &&
         (webWildCards?.isEmpty ?? true);
   }
 
   /// Returns the list of uniform type identifiers for this group
+  @Deprecated('Use uniformTypeIdentifiers instead')
   List<String>? get macUTIs => uniformTypeIdentifiers;
 
   static List<String>? _removeLeadingDots(List<String>? exts) => exts
diff --git a/packages/file_selector/file_selector_platform_interface/pubspec.yaml b/packages/file_selector/file_selector_platform_interface/pubspec.yaml
index a376719..c0ecf52 100644
--- a/packages/file_selector/file_selector_platform_interface/pubspec.yaml
+++ b/packages/file_selector/file_selector_platform_interface/pubspec.yaml
@@ -4,7 +4,7 @@
 issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+file_selector%22
 # NOTE: We strongly prefer non-breaking changes, even at the expense of a
 # less-clean API. See https://flutter.dev/go/platform-interface-breaking-changes
-version: 2.4.1
+version: 2.5.0
 
 environment:
   sdk: ">=2.17.0 <4.0.0"
diff --git a/packages/file_selector/file_selector_platform_interface/test/method_channel_file_selector_test.dart b/packages/file_selector/file_selector_platform_interface/test/method_channel_file_selector_test.dart
index c5438f7..2c7d455 100644
--- a/packages/file_selector/file_selector_platform_interface/test/method_channel_file_selector_test.dart
+++ b/packages/file_selector/file_selector_platform_interface/test/method_channel_file_selector_test.dart
@@ -35,14 +35,14 @@
           label: 'text',
           extensions: <String>['txt'],
           mimeTypes: <String>['text/plain'],
-          macUTIs: <String>['public.text'],
+          uniformTypeIdentifiers: <String>['public.text'],
         );
 
         const XTypeGroup groupTwo = XTypeGroup(
             label: 'image',
             extensions: <String>['jpg'],
             mimeTypes: <String>['image/jpg'],
-            macUTIs: <String>['public.image'],
+            uniformTypeIdentifiers: <String>['public.image'],
             webWildCards: <String>['image/*']);
 
         await plugin
@@ -97,14 +97,14 @@
           label: 'text',
           extensions: <String>['txt'],
           mimeTypes: <String>['text/plain'],
-          macUTIs: <String>['public.text'],
+          uniformTypeIdentifiers: <String>['public.text'],
         );
 
         const XTypeGroup groupTwo = XTypeGroup(
             label: 'image',
             extensions: <String>['jpg'],
             mimeTypes: <String>['image/jpg'],
-            macUTIs: <String>['public.image'],
+            uniformTypeIdentifiers: <String>['public.image'],
             webWildCards: <String>['image/*']);
 
         await plugin
@@ -160,14 +160,14 @@
           label: 'text',
           extensions: <String>['txt'],
           mimeTypes: <String>['text/plain'],
-          macUTIs: <String>['public.text'],
+          uniformTypeIdentifiers: <String>['public.text'],
         );
 
         const XTypeGroup groupTwo = XTypeGroup(
             label: 'image',
             extensions: <String>['jpg'],
             mimeTypes: <String>['image/jpg'],
-            macUTIs: <String>['public.image'],
+            uniformTypeIdentifiers: <String>['public.image'],
             webWildCards: <String>['image/*']);
 
         await plugin
diff --git a/packages/file_selector/file_selector_platform_interface/test/x_type_group_test.dart b/packages/file_selector/file_selector_platform_interface/test/x_type_group_test.dart
index 5ac5722..0a36c82 100644
--- a/packages/file_selector/file_selector_platform_interface/test/x_type_group_test.dart
+++ b/packages/file_selector/file_selector_platform_interface/test/x_type_group_test.dart
@@ -10,14 +10,14 @@
     test('toJSON() creates correct map', () {
       const List<String> extensions = <String>['txt', 'jpg'];
       const List<String> mimeTypes = <String>['text/plain'];
-      const List<String> macUTIs = <String>['public.plain-text'];
+      const List<String> uniformTypeIdentifiers = <String>['public.plain-text'];
       const List<String> webWildCards = <String>['image/*'];
       const String label = 'test group';
       const XTypeGroup group = XTypeGroup(
         label: label,
         extensions: extensions,
         mimeTypes: mimeTypes,
-        macUTIs: macUTIs,
+        uniformTypeIdentifiers: uniformTypeIdentifiers,
         webWildCards: webWildCards,
       );
 
@@ -25,8 +25,10 @@
       expect(jsonMap['label'], label);
       expect(jsonMap['extensions'], extensions);
       expect(jsonMap['mimeTypes'], mimeTypes);
-      expect(jsonMap['macUTIs'], macUTIs);
+      expect(jsonMap['uniformTypeIdentifiers'], uniformTypeIdentifiers);
       expect(jsonMap['webWildCards'], webWildCards);
+      // Validate the legacy key for backwards compatibility.
+      expect(jsonMap['macUTIs'], uniformTypeIdentifiers);
     });
 
     test('a wildcard group can be created', () {
@@ -37,7 +39,7 @@
       final Map<String, dynamic> jsonMap = group.toJSON();
       expect(jsonMap['extensions'], null);
       expect(jsonMap['mimeTypes'], null);
-      expect(jsonMap['macUTIs'], null);
+      expect(jsonMap['uniformTypeIdentifiers'], null);
       expect(jsonMap['webWildCards'], null);
       expect(group.allowsAny, true);
     });
@@ -47,7 +49,7 @@
         label: 'Any',
         extensions: <String>[],
         mimeTypes: <String>[],
-        macUTIs: <String>[],
+        uniformTypeIdentifiers: <String>[],
         webWildCards: <String>[],
       );
 
@@ -59,8 +61,8 @@
           XTypeGroup(label: 'extensions', extensions: <String>['txt']);
       const XTypeGroup mimeOnly =
           XTypeGroup(label: 'mime', mimeTypes: <String>['text/plain']);
-      const XTypeGroup utiOnly =
-          XTypeGroup(label: 'utis', macUTIs: <String>['public.text']);
+      const XTypeGroup utiOnly = XTypeGroup(
+          label: 'utis', uniformTypeIdentifiers: <String>['public.text']);
       const XTypeGroup webOnly =
           XTypeGroup(label: 'web', webWildCards: <String>['.txt']);
 
@@ -70,67 +72,73 @@
       expect(webOnly.allowsAny, false);
     });
 
-    test('passing only macUTIs should fill uniformTypeIdentifiers', () {
-      const List<String> macUTIs = <String>['public.plain-text'];
-      const XTypeGroup group = XTypeGroup(
-        macUTIs: macUTIs,
-      );
+    group('macUTIs -> uniformTypeIdentifiers transition', () {
+      test('passing only macUTIs should fill uniformTypeIdentifiers', () {
+        const List<String> uniformTypeIdentifiers = <String>[
+          'public.plain-text'
+        ];
+        const XTypeGroup group = XTypeGroup(
+          macUTIs: uniformTypeIdentifiers,
+        );
 
-      expect(group.uniformTypeIdentifiers, macUTIs);
-    });
+        expect(group.uniformTypeIdentifiers, uniformTypeIdentifiers);
+      });
 
-    test(
-        'passing only uniformTypeIdentifiers should fill uniformTypeIdentifiers',
-        () {
-      const List<String> uniformTypeIdentifiers = <String>['public.plain-text'];
-      const XTypeGroup group = XTypeGroup(
-        uniformTypeIdentifiers: uniformTypeIdentifiers,
-      );
+      test(
+          'passing only uniformTypeIdentifiers should fill uniformTypeIdentifiers',
+          () {
+        const List<String> uniformTypeIdentifiers = <String>[
+          'public.plain-text'
+        ];
+        const XTypeGroup group = XTypeGroup(
+          uniformTypeIdentifiers: uniformTypeIdentifiers,
+        );
 
-      expect(group.uniformTypeIdentifiers, uniformTypeIdentifiers);
-    });
+        expect(group.uniformTypeIdentifiers, uniformTypeIdentifiers);
+      });
 
-    test('macUTIs getter return macUTIs value passed in constructor', () {
-      const List<String> macUTIs = <String>['public.plain-text'];
-      const XTypeGroup group = XTypeGroup(
-        macUTIs: macUTIs,
-      );
+      test('macUTIs getter return macUTIs value passed in constructor', () {
+        const List<String> uniformTypeIdentifiers = <String>[
+          'public.plain-text'
+        ];
+        const XTypeGroup group = XTypeGroup(
+          macUTIs: uniformTypeIdentifiers,
+        );
 
-      expect(group.macUTIs, macUTIs);
-    });
+        expect(group.macUTIs, uniformTypeIdentifiers);
+      });
 
-    test(
-        'macUTIs getter returns uniformTypeIdentifiers value passed in constructor',
-        () {
-      const List<String> uniformTypeIdentifiers = <String>['public.plain-text'];
-      const XTypeGroup group = XTypeGroup(
-        uniformTypeIdentifiers: uniformTypeIdentifiers,
-      );
+      test(
+          'macUTIs getter returns uniformTypeIdentifiers value passed in constructor',
+          () {
+        const List<String> uniformTypeIdentifiers = <String>[
+          'public.plain-text'
+        ];
+        const XTypeGroup group = XTypeGroup(
+          uniformTypeIdentifiers: uniformTypeIdentifiers,
+        );
 
-      expect(group.macUTIs, uniformTypeIdentifiers);
-    });
+        expect(group.macUTIs, uniformTypeIdentifiers);
+      });
 
-    test('passing both uniformTypeIdentifiers and macUTIs should throw', () {
-      const List<String> macUTIs = <String>['public.plain-text'];
-      const List<String> uniformTypeIndentifiers = <String>[
-        'public.plain-images'
-      ];
-      expect(
-          () => XTypeGroup(
-              macUTIs: macUTIs,
-              uniformTypeIdentifiers: uniformTypeIndentifiers),
-          throwsA(predicate((Object? e) =>
-              e is AssertionError &&
-              e.message ==
-                  'Only one of uniformTypeIdentifiers or macUTIs can be non-null')));
-    });
+      test('passing both uniformTypeIdentifiers and macUTIs should throw', () {
+        expect(
+            () => XTypeGroup(
+                macUTIs: const <String>['public.plain-text'],
+                uniformTypeIdentifiers: const <String>['public.plain-images']),
+            throwsA(predicate((Object? e) =>
+                e is AssertionError &&
+                e.message ==
+                    'Only one of uniformTypeIdentifiers or macUTIs can be non-null')));
+      });
 
-    test(
-        'having uniformTypeIdentifiers and macUTIs as null should leave uniformTypeIdentifiers as null',
-        () {
-      const XTypeGroup group = XTypeGroup();
+      test(
+          'having uniformTypeIdentifiers and macUTIs as null should leave uniformTypeIdentifiers as null',
+          () {
+        const XTypeGroup group = XTypeGroup();
 
-      expect(group.uniformTypeIdentifiers, null);
+        expect(group.uniformTypeIdentifiers, null);
+      });
     });
 
     test('leading dots are removed from extensions', () {