[path_provider] Migrated path_provider_ios to pigeon. (#5944)

* Migrated path_provider_ios to pigeon.

* increased flutter version to 3.0.0
diff --git a/packages/path_provider/path_provider_ios/CHANGELOG.md b/packages/path_provider/path_provider_ios/CHANGELOG.md
index 1940f5c..8569c1b 100644
--- a/packages/path_provider/path_provider_ios/CHANGELOG.md
+++ b/packages/path_provider/path_provider_ios/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 2.0.10
+
+* Switches backend to pigeon.
+
 ## 2.0.9
 
 * Fixes library_private_types_in_public_api, sort_child_properties_last and use_key_in_widget_constructors
diff --git a/packages/path_provider/path_provider_ios/example/ios/Runner.xcodeproj/project.pbxproj b/packages/path_provider/path_provider_ios/example/ios/Runner.xcodeproj/project.pbxproj
index fec246b..601985b 100644
--- a/packages/path_provider/path_provider_ios/example/ios/Runner.xcodeproj/project.pbxproj
+++ b/packages/path_provider/path_provider_ios/example/ios/Runner.xcodeproj/project.pbxproj
@@ -3,7 +3,7 @@
 	archiveVersion = 1;
 	classes = {
 	};
-	objectVersion = 50;
+	objectVersion = 46;
 	objects = {
 
 /* Begin PBXBuildFile section */
@@ -512,6 +512,7 @@
 					"$(PROJECT_DIR)/Flutter",
 				);
 				INFOPLIST_FILE = Runner/Info.plist;
+				IPHONEOS_DEPLOYMENT_TARGET = 11.0;
 				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
@@ -533,6 +534,7 @@
 					"$(PROJECT_DIR)/Flutter",
 				);
 				INFOPLIST_FILE = Runner/Info.plist;
+				IPHONEOS_DEPLOYMENT_TARGET = 11.0;
 				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
diff --git a/packages/path_provider/path_provider_ios/ios/Classes/FLTPathProviderPlugin.m b/packages/path_provider/path_provider_ios/ios/Classes/FLTPathProviderPlugin.m
index ac6a1be..82b8df5 100644
--- a/packages/path_provider/path_provider_ios/ios/Classes/FLTPathProviderPlugin.m
+++ b/packages/path_provider/path_provider_ios/ios/Classes/FLTPathProviderPlugin.m
@@ -3,47 +3,41 @@
 // found in the LICENSE file.
 
 #import "FLTPathProviderPlugin.h"
+#import "messages.g.h"
 
-NSString *GetDirectoryOfType(NSSearchPathDirectory dir) {
+static NSString *GetDirectoryOfType(NSSearchPathDirectory dir) {
   NSArray *paths = NSSearchPathForDirectoriesInDomains(dir, NSUserDomainMask, YES);
   return paths.firstObject;
 }
 
+@interface FLTPathProviderPlugin () <FLTPathProviderApi>
+@end
+
 @implementation FLTPathProviderPlugin
 
 + (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar> *)registrar {
-  FlutterMethodChannel *channel =
-      [FlutterMethodChannel methodChannelWithName:@"plugins.flutter.io/path_provider_ios"
-                                  binaryMessenger:registrar.messenger];
-  [channel setMethodCallHandler:^(FlutterMethodCall *call, FlutterResult result) {
-    if ([@"getTemporaryDirectory" isEqualToString:call.method]) {
-      result([self getTemporaryDirectory]);
-    } else if ([@"getApplicationDocumentsDirectory" isEqualToString:call.method]) {
-      result([self getApplicationDocumentsDirectory]);
-    } else if ([@"getApplicationSupportDirectory" isEqualToString:call.method]) {
-      result([self getApplicationSupportDirectory]);
-    } else if ([@"getLibraryDirectory" isEqualToString:call.method]) {
-      result([self getLibraryDirectory]);
-    } else {
-      result(FlutterMethodNotImplemented);
-    }
-  }];
+  FLTPathProviderPlugin *plugin = [[FLTPathProviderPlugin alloc] init];
+  FLTPathProviderApiSetup(registrar.messenger, plugin);
 }
 
-+ (NSString *)getTemporaryDirectory {
-  return GetDirectoryOfType(NSCachesDirectory);
-}
-
-+ (NSString *)getApplicationDocumentsDirectory {
+- (nullable NSString *)getApplicationDocumentsPathWithError:
+    (FlutterError *_Nullable __autoreleasing *_Nonnull)error {
   return GetDirectoryOfType(NSDocumentDirectory);
 }
 
-+ (NSString *)getApplicationSupportDirectory {
+- (nullable NSString *)getApplicationSupportPathWithError:
+    (FlutterError *_Nullable __autoreleasing *_Nonnull)error {
   return GetDirectoryOfType(NSApplicationSupportDirectory);
 }
 
-+ (NSString *)getLibraryDirectory {
+- (nullable NSString *)getLibraryPathWithError:
+    (FlutterError *_Nullable __autoreleasing *_Nonnull)error {
   return GetDirectoryOfType(NSLibraryDirectory);
 }
 
+- (nullable NSString *)getTemporaryPathWithError:
+    (FlutterError *_Nullable __autoreleasing *_Nonnull)error {
+  return GetDirectoryOfType(NSCachesDirectory);
+}
+
 @end
diff --git a/packages/path_provider/path_provider_ios/ios/Classes/messages.g.h b/packages/path_provider/path_provider_ios/ios/Classes/messages.g.h
new file mode 100644
index 0000000..b6c1d4d
--- /dev/null
+++ b/packages/path_provider/path_provider_ios/ios/Classes/messages.g.h
@@ -0,0 +1,28 @@
+// Copyright 2013 The Flutter Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+// Autogenerated from Pigeon (v3.1.5), do not edit directly.
+// See also: https://pub.dev/packages/pigeon
+#import <Foundation/Foundation.h>
+@protocol FlutterBinaryMessenger;
+@protocol FlutterMessageCodec;
+@class FlutterError;
+@class FlutterStandardTypedData;
+
+NS_ASSUME_NONNULL_BEGIN
+
+/// The codec used by FLTPathProviderApi.
+NSObject<FlutterMessageCodec> *FLTPathProviderApiGetCodec(void);
+
+@protocol FLTPathProviderApi
+- (nullable NSString *)getTemporaryPathWithError:(FlutterError *_Nullable *_Nonnull)error;
+- (nullable NSString *)getApplicationSupportPathWithError:(FlutterError *_Nullable *_Nonnull)error;
+- (nullable NSString *)getLibraryPathWithError:(FlutterError *_Nullable *_Nonnull)error;
+- (nullable NSString *)getApplicationDocumentsPathWithError:
+    (FlutterError *_Nullable *_Nonnull)error;
+@end
+
+extern void FLTPathProviderApiSetup(id<FlutterBinaryMessenger> binaryMessenger,
+                                    NSObject<FLTPathProviderApi> *_Nullable api);
+
+NS_ASSUME_NONNULL_END
diff --git a/packages/path_provider/path_provider_ios/ios/Classes/messages.g.m b/packages/path_provider/path_provider_ios/ios/Classes/messages.g.m
new file mode 100644
index 0000000..2589df1
--- /dev/null
+++ b/packages/path_provider/path_provider_ios/ios/Classes/messages.g.m
@@ -0,0 +1,138 @@
+// Copyright 2013 The Flutter Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+// Autogenerated from Pigeon (v3.1.5), do not edit directly.
+// See also: https://pub.dev/packages/pigeon
+#import "messages.g.h"
+#import <Flutter/Flutter.h>
+
+#if !__has_feature(objc_arc)
+#error File requires ARC to be enabled.
+#endif
+
+static NSDictionary<NSString *, id> *wrapResult(id result, FlutterError *error) {
+  NSDictionary *errorDict = (NSDictionary *)[NSNull null];
+  if (error) {
+    errorDict = @{
+      @"code" : (error.code ?: [NSNull null]),
+      @"message" : (error.message ?: [NSNull null]),
+      @"details" : (error.details ?: [NSNull null]),
+    };
+  }
+  return @{
+    @"result" : (result ?: [NSNull null]),
+    @"error" : errorDict,
+  };
+}
+
+@interface FLTPathProviderApiCodecReader : FlutterStandardReader
+@end
+@implementation FLTPathProviderApiCodecReader
+@end
+
+@interface FLTPathProviderApiCodecWriter : FlutterStandardWriter
+@end
+@implementation FLTPathProviderApiCodecWriter
+@end
+
+@interface FLTPathProviderApiCodecReaderWriter : FlutterStandardReaderWriter
+@end
+@implementation FLTPathProviderApiCodecReaderWriter
+- (FlutterStandardWriter *)writerWithData:(NSMutableData *)data {
+  return [[FLTPathProviderApiCodecWriter alloc] initWithData:data];
+}
+- (FlutterStandardReader *)readerWithData:(NSData *)data {
+  return [[FLTPathProviderApiCodecReader alloc] initWithData:data];
+}
+@end
+
+NSObject<FlutterMessageCodec> *FLTPathProviderApiGetCodec() {
+  static dispatch_once_t sPred = 0;
+  static FlutterStandardMessageCodec *sSharedObject = nil;
+  dispatch_once(&sPred, ^{
+    FLTPathProviderApiCodecReaderWriter *readerWriter =
+        [[FLTPathProviderApiCodecReaderWriter alloc] init];
+    sSharedObject = [FlutterStandardMessageCodec codecWithReaderWriter:readerWriter];
+  });
+  return sSharedObject;
+}
+
+void FLTPathProviderApiSetup(id<FlutterBinaryMessenger> binaryMessenger,
+                             NSObject<FLTPathProviderApi> *api) {
+  {
+    FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc]
+           initWithName:@"dev.flutter.pigeon.PathProviderApi.getTemporaryPath"
+        binaryMessenger:binaryMessenger
+                  codec:FLTPathProviderApiGetCodec()];
+    if (api) {
+      NSCAssert(
+          [api respondsToSelector:@selector(getTemporaryPathWithError:)],
+          @"FLTPathProviderApi api (%@) doesn't respond to @selector(getTemporaryPathWithError:)",
+          api);
+      [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
+        FlutterError *error;
+        NSString *output = [api getTemporaryPathWithError:&error];
+        callback(wrapResult(output, error));
+      }];
+    } else {
+      [channel setMessageHandler:nil];
+    }
+  }
+  {
+    FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc]
+           initWithName:@"dev.flutter.pigeon.PathProviderApi.getApplicationSupportPath"
+        binaryMessenger:binaryMessenger
+                  codec:FLTPathProviderApiGetCodec()];
+    if (api) {
+      NSCAssert([api respondsToSelector:@selector(getApplicationSupportPathWithError:)],
+                @"FLTPathProviderApi api (%@) doesn't respond to "
+                @"@selector(getApplicationSupportPathWithError:)",
+                api);
+      [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
+        FlutterError *error;
+        NSString *output = [api getApplicationSupportPathWithError:&error];
+        callback(wrapResult(output, error));
+      }];
+    } else {
+      [channel setMessageHandler:nil];
+    }
+  }
+  {
+    FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc]
+           initWithName:@"dev.flutter.pigeon.PathProviderApi.getLibraryPath"
+        binaryMessenger:binaryMessenger
+                  codec:FLTPathProviderApiGetCodec()];
+    if (api) {
+      NSCAssert(
+          [api respondsToSelector:@selector(getLibraryPathWithError:)],
+          @"FLTPathProviderApi api (%@) doesn't respond to @selector(getLibraryPathWithError:)",
+          api);
+      [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
+        FlutterError *error;
+        NSString *output = [api getLibraryPathWithError:&error];
+        callback(wrapResult(output, error));
+      }];
+    } else {
+      [channel setMessageHandler:nil];
+    }
+  }
+  {
+    FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc]
+           initWithName:@"dev.flutter.pigeon.PathProviderApi.getApplicationDocumentsPath"
+        binaryMessenger:binaryMessenger
+                  codec:FLTPathProviderApiGetCodec()];
+    if (api) {
+      NSCAssert([api respondsToSelector:@selector(getApplicationDocumentsPathWithError:)],
+                @"FLTPathProviderApi api (%@) doesn't respond to "
+                @"@selector(getApplicationDocumentsPathWithError:)",
+                api);
+      [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
+        FlutterError *error;
+        NSString *output = [api getApplicationDocumentsPathWithError:&error];
+        callback(wrapResult(output, error));
+      }];
+    } else {
+      [channel setMessageHandler:nil];
+    }
+  }
+}
diff --git a/packages/path_provider/path_provider_ios/lib/messages.g.dart b/packages/path_provider/path_provider_ios/lib/messages.g.dart
new file mode 100644
index 0000000..1914119
--- /dev/null
+++ b/packages/path_provider/path_provider_ios/lib/messages.g.dart
@@ -0,0 +1,124 @@
+// Copyright 2013 The Flutter Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+// Autogenerated from Pigeon (v3.1.5), do not edit directly.
+// See also: https://pub.dev/packages/pigeon
+// ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name
+// @dart = 2.12
+import 'dart:async';
+import 'dart:typed_data' show Uint8List, Int32List, Int64List, Float64List;
+
+import 'package:flutter/foundation.dart' show WriteBuffer, ReadBuffer;
+import 'package:flutter/services.dart';
+
+class _PathProviderApiCodec extends StandardMessageCodec {
+  const _PathProviderApiCodec();
+}
+
+class PathProviderApi {
+  /// Constructor for [PathProviderApi].  The [binaryMessenger] named argument is
+  /// available for dependency injection.  If it is left null, the default
+  /// BinaryMessenger will be used which routes to the host platform.
+  PathProviderApi({BinaryMessenger? binaryMessenger})
+      : _binaryMessenger = binaryMessenger;
+
+  final BinaryMessenger? _binaryMessenger;
+
+  static const MessageCodec<Object?> codec = _PathProviderApiCodec();
+
+  Future<String?> getTemporaryPath() async {
+    final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
+        'dev.flutter.pigeon.PathProviderApi.getTemporaryPath', codec,
+        binaryMessenger: _binaryMessenger);
+    final Map<Object?, Object?>? replyMap =
+        await channel.send(null) as Map<Object?, Object?>?;
+    if (replyMap == null) {
+      throw PlatformException(
+        code: 'channel-error',
+        message: 'Unable to establish connection on channel.',
+      );
+    } else if (replyMap['error'] != null) {
+      final Map<Object?, Object?> error =
+          (replyMap['error'] as Map<Object?, Object?>?)!;
+      throw PlatformException(
+        code: (error['code'] as String?)!,
+        message: error['message'] as String?,
+        details: error['details'],
+      );
+    } else {
+      return (replyMap['result'] as String?);
+    }
+  }
+
+  Future<String?> getApplicationSupportPath() async {
+    final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
+        'dev.flutter.pigeon.PathProviderApi.getApplicationSupportPath', codec,
+        binaryMessenger: _binaryMessenger);
+    final Map<Object?, Object?>? replyMap =
+        await channel.send(null) as Map<Object?, Object?>?;
+    if (replyMap == null) {
+      throw PlatformException(
+        code: 'channel-error',
+        message: 'Unable to establish connection on channel.',
+      );
+    } else if (replyMap['error'] != null) {
+      final Map<Object?, Object?> error =
+          (replyMap['error'] as Map<Object?, Object?>?)!;
+      throw PlatformException(
+        code: (error['code'] as String?)!,
+        message: error['message'] as String?,
+        details: error['details'],
+      );
+    } else {
+      return (replyMap['result'] as String?);
+    }
+  }
+
+  Future<String?> getLibraryPath() async {
+    final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
+        'dev.flutter.pigeon.PathProviderApi.getLibraryPath', codec,
+        binaryMessenger: _binaryMessenger);
+    final Map<Object?, Object?>? replyMap =
+        await channel.send(null) as Map<Object?, Object?>?;
+    if (replyMap == null) {
+      throw PlatformException(
+        code: 'channel-error',
+        message: 'Unable to establish connection on channel.',
+      );
+    } else if (replyMap['error'] != null) {
+      final Map<Object?, Object?> error =
+          (replyMap['error'] as Map<Object?, Object?>?)!;
+      throw PlatformException(
+        code: (error['code'] as String?)!,
+        message: error['message'] as String?,
+        details: error['details'],
+      );
+    } else {
+      return (replyMap['result'] as String?);
+    }
+  }
+
+  Future<String?> getApplicationDocumentsPath() async {
+    final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
+        'dev.flutter.pigeon.PathProviderApi.getApplicationDocumentsPath', codec,
+        binaryMessenger: _binaryMessenger);
+    final Map<Object?, Object?>? replyMap =
+        await channel.send(null) as Map<Object?, Object?>?;
+    if (replyMap == null) {
+      throw PlatformException(
+        code: 'channel-error',
+        message: 'Unable to establish connection on channel.',
+      );
+    } else if (replyMap['error'] != null) {
+      final Map<Object?, Object?> error =
+          (replyMap['error'] as Map<Object?, Object?>?)!;
+      throw PlatformException(
+        code: (error['code'] as String?)!,
+        message: error['message'] as String?,
+        details: error['details'],
+      );
+    } else {
+      return (replyMap['result'] as String?);
+    }
+  }
+}
diff --git a/packages/path_provider/path_provider_ios/lib/path_provider_ios.dart b/packages/path_provider/path_provider_ios/lib/path_provider_ios.dart
index 88becf2..05be053 100644
--- a/packages/path_provider/path_provider_ios/lib/path_provider_ios.dart
+++ b/packages/path_provider/path_provider_ios/lib/path_provider_ios.dart
@@ -4,16 +4,13 @@
 
 import 'dart:io';
 
-import 'package:flutter/foundation.dart' show visibleForTesting;
-import 'package:flutter/services.dart';
 import 'package:path_provider_platform_interface/path_provider_platform_interface.dart';
+import 'messages.g.dart';
 
 /// The iOS implementation of [PathProviderPlatform].
 class PathProviderIOS extends PathProviderPlatform {
   /// The method channel used to interact with the native platform.
-  @visibleForTesting
-  MethodChannel methodChannel =
-      const MethodChannel('plugins.flutter.io/path_provider_ios');
+  final PathProviderApi _pathProvider = PathProviderApi();
 
   /// Registers this class as the default instance of [PathProviderPlatform]
   static void registerWith() {
@@ -22,13 +19,12 @@
 
   @override
   Future<String?> getTemporaryPath() async {
-    return methodChannel.invokeMethod<String>('getTemporaryDirectory');
+    return _pathProvider.getTemporaryPath();
   }
 
   @override
   Future<String?> getApplicationSupportPath() async {
-    final String? path = await methodChannel
-        .invokeMethod<String>('getApplicationSupportDirectory');
+    final String? path = await _pathProvider.getApplicationSupportPath();
     if (path != null) {
       // Ensure the directory exists before returning it, for consistency with
       // other platforms.
@@ -39,13 +35,12 @@
 
   @override
   Future<String?> getLibraryPath() async {
-    return methodChannel.invokeMethod<String>('getLibraryDirectory');
+    return _pathProvider.getLibraryPath();
   }
 
   @override
   Future<String?> getApplicationDocumentsPath() async {
-    return methodChannel
-        .invokeMethod<String>('getApplicationDocumentsDirectory');
+    return _pathProvider.getApplicationDocumentsPath();
   }
 
   @override
diff --git a/packages/path_provider/path_provider_ios/pigeons/copyright.txt b/packages/path_provider/path_provider_ios/pigeons/copyright.txt
new file mode 100644
index 0000000..1236b63
--- /dev/null
+++ b/packages/path_provider/path_provider_ios/pigeons/copyright.txt
@@ -0,0 +1,3 @@
+Copyright 2013 The Flutter Authors. All rights reserved.
+Use of this source code is governed by a BSD-style license that can be
+found in the LICENSE file.
diff --git a/packages/path_provider/path_provider_ios/pigeons/messages.dart b/packages/path_provider/path_provider_ios/pigeons/messages.dart
new file mode 100644
index 0000000..2ed7991
--- /dev/null
+++ b/packages/path_provider/path_provider_ios/pigeons/messages.dart
@@ -0,0 +1,21 @@
+// Copyright 2013 The Flutter Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+import 'package:pigeon/pigeon.dart';
+
+@ConfigurePigeon(PigeonOptions(
+  input: 'pigeons/messages.dart',
+  objcOptions: ObjcOptions(prefix: 'FLT'),
+  objcHeaderOut: 'ios/Classes/messages.g.h',
+  objcSourceOut: 'ios/Classes/messages.g.m',
+  dartOut: 'lib/messages.g.dart',
+  dartTestOut: 'test/messages_test.g.dart',
+  copyrightHeader: 'pigeons/copyright.txt',
+))
+@HostApi(dartHostTestHandler: 'TestPathProviderApi')
+abstract class PathProviderApi {
+  String? getTemporaryPath();
+  String? getApplicationSupportPath();
+  String? getLibraryPath();
+  String? getApplicationDocumentsPath();
+}
diff --git a/packages/path_provider/path_provider_ios/pubspec.yaml b/packages/path_provider/path_provider_ios/pubspec.yaml
index d6c7de1..16d2f2e 100644
--- a/packages/path_provider/path_provider_ios/pubspec.yaml
+++ b/packages/path_provider/path_provider_ios/pubspec.yaml
@@ -2,11 +2,11 @@
 description: iOS implementation of the path_provider plugin.
 repository: https://github.com/flutter/plugins/tree/main/packages/path_provider/path_provider_ios
 issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+path_provider%22
-version: 2.0.9
+version: 2.0.10
 
 environment:
   sdk: ">=2.14.0 <3.0.0"
-  flutter: ">=2.8.0"
+  flutter: ">=3.0.0"
 
 flutter:
   plugin:
@@ -29,5 +29,6 @@
   integration_test:
     sdk: flutter
   path: ^1.8.0
+  pigeon: ^3.1.5
   plugin_platform_interface: ^2.0.0
   test: ^1.16.0
diff --git a/packages/path_provider/path_provider_ios/test/messages_test.g.dart b/packages/path_provider/path_provider_ios/test/messages_test.g.dart
new file mode 100644
index 0000000..d1c9ff8
--- /dev/null
+++ b/packages/path_provider/path_provider_ios/test/messages_test.g.dart
@@ -0,0 +1,88 @@
+// Copyright 2013 The Flutter Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+// Autogenerated from Pigeon (v3.1.5), do not edit directly.
+// See also: https://pub.dev/packages/pigeon
+// ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis
+// ignore_for_file: avoid_relative_lib_imports
+// @dart = 2.12
+import 'dart:async';
+import 'dart:typed_data' show Uint8List, Int32List, Int64List, Float64List;
+import 'package:flutter/foundation.dart' show WriteBuffer, ReadBuffer;
+import 'package:flutter/services.dart';
+import 'package:flutter_test/flutter_test.dart';
+
+import '../lib/messages.g.dart';
+
+class _TestPathProviderApiCodec extends StandardMessageCodec {
+  const _TestPathProviderApiCodec();
+}
+
+abstract class TestPathProviderApi {
+  static const MessageCodec<Object?> codec = _TestPathProviderApiCodec();
+
+  String? getTemporaryPath();
+  String? getApplicationSupportPath();
+  String? getLibraryPath();
+  String? getApplicationDocumentsPath();
+  static void setup(TestPathProviderApi? api,
+      {BinaryMessenger? binaryMessenger}) {
+    {
+      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
+          'dev.flutter.pigeon.PathProviderApi.getTemporaryPath', codec,
+          binaryMessenger: binaryMessenger);
+      if (api == null) {
+        channel.setMockMessageHandler(null);
+      } else {
+        channel.setMockMessageHandler((Object? message) async {
+          // ignore message
+          final String? output = api.getTemporaryPath();
+          return <Object?, Object?>{'result': output};
+        });
+      }
+    }
+    {
+      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
+          'dev.flutter.pigeon.PathProviderApi.getApplicationSupportPath', codec,
+          binaryMessenger: binaryMessenger);
+      if (api == null) {
+        channel.setMockMessageHandler(null);
+      } else {
+        channel.setMockMessageHandler((Object? message) async {
+          // ignore message
+          final String? output = api.getApplicationSupportPath();
+          return <Object?, Object?>{'result': output};
+        });
+      }
+    }
+    {
+      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
+          'dev.flutter.pigeon.PathProviderApi.getLibraryPath', codec,
+          binaryMessenger: binaryMessenger);
+      if (api == null) {
+        channel.setMockMessageHandler(null);
+      } else {
+        channel.setMockMessageHandler((Object? message) async {
+          // ignore message
+          final String? output = api.getLibraryPath();
+          return <Object?, Object?>{'result': output};
+        });
+      }
+    }
+    {
+      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
+          'dev.flutter.pigeon.PathProviderApi.getApplicationDocumentsPath',
+          codec,
+          binaryMessenger: binaryMessenger);
+      if (api == null) {
+        channel.setMockMessageHandler(null);
+      } else {
+        channel.setMockMessageHandler((Object? message) async {
+          // ignore message
+          final String? output = api.getApplicationDocumentsPath();
+          return <Object?, Object?>{'result': output};
+        });
+      }
+    }
+  }
+}
diff --git a/packages/path_provider/path_provider_ios/test/path_provider_ios_test.dart b/packages/path_provider/path_provider_ios/test/path_provider_ios_test.dart
index 40f81c5..16a7cd8 100644
--- a/packages/path_provider/path_provider_ios/test/path_provider_ios_test.dart
+++ b/packages/path_provider/path_provider_ios/test/path_provider_ios_test.dart
@@ -4,17 +4,35 @@
 
 import 'dart:io';
 
-import 'package:flutter/services.dart';
 import 'package:flutter_test/flutter_test.dart';
 import 'package:path/path.dart' as p;
 import 'package:path_provider_ios/path_provider_ios.dart';
+import 'messages_test.g.dart';
+
+class _Api implements TestPathProviderApi {
+  String? applicationDocumentsPath;
+  String? applicationSupportPath;
+  String? libraryPath;
+  String? temporaryPath;
+
+  @override
+  String? getApplicationDocumentsPath() => applicationDocumentsPath;
+
+  @override
+  String? getApplicationSupportPath() => applicationSupportPath;
+
+  @override
+  String? getLibraryPath() => libraryPath;
+
+  @override
+  String? getTemporaryPath() => temporaryPath;
+}
 
 void main() {
   TestWidgetsFlutterBinding.ensureInitialized();
 
   group('PathProviderIOS', () {
     late PathProviderIOS pathProvider;
-    late List<MethodCall> log;
     // These unit tests use the actual filesystem, since an injectable
     // filesystem would add a runtime dependency to the package, so everything
     // is contained to a temporary directory.
@@ -24,6 +42,7 @@
     late String applicationSupportPath;
     late String libraryPath;
     late String applicationDocumentsPath;
+    late _Api api;
 
     setUp(() async {
       pathProvider = PathProviderIOS();
@@ -37,24 +56,12 @@
       applicationDocumentsPath =
           p.join(basePath, 'application', 'documents', 'path');
 
-      log = <MethodCall>[];
-      TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger
-          .setMockMethodCallHandler(pathProvider.methodChannel,
-              (MethodCall methodCall) async {
-        log.add(methodCall);
-        switch (methodCall.method) {
-          case 'getTemporaryDirectory':
-            return temporaryPath;
-          case 'getApplicationSupportDirectory':
-            return applicationSupportPath;
-          case 'getLibraryDirectory':
-            return libraryPath;
-          case 'getApplicationDocumentsDirectory':
-            return applicationDocumentsPath;
-          default:
-            return null;
-        }
-      });
+      api = _Api();
+      api.applicationDocumentsPath = applicationDocumentsPath;
+      api.applicationSupportPath = applicationSupportPath;
+      api.libraryPath = libraryPath;
+      api.temporaryPath = temporaryPath;
+      TestPathProviderApi.setup(api);
     });
 
     tearDown(() {
@@ -63,21 +70,11 @@
 
     test('getTemporaryPath', () async {
       final String? path = await pathProvider.getTemporaryPath();
-      expect(
-        log,
-        <Matcher>[isMethodCall('getTemporaryDirectory', arguments: null)],
-      );
       expect(path, temporaryPath);
     });
 
     test('getApplicationSupportPath', () async {
       final String? path = await pathProvider.getApplicationSupportPath();
-      expect(
-        log,
-        <Matcher>[
-          isMethodCall('getApplicationSupportDirectory', arguments: null)
-        ],
-      );
       expect(path, applicationSupportPath);
     });
 
@@ -89,21 +86,11 @@
 
     test('getLibraryPath', () async {
       final String? path = await pathProvider.getLibraryPath();
-      expect(
-        log,
-        <Matcher>[isMethodCall('getLibraryDirectory', arguments: null)],
-      );
       expect(path, libraryPath);
     });
 
     test('getApplicationDocumentsPath', () async {
       final String? path = await pathProvider.getApplicationDocumentsPath();
-      expect(
-        log,
-        <Matcher>[
-          isMethodCall('getApplicationDocumentsDirectory', arguments: null)
-        ],
-      );
       expect(path, applicationDocumentsPath);
     });