[file_selector] Basic iOS implementation (#5448)

diff --git a/packages/file_selector/file_selector_ios/.gitignore b/packages/file_selector/file_selector_ios/.gitignore
new file mode 100644
index 0000000..9be145f
--- /dev/null
+++ b/packages/file_selector/file_selector_ios/.gitignore
@@ -0,0 +1,29 @@
+# Miscellaneous
+*.class
+*.log
+*.pyc
+*.swp
+.DS_Store
+.atom/
+.buildlog/
+.history
+.svn/
+
+# IntelliJ related
+*.iml
+*.ipr
+*.iws
+.idea/
+
+# The .vscode folder contains launch configuration and tasks you configure in
+# VS Code which you may wish to be included in version control, so this line
+# is commented out by default.
+#.vscode/
+
+# Flutter/Dart/Pub related
+# Libraries should not include pubspec.lock, per https://dart.dev/guides/libraries/private-files#pubspeclock.
+/pubspec.lock
+**/doc/api/
+.dart_tool/
+.packages
+build/
diff --git a/packages/file_selector/file_selector_ios/.metadata b/packages/file_selector/file_selector_ios/.metadata
new file mode 100644
index 0000000..295d2f7
--- /dev/null
+++ b/packages/file_selector/file_selector_ios/.metadata
@@ -0,0 +1,30 @@
+# This file tracks properties of this Flutter project.
+# Used by Flutter tool to assess capabilities and perform upgrades etc.
+#
+# This file should be version controlled.
+
+version:
+  revision: ac1aa511ca94f46c7e80b94dafd521de35e808e5
+  channel: master
+
+project_type: plugin
+
+# Tracks metadata for the flutter migrate command
+migration:
+  platforms:
+    - platform: root
+      create_revision: ac1aa511ca94f46c7e80b94dafd521de35e808e5
+      base_revision: ac1aa511ca94f46c7e80b94dafd521de35e808e5
+    - platform: ios
+      create_revision: ac1aa511ca94f46c7e80b94dafd521de35e808e5
+      base_revision: ac1aa511ca94f46c7e80b94dafd521de35e808e5
+
+  # User provided section
+
+  # List of Local paths (relative to this file) that should be
+  # ignored by the migrate tool.
+  #
+  # Files that are not part of the templates will be ignored by default.
+  unmanaged_files:
+    - 'lib/main.dart'
+    - 'ios/Runner.xcodeproj/project.pbxproj'
diff --git a/packages/file_selector/file_selector_ios/AUTHORS b/packages/file_selector/file_selector_ios/AUTHORS
new file mode 100644
index 0000000..557dff9
--- /dev/null
+++ b/packages/file_selector/file_selector_ios/AUTHORS
@@ -0,0 +1,6 @@
+# Below is a list of people and organizations that have contributed
+# to the Flutter project. Names should be added to the list like so:
+#
+#   Name/Organization <email address>
+
+Google Inc.
diff --git a/packages/file_selector/file_selector_ios/CHANGELOG.md b/packages/file_selector/file_selector_ios/CHANGELOG.md
new file mode 100644
index 0000000..8c5d885
--- /dev/null
+++ b/packages/file_selector/file_selector_ios/CHANGELOG.md
@@ -0,0 +1,3 @@
+## 0.5.0
+
+* Initial iOS implementation of `file_selector`.
diff --git a/packages/file_selector/file_selector_ios/LICENSE b/packages/file_selector/file_selector_ios/LICENSE
new file mode 100644
index 0000000..c6823b8
--- /dev/null
+++ b/packages/file_selector/file_selector_ios/LICENSE
@@ -0,0 +1,25 @@
+Copyright 2013 The Flutter Authors. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+    * Neither the name of Google Inc. nor the names of its
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/packages/file_selector/file_selector_ios/README.md b/packages/file_selector/file_selector_ios/README.md
new file mode 100644
index 0000000..23b234d
--- /dev/null
+++ b/packages/file_selector/file_selector_ios/README.md
@@ -0,0 +1,19 @@
+# file\_selector\_ios
+
+The iOS implementation of [`file_selector`][1].
+
+## Usage
+
+### Importing the package
+
+This implementation has not yet been endorsed, meaning that you need to
+[depend on `file_selector_ios`][2] in addition to
+[depending on `file_selector`][3].
+
+Once your pubspec includes the ios implementation, you can use the
+`file_selector` APIs normally. You should not use the `file_selector_ios`
+APIs directly.
+
+[1]: https://pub.dev/packages/file_selector
+[2]: https://pub.dev/packages/file_selector_ios/install
+[3]: https://pub.dev/packages/file_selector/install
\ No newline at end of file
diff --git a/packages/file_selector/file_selector_ios/example/.gitignore b/packages/file_selector/file_selector_ios/example/.gitignore
new file mode 100644
index 0000000..0fa6b67
--- /dev/null
+++ b/packages/file_selector/file_selector_ios/example/.gitignore
@@ -0,0 +1,46 @@
+# Miscellaneous
+*.class
+*.log
+*.pyc
+*.swp
+.DS_Store
+.atom/
+.buildlog/
+.history
+.svn/
+
+# IntelliJ related
+*.iml
+*.ipr
+*.iws
+.idea/
+
+# The .vscode folder contains launch configuration and tasks you configure in
+# VS Code which you may wish to be included in version control, so this line
+# is commented out by default.
+#.vscode/
+
+# Flutter/Dart/Pub related
+**/doc/api/
+**/ios/Flutter/.last_build_id
+.dart_tool/
+.flutter-plugins
+.flutter-plugins-dependencies
+.packages
+.pub-cache/
+.pub/
+/build/
+
+# Web related
+lib/generated_plugin_registrant.dart
+
+# Symbolication related
+app.*.symbols
+
+# Obfuscation related
+app.*.map.json
+
+# Android Studio will place build artifacts here
+/android/app/debug
+/android/app/profile
+/android/app/release
diff --git a/packages/file_selector/file_selector_ios/example/.metadata b/packages/file_selector/file_selector_ios/example/.metadata
new file mode 100644
index 0000000..3c3e4b5
--- /dev/null
+++ b/packages/file_selector/file_selector_ios/example/.metadata
@@ -0,0 +1,10 @@
+# This file tracks properties of this Flutter project.
+# Used by Flutter tool to assess capabilities and perform upgrades etc.
+#
+# This file should be version controlled and should not be manually edited.
+
+version:
+  revision: 5464c5bac742001448fe4fc0597be939379f88ea
+  channel: stable
+
+project_type: app
diff --git a/packages/file_selector/file_selector_ios/example/README.md b/packages/file_selector/file_selector_ios/example/README.md
new file mode 100644
index 0000000..9ed63fd
--- /dev/null
+++ b/packages/file_selector/file_selector_ios/example/README.md
@@ -0,0 +1,4 @@
+# `file_selector_ios` example
+
+Demonstrates iOS implementation of the
+[`file_selector` plugin](https://pub.dev/packages/file_selector).
\ No newline at end of file
diff --git a/packages/file_selector/file_selector_ios/example/ios/.gitignore b/packages/file_selector/file_selector_ios/example/ios/.gitignore
new file mode 100644
index 0000000..7a7f987
--- /dev/null
+++ b/packages/file_selector/file_selector_ios/example/ios/.gitignore
@@ -0,0 +1,34 @@
+**/dgph
+*.mode1v3
+*.mode2v3
+*.moved-aside
+*.pbxuser
+*.perspectivev3
+**/*sync/
+.sconsign.dblite
+.tags*
+**/.vagrant/
+**/DerivedData/
+Icon?
+**/Pods/
+**/.symlinks/
+profile
+xcuserdata
+**/.generated/
+Flutter/App.framework
+Flutter/Flutter.framework
+Flutter/Flutter.podspec
+Flutter/Generated.xcconfig
+Flutter/ephemeral/
+Flutter/app.flx
+Flutter/app.zip
+Flutter/flutter_assets/
+Flutter/flutter_export_environment.sh
+ServiceDefinitions.json
+Runner/GeneratedPluginRegistrant.*
+
+# Exceptions to above rules.
+!default.mode1v3
+!default.mode2v3
+!default.pbxuser
+!default.perspectivev3
diff --git a/packages/file_selector/file_selector_ios/example/ios/Flutter/AppFrameworkInfo.plist b/packages/file_selector/file_selector_ios/example/ios/Flutter/AppFrameworkInfo.plist
new file mode 100644
index 0000000..9625e10
--- /dev/null
+++ b/packages/file_selector/file_selector_ios/example/ios/Flutter/AppFrameworkInfo.plist
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+  <key>CFBundleDevelopmentRegion</key>
+  <string>en</string>
+  <key>CFBundleExecutable</key>
+  <string>App</string>
+  <key>CFBundleIdentifier</key>
+  <string>io.flutter.flutter.app</string>
+  <key>CFBundleInfoDictionaryVersion</key>
+  <string>6.0</string>
+  <key>CFBundleName</key>
+  <string>App</string>
+  <key>CFBundlePackageType</key>
+  <string>FMWK</string>
+  <key>CFBundleShortVersionString</key>
+  <string>1.0</string>
+  <key>CFBundleSignature</key>
+  <string>????</string>
+  <key>CFBundleVersion</key>
+  <string>1.0</string>
+  <key>MinimumOSVersion</key>
+  <string>11.0</string>
+</dict>
+</plist>
diff --git a/packages/file_selector/file_selector_ios/example/ios/Flutter/Debug.xcconfig b/packages/file_selector/file_selector_ios/example/ios/Flutter/Debug.xcconfig
new file mode 100644
index 0000000..ec97fc6
--- /dev/null
+++ b/packages/file_selector/file_selector_ios/example/ios/Flutter/Debug.xcconfig
@@ -0,0 +1,2 @@
+#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
+#include "Generated.xcconfig"
diff --git a/packages/file_selector/file_selector_ios/example/ios/Flutter/Release.xcconfig b/packages/file_selector/file_selector_ios/example/ios/Flutter/Release.xcconfig
new file mode 100644
index 0000000..c4855bf
--- /dev/null
+++ b/packages/file_selector/file_selector_ios/example/ios/Flutter/Release.xcconfig
@@ -0,0 +1,2 @@
+#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
+#include "Generated.xcconfig"
diff --git a/packages/file_selector/file_selector_ios/example/ios/Podfile b/packages/file_selector/file_selector_ios/example/ios/Podfile
new file mode 100644
index 0000000..3c0b314
--- /dev/null
+++ b/packages/file_selector/file_selector_ios/example/ios/Podfile
@@ -0,0 +1,46 @@
+# Uncomment this line to define a global platform for your project
+# platform :ios, '11.0'
+
+# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
+ENV['COCOAPODS_DISABLE_STATS'] = 'true'
+
+project 'Runner', {
+  'Debug' => :debug,
+  'Profile' => :release,
+  'Release' => :release,
+}
+
+def flutter_root
+  generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__)
+  unless File.exist?(generated_xcode_build_settings_path)
+    raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first"
+  end
+
+  File.foreach(generated_xcode_build_settings_path) do |line|
+    matches = line.match(/FLUTTER_ROOT\=(.*)/)
+    return matches[1].strip if matches
+  end
+  raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get"
+end
+
+require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)
+
+flutter_ios_podfile_setup
+
+target 'Runner' do
+  use_frameworks!
+  use_modular_headers!
+
+  flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
+  target 'RunnerTests' do
+    inherit! :search_paths
+    # Pods for testing
+    pod 'OCMock', '~> 3.8.1'
+  end
+end
+
+post_install do |installer|
+  installer.pods_project.targets.each do |target|
+    flutter_additional_ios_build_settings(target)
+  end
+end
diff --git a/packages/file_selector/file_selector_ios/example/ios/Runner.xcodeproj/project.pbxproj b/packages/file_selector/file_selector_ios/example/ios/Runner.xcodeproj/project.pbxproj
new file mode 100644
index 0000000..e21f78a
--- /dev/null
+++ b/packages/file_selector/file_selector_ios/example/ios/Runner.xcodeproj/project.pbxproj
@@ -0,0 +1,771 @@
+// !$*UTF8*$!
+{
+	archiveVersion = 1;
+	classes = {
+	};
+	objectVersion = 54;
+	objects = {
+
+/* Begin PBXBuildFile section */
+		1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
+		21160A929DC757957DE39F1E /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 000792269CB6B9FE88AC567C /* Pods_Runner.framework */; };
+		3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
+		6165A2F80DFA224EAF50A1D5 /* Pods_RunnerTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AC3841659BF3693FAC5A2F8F /* Pods_RunnerTests.framework */; };
+		74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
+		97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
+		97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
+		97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
+		C71AE4C8281C6B6B0086307A /* FileSelectorTests.m in Sources */ = {isa = PBXBuildFile; fileRef = C71AE4C5281C6B530086307A /* FileSelectorTests.m */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXContainerItemProxy section */
+		C71AE4BA281C6A090086307A /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 97C146E61CF9000F007C117D /* Project object */;
+			proxyType = 1;
+			remoteGlobalIDString = 97C146ED1CF9000F007C117D;
+			remoteInfo = Runner;
+		};
+/* End PBXContainerItemProxy section */
+
+/* Begin PBXCopyFilesBuildPhase section */
+		9705A1C41CF9048500538489 /* Embed Frameworks */ = {
+			isa = PBXCopyFilesBuildPhase;
+			buildActionMask = 2147483647;
+			dstPath = "";
+			dstSubfolderSpec = 10;
+			files = (
+			);
+			name = "Embed Frameworks";
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXCopyFilesBuildPhase section */
+
+/* Begin PBXFileReference section */
+		000792269CB6B9FE88AC567C /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
+		1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; };
+		1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
+		3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
+		4A27CC0DB4EF6669B637A1E8 /* Pods-RunnerTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.debug.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.debug.xcconfig"; sourceTree = "<group>"; };
+		5667547C6832727A744371E2 /* Pods-RunnerTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.release.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.release.xcconfig"; sourceTree = "<group>"; };
+		5C0E87EDCB9350EC4916E293 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = "<group>"; };
+		74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = "<group>"; };
+		74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
+		786CCB880423FD6D1019F59B /* Pods-RunnerTests.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.profile.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.profile.xcconfig"; sourceTree = "<group>"; };
+		79C120FEED85F112A72B5D35 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };
+		7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; };
+		9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = "<group>"; };
+		9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = "<group>"; };
+		97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; };
+		97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
+		97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
+		97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
+		97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
+		AC3841659BF3693FAC5A2F8F /* Pods_RunnerTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RunnerTests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
+		C71AE4B6281C6A090086307A /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
+		C71AE4C5281C6B530086307A /* FileSelectorTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FileSelectorTests.m; sourceTree = "<group>"; };
+		F818CE2D7CDF8AFF94707327 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+		97C146EB1CF9000F007C117D /* Frameworks */ = {
+			isa = PBXFrameworksBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				21160A929DC757957DE39F1E /* Pods_Runner.framework in Frameworks */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+		C71AE4B3281C6A090086307A /* Frameworks */ = {
+			isa = PBXFrameworksBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				6165A2F80DFA224EAF50A1D5 /* Pods_RunnerTests.framework in Frameworks */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+		2E44EE3EE3BCCAB6933171F8 /* Pods */ = {
+			isa = PBXGroup;
+			children = (
+				79C120FEED85F112A72B5D35 /* Pods-Runner.debug.xcconfig */,
+				F818CE2D7CDF8AFF94707327 /* Pods-Runner.release.xcconfig */,
+				5C0E87EDCB9350EC4916E293 /* Pods-Runner.profile.xcconfig */,
+				4A27CC0DB4EF6669B637A1E8 /* Pods-RunnerTests.debug.xcconfig */,
+				5667547C6832727A744371E2 /* Pods-RunnerTests.release.xcconfig */,
+				786CCB880423FD6D1019F59B /* Pods-RunnerTests.profile.xcconfig */,
+			);
+			path = Pods;
+			sourceTree = "<group>";
+		};
+		9740EEB11CF90186004384FC /* Flutter */ = {
+			isa = PBXGroup;
+			children = (
+				3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */,
+				9740EEB21CF90195004384FC /* Debug.xcconfig */,
+				7AFA3C8E1D35360C0083082E /* Release.xcconfig */,
+				9740EEB31CF90195004384FC /* Generated.xcconfig */,
+			);
+			name = Flutter;
+			sourceTree = "<group>";
+		};
+		97C146E51CF9000F007C117D = {
+			isa = PBXGroup;
+			children = (
+				C71AE4C4281C6B370086307A /* RunnerTests */,
+				9740EEB11CF90186004384FC /* Flutter */,
+				97C146F01CF9000F007C117D /* Runner */,
+				97C146EF1CF9000F007C117D /* Products */,
+				2E44EE3EE3BCCAB6933171F8 /* Pods */,
+				C832A34FD3BC866442874ED0 /* Frameworks */,
+			);
+			sourceTree = "<group>";
+		};
+		97C146EF1CF9000F007C117D /* Products */ = {
+			isa = PBXGroup;
+			children = (
+				97C146EE1CF9000F007C117D /* Runner.app */,
+				C71AE4B6281C6A090086307A /* RunnerTests.xctest */,
+			);
+			name = Products;
+			sourceTree = "<group>";
+		};
+		97C146F01CF9000F007C117D /* Runner */ = {
+			isa = PBXGroup;
+			children = (
+				97C146FA1CF9000F007C117D /* Main.storyboard */,
+				97C146FD1CF9000F007C117D /* Assets.xcassets */,
+				97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */,
+				97C147021CF9000F007C117D /* Info.plist */,
+				1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */,
+				1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */,
+				74858FAE1ED2DC5600515810 /* AppDelegate.swift */,
+				74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */,
+			);
+			path = Runner;
+			sourceTree = "<group>";
+		};
+		C71AE4C4281C6B370086307A /* RunnerTests */ = {
+			isa = PBXGroup;
+			children = (
+				C71AE4C5281C6B530086307A /* FileSelectorTests.m */,
+			);
+			path = RunnerTests;
+			sourceTree = "<group>";
+		};
+		C832A34FD3BC866442874ED0 /* Frameworks */ = {
+			isa = PBXGroup;
+			children = (
+				000792269CB6B9FE88AC567C /* Pods_Runner.framework */,
+				AC3841659BF3693FAC5A2F8F /* Pods_RunnerTests.framework */,
+			);
+			name = Frameworks;
+			sourceTree = "<group>";
+		};
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+		97C146ED1CF9000F007C117D /* Runner */ = {
+			isa = PBXNativeTarget;
+			buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
+			buildPhases = (
+				AC24910767ED5F17F5245292 /* [CP] Check Pods Manifest.lock */,
+				9740EEB61CF901F6004384FC /* Run Script */,
+				97C146EA1CF9000F007C117D /* Sources */,
+				97C146EB1CF9000F007C117D /* Frameworks */,
+				97C146EC1CF9000F007C117D /* Resources */,
+				9705A1C41CF9048500538489 /* Embed Frameworks */,
+				3B06AD1E1E4923F5004D2608 /* Thin Binary */,
+				BE6D85B8F242B768015B938B /* [CP] Embed Pods Frameworks */,
+			);
+			buildRules = (
+			);
+			dependencies = (
+			);
+			name = Runner;
+			productName = Runner;
+			productReference = 97C146EE1CF9000F007C117D /* Runner.app */;
+			productType = "com.apple.product-type.application";
+		};
+		C71AE4B5281C6A090086307A /* RunnerTests */ = {
+			isa = PBXNativeTarget;
+			buildConfigurationList = C71AE4BF281C6A090086307A /* Build configuration list for PBXNativeTarget "RunnerTests" */;
+			buildPhases = (
+				A68B14611B411E4F96A5C80D /* [CP] Check Pods Manifest.lock */,
+				C71AE4B2281C6A090086307A /* Sources */,
+				C71AE4B3281C6A090086307A /* Frameworks */,
+				C71AE4B4281C6A090086307A /* Resources */,
+				5BE5886DAAA885227DE0796D /* [CP] Embed Pods Frameworks */,
+			);
+			buildRules = (
+			);
+			dependencies = (
+				C71AE4BB281C6A090086307A /* PBXTargetDependency */,
+			);
+			name = RunnerTests;
+			productName = FileSelectorTests;
+			productReference = C71AE4B6281C6A090086307A /* RunnerTests.xctest */;
+			productType = "com.apple.product-type.bundle.unit-test";
+		};
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+		97C146E61CF9000F007C117D /* Project object */ = {
+			isa = PBXProject;
+			attributes = {
+				LastUpgradeCheck = 1300;
+				ORGANIZATIONNAME = "";
+				TargetAttributes = {
+					97C146ED1CF9000F007C117D = {
+						CreatedOnToolsVersion = 7.3.1;
+						LastSwiftMigration = 1100;
+					};
+					C71AE4B5281C6A090086307A = {
+						CreatedOnToolsVersion = 13.1;
+						TestTargetID = 97C146ED1CF9000F007C117D;
+					};
+				};
+			};
+			buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */;
+			compatibilityVersion = "Xcode 9.3";
+			developmentRegion = en;
+			hasScannedForEncodings = 0;
+			knownRegions = (
+				en,
+				Base,
+			);
+			mainGroup = 97C146E51CF9000F007C117D;
+			productRefGroup = 97C146EF1CF9000F007C117D /* Products */;
+			projectDirPath = "";
+			projectRoot = "";
+			targets = (
+				97C146ED1CF9000F007C117D /* Runner */,
+				C71AE4B5281C6A090086307A /* RunnerTests */,
+			);
+		};
+/* End PBXProject section */
+
+/* Begin PBXResourcesBuildPhase section */
+		97C146EC1CF9000F007C117D /* Resources */ = {
+			isa = PBXResourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */,
+				3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */,
+				97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */,
+				97C146FC1CF9000F007C117D /* Main.storyboard in Resources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+		C71AE4B4281C6A090086307A /* Resources */ = {
+			isa = PBXResourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXShellScriptBuildPhase section */
+		3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
+			isa = PBXShellScriptBuildPhase;
+			alwaysOutOfDate = 1;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			inputPaths = (
+			);
+			name = "Thin Binary";
+			outputPaths = (
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+			shellPath = /bin/sh;
+			shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin";
+		};
+		5BE5886DAAA885227DE0796D /* [CP] Embed Pods Frameworks */ = {
+			isa = PBXShellScriptBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			inputFileListPaths = (
+				"${PODS_ROOT}/Target Support Files/Pods-RunnerTests/Pods-RunnerTests-frameworks-${CONFIGURATION}-input-files.xcfilelist",
+			);
+			name = "[CP] Embed Pods Frameworks";
+			outputFileListPaths = (
+				"${PODS_ROOT}/Target Support Files/Pods-RunnerTests/Pods-RunnerTests-frameworks-${CONFIGURATION}-output-files.xcfilelist",
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+			shellPath = /bin/sh;
+			shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-RunnerTests/Pods-RunnerTests-frameworks.sh\"\n";
+			showEnvVarsInLog = 0;
+		};
+		9740EEB61CF901F6004384FC /* Run Script */ = {
+			isa = PBXShellScriptBuildPhase;
+			alwaysOutOfDate = 1;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			inputPaths = (
+			);
+			name = "Run Script";
+			outputPaths = (
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+			shellPath = /bin/sh;
+			shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build";
+		};
+		A68B14611B411E4F96A5C80D /* [CP] Check Pods Manifest.lock */ = {
+			isa = PBXShellScriptBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			inputFileListPaths = (
+			);
+			inputPaths = (
+				"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
+				"${PODS_ROOT}/Manifest.lock",
+			);
+			name = "[CP] Check Pods Manifest.lock";
+			outputFileListPaths = (
+			);
+			outputPaths = (
+				"$(DERIVED_FILE_DIR)/Pods-RunnerTests-checkManifestLockResult.txt",
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+			shellPath = /bin/sh;
+			shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n    # print error to STDERR\n    echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n    exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
+			showEnvVarsInLog = 0;
+		};
+		AC24910767ED5F17F5245292 /* [CP] Check Pods Manifest.lock */ = {
+			isa = PBXShellScriptBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			inputFileListPaths = (
+			);
+			inputPaths = (
+				"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
+				"${PODS_ROOT}/Manifest.lock",
+			);
+			name = "[CP] Check Pods Manifest.lock";
+			outputFileListPaths = (
+			);
+			outputPaths = (
+				"$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt",
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+			shellPath = /bin/sh;
+			shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n    # print error to STDERR\n    echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n    exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
+			showEnvVarsInLog = 0;
+		};
+		BE6D85B8F242B768015B938B /* [CP] Embed Pods Frameworks */ = {
+			isa = PBXShellScriptBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			inputFileListPaths = (
+				"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist",
+			);
+			name = "[CP] Embed Pods Frameworks";
+			outputFileListPaths = (
+				"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist",
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+			shellPath = /bin/sh;
+			shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
+			showEnvVarsInLog = 0;
+		};
+/* End PBXShellScriptBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+		97C146EA1CF9000F007C117D /* Sources */ = {
+			isa = PBXSourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */,
+				1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+		C71AE4B2281C6A090086307A /* Sources */ = {
+			isa = PBXSourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				C71AE4C8281C6B6B0086307A /* FileSelectorTests.m in Sources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXSourcesBuildPhase section */
+
+/* Begin PBXTargetDependency section */
+		C71AE4BB281C6A090086307A /* PBXTargetDependency */ = {
+			isa = PBXTargetDependency;
+			target = 97C146ED1CF9000F007C117D /* Runner */;
+			targetProxy = C71AE4BA281C6A090086307A /* PBXContainerItemProxy */;
+		};
+/* End PBXTargetDependency section */
+
+/* Begin PBXVariantGroup section */
+		97C146FA1CF9000F007C117D /* Main.storyboard */ = {
+			isa = PBXVariantGroup;
+			children = (
+				97C146FB1CF9000F007C117D /* Base */,
+			);
+			name = Main.storyboard;
+			sourceTree = "<group>";
+		};
+		97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = {
+			isa = PBXVariantGroup;
+			children = (
+				97C147001CF9000F007C117D /* Base */,
+			);
+			name = LaunchScreen.storyboard;
+			sourceTree = "<group>";
+		};
+/* End PBXVariantGroup section */
+
+/* Begin XCBuildConfiguration section */
+		249021D3217E4FDB00AE95B9 /* Profile */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ALWAYS_SEARCH_USER_PATHS = NO;
+				CLANG_ANALYZER_NONNULL = YES;
+				CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+				CLANG_CXX_LIBRARY = "libc++";
+				CLANG_ENABLE_MODULES = YES;
+				CLANG_ENABLE_OBJC_ARC = YES;
+				CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+				CLANG_WARN_BOOL_CONVERSION = YES;
+				CLANG_WARN_COMMA = YES;
+				CLANG_WARN_CONSTANT_CONVERSION = YES;
+				CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+				CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+				CLANG_WARN_EMPTY_BODY = YES;
+				CLANG_WARN_ENUM_CONVERSION = YES;
+				CLANG_WARN_INFINITE_RECURSION = YES;
+				CLANG_WARN_INT_CONVERSION = YES;
+				CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+				CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+				CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+				CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+				CLANG_WARN_STRICT_PROTOTYPES = YES;
+				CLANG_WARN_SUSPICIOUS_MOVE = YES;
+				CLANG_WARN_UNREACHABLE_CODE = YES;
+				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+				"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+				COPY_PHASE_STRIP = NO;
+				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+				ENABLE_NS_ASSERTIONS = NO;
+				ENABLE_STRICT_OBJC_MSGSEND = YES;
+				GCC_C_LANGUAGE_STANDARD = gnu99;
+				GCC_NO_COMMON_BLOCKS = YES;
+				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+				GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+				GCC_WARN_UNDECLARED_SELECTOR = YES;
+				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+				GCC_WARN_UNUSED_FUNCTION = YES;
+				GCC_WARN_UNUSED_VARIABLE = YES;
+				IPHONEOS_DEPLOYMENT_TARGET = 11.0;
+				MTL_ENABLE_DEBUG_INFO = NO;
+				SDKROOT = iphoneos;
+				SUPPORTED_PLATFORMS = iphoneos;
+				TARGETED_DEVICE_FAMILY = "1,2";
+				VALIDATE_PRODUCT = YES;
+			};
+			name = Profile;
+		};
+		249021D4217E4FDB00AE95B9 /* Profile */ = {
+			isa = XCBuildConfiguration;
+			baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
+			buildSettings = {
+				ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+				CLANG_ENABLE_MODULES = YES;
+				CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
+				ENABLE_BITCODE = NO;
+				INFOPLIST_FILE = Runner/Info.plist;
+				LD_RUNPATH_SEARCH_PATHS = (
+					"$(inherited)",
+					"@executable_path/Frameworks",
+				);
+				PRODUCT_BUNDLE_IDENTIFIER = com.example.fileSelectorIosExample;
+				PRODUCT_NAME = "$(TARGET_NAME)";
+				SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
+				SWIFT_VERSION = 5.0;
+				VERSIONING_SYSTEM = "apple-generic";
+			};
+			name = Profile;
+		};
+		97C147031CF9000F007C117D /* Debug */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ALWAYS_SEARCH_USER_PATHS = NO;
+				CLANG_ANALYZER_NONNULL = YES;
+				CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+				CLANG_CXX_LIBRARY = "libc++";
+				CLANG_ENABLE_MODULES = YES;
+				CLANG_ENABLE_OBJC_ARC = YES;
+				CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+				CLANG_WARN_BOOL_CONVERSION = YES;
+				CLANG_WARN_COMMA = YES;
+				CLANG_WARN_CONSTANT_CONVERSION = YES;
+				CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+				CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+				CLANG_WARN_EMPTY_BODY = YES;
+				CLANG_WARN_ENUM_CONVERSION = YES;
+				CLANG_WARN_INFINITE_RECURSION = YES;
+				CLANG_WARN_INT_CONVERSION = YES;
+				CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+				CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+				CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+				CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+				CLANG_WARN_STRICT_PROTOTYPES = YES;
+				CLANG_WARN_SUSPICIOUS_MOVE = YES;
+				CLANG_WARN_UNREACHABLE_CODE = YES;
+				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+				"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+				COPY_PHASE_STRIP = NO;
+				DEBUG_INFORMATION_FORMAT = dwarf;
+				ENABLE_STRICT_OBJC_MSGSEND = YES;
+				ENABLE_TESTABILITY = YES;
+				GCC_C_LANGUAGE_STANDARD = gnu99;
+				GCC_DYNAMIC_NO_PIC = NO;
+				GCC_NO_COMMON_BLOCKS = YES;
+				GCC_OPTIMIZATION_LEVEL = 0;
+				GCC_PREPROCESSOR_DEFINITIONS = (
+					"DEBUG=1",
+					"$(inherited)",
+				);
+				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+				GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+				GCC_WARN_UNDECLARED_SELECTOR = YES;
+				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+				GCC_WARN_UNUSED_FUNCTION = YES;
+				GCC_WARN_UNUSED_VARIABLE = YES;
+				IPHONEOS_DEPLOYMENT_TARGET = 11.0;
+				MTL_ENABLE_DEBUG_INFO = YES;
+				ONLY_ACTIVE_ARCH = YES;
+				SDKROOT = iphoneos;
+				TARGETED_DEVICE_FAMILY = "1,2";
+			};
+			name = Debug;
+		};
+		97C147041CF9000F007C117D /* Release */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ALWAYS_SEARCH_USER_PATHS = NO;
+				CLANG_ANALYZER_NONNULL = YES;
+				CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+				CLANG_CXX_LIBRARY = "libc++";
+				CLANG_ENABLE_MODULES = YES;
+				CLANG_ENABLE_OBJC_ARC = YES;
+				CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+				CLANG_WARN_BOOL_CONVERSION = YES;
+				CLANG_WARN_COMMA = YES;
+				CLANG_WARN_CONSTANT_CONVERSION = YES;
+				CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+				CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+				CLANG_WARN_EMPTY_BODY = YES;
+				CLANG_WARN_ENUM_CONVERSION = YES;
+				CLANG_WARN_INFINITE_RECURSION = YES;
+				CLANG_WARN_INT_CONVERSION = YES;
+				CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+				CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+				CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+				CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+				CLANG_WARN_STRICT_PROTOTYPES = YES;
+				CLANG_WARN_SUSPICIOUS_MOVE = YES;
+				CLANG_WARN_UNREACHABLE_CODE = YES;
+				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+				"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+				COPY_PHASE_STRIP = NO;
+				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+				ENABLE_NS_ASSERTIONS = NO;
+				ENABLE_STRICT_OBJC_MSGSEND = YES;
+				GCC_C_LANGUAGE_STANDARD = gnu99;
+				GCC_NO_COMMON_BLOCKS = YES;
+				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+				GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+				GCC_WARN_UNDECLARED_SELECTOR = YES;
+				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+				GCC_WARN_UNUSED_FUNCTION = YES;
+				GCC_WARN_UNUSED_VARIABLE = YES;
+				IPHONEOS_DEPLOYMENT_TARGET = 11.0;
+				MTL_ENABLE_DEBUG_INFO = NO;
+				SDKROOT = iphoneos;
+				SUPPORTED_PLATFORMS = iphoneos;
+				SWIFT_COMPILATION_MODE = wholemodule;
+				SWIFT_OPTIMIZATION_LEVEL = "-O";
+				TARGETED_DEVICE_FAMILY = "1,2";
+				VALIDATE_PRODUCT = YES;
+			};
+			name = Release;
+		};
+		97C147061CF9000F007C117D /* Debug */ = {
+			isa = XCBuildConfiguration;
+			baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
+			buildSettings = {
+				ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+				CLANG_ENABLE_MODULES = YES;
+				CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
+				ENABLE_BITCODE = NO;
+				INFOPLIST_FILE = Runner/Info.plist;
+				LD_RUNPATH_SEARCH_PATHS = (
+					"$(inherited)",
+					"@executable_path/Frameworks",
+				);
+				PRODUCT_BUNDLE_IDENTIFIER = com.example.fileSelectorIosExample;
+				PRODUCT_NAME = "$(TARGET_NAME)";
+				SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
+				SWIFT_OPTIMIZATION_LEVEL = "-Onone";
+				SWIFT_VERSION = 5.0;
+				VERSIONING_SYSTEM = "apple-generic";
+			};
+			name = Debug;
+		};
+		97C147071CF9000F007C117D /* Release */ = {
+			isa = XCBuildConfiguration;
+			baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
+			buildSettings = {
+				ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+				CLANG_ENABLE_MODULES = YES;
+				CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
+				ENABLE_BITCODE = NO;
+				INFOPLIST_FILE = Runner/Info.plist;
+				LD_RUNPATH_SEARCH_PATHS = (
+					"$(inherited)",
+					"@executable_path/Frameworks",
+				);
+				PRODUCT_BUNDLE_IDENTIFIER = com.example.fileSelectorIosExample;
+				PRODUCT_NAME = "$(TARGET_NAME)";
+				SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
+				SWIFT_VERSION = 5.0;
+				VERSIONING_SYSTEM = "apple-generic";
+			};
+			name = Release;
+		};
+		C71AE4BC281C6A090086307A /* Debug */ = {
+			isa = XCBuildConfiguration;
+			baseConfigurationReference = 4A27CC0DB4EF6669B637A1E8 /* Pods-RunnerTests.debug.xcconfig */;
+			buildSettings = {
+				BUNDLE_LOADER = "$(TEST_HOST)";
+				CODE_SIGN_STYLE = Automatic;
+				CURRENT_PROJECT_VERSION = 1;
+				GENERATE_INFOPLIST_FILE = YES;
+				LD_RUNPATH_SEARCH_PATHS = (
+					"$(inherited)",
+					"@executable_path/Frameworks",
+					"@loader_path/Frameworks",
+				);
+				MARKETING_VERSION = 1.0;
+				PRODUCT_BUNDLE_IDENTIFIER = dev.flutter.plugins.FileSelectorTests;
+				PRODUCT_NAME = "$(TARGET_NAME)";
+				TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/Runner";
+			};
+			name = Debug;
+		};
+		C71AE4BD281C6A090086307A /* Release */ = {
+			isa = XCBuildConfiguration;
+			baseConfigurationReference = 5667547C6832727A744371E2 /* Pods-RunnerTests.release.xcconfig */;
+			buildSettings = {
+				ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
+				BUNDLE_LOADER = "$(TEST_HOST)";
+				CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+				CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
+				CLANG_ENABLE_OBJC_WEAK = YES;
+				CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+				CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
+				CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
+				CODE_SIGN_STYLE = Automatic;
+				CURRENT_PROJECT_VERSION = 1;
+				GCC_C_LANGUAGE_STANDARD = gnu11;
+				GENERATE_INFOPLIST_FILE = YES;
+				IPHONEOS_DEPLOYMENT_TARGET = 15.0;
+				LD_RUNPATH_SEARCH_PATHS = (
+					"$(inherited)",
+					"@executable_path/Frameworks",
+					"@loader_path/Frameworks",
+				);
+				MARKETING_VERSION = 1.0;
+				MTL_FAST_MATH = YES;
+				PRODUCT_BUNDLE_IDENTIFIER = dev.flutter.plugins.FileSelectorTests;
+				PRODUCT_NAME = "$(TARGET_NAME)";
+				SWIFT_EMIT_LOC_STRINGS = NO;
+				TARGETED_DEVICE_FAMILY = "1,2";
+				TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/Runner";
+			};
+			name = Release;
+		};
+		C71AE4BE281C6A090086307A /* Profile */ = {
+			isa = XCBuildConfiguration;
+			baseConfigurationReference = 786CCB880423FD6D1019F59B /* Pods-RunnerTests.profile.xcconfig */;
+			buildSettings = {
+				ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
+				BUNDLE_LOADER = "$(TEST_HOST)";
+				CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+				CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
+				CLANG_ENABLE_OBJC_WEAK = YES;
+				CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+				CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
+				CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
+				CODE_SIGN_STYLE = Automatic;
+				CURRENT_PROJECT_VERSION = 1;
+				GCC_C_LANGUAGE_STANDARD = gnu11;
+				GENERATE_INFOPLIST_FILE = YES;
+				IPHONEOS_DEPLOYMENT_TARGET = 15.0;
+				LD_RUNPATH_SEARCH_PATHS = (
+					"$(inherited)",
+					"@executable_path/Frameworks",
+					"@loader_path/Frameworks",
+				);
+				MARKETING_VERSION = 1.0;
+				MTL_FAST_MATH = YES;
+				PRODUCT_BUNDLE_IDENTIFIER = dev.flutter.plugins.FileSelectorTests;
+				PRODUCT_NAME = "$(TARGET_NAME)";
+				SWIFT_EMIT_LOC_STRINGS = NO;
+				TARGETED_DEVICE_FAMILY = "1,2";
+				TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/Runner";
+			};
+			name = Profile;
+		};
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+		97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				97C147031CF9000F007C117D /* Debug */,
+				97C147041CF9000F007C117D /* Release */,
+				249021D3217E4FDB00AE95B9 /* Profile */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
+		};
+		97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				97C147061CF9000F007C117D /* Debug */,
+				97C147071CF9000F007C117D /* Release */,
+				249021D4217E4FDB00AE95B9 /* Profile */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
+		};
+		C71AE4BF281C6A090086307A /* Build configuration list for PBXNativeTarget "RunnerTests" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				C71AE4BC281C6A090086307A /* Debug */,
+				C71AE4BD281C6A090086307A /* Release */,
+				C71AE4BE281C6A090086307A /* Profile */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
+		};
+/* End XCConfigurationList section */
+	};
+	rootObject = 97C146E61CF9000F007C117D /* Project object */;
+}
diff --git a/packages/file_selector/file_selector_ios/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/packages/file_selector/file_selector_ios/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 0000000..919434a
--- /dev/null
+++ b/packages/file_selector/file_selector_ios/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Workspace
+   version = "1.0">
+   <FileRef
+      location = "self:">
+   </FileRef>
+</Workspace>
diff --git a/packages/file_selector/file_selector_ios/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/packages/file_selector/file_selector_ios/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
new file mode 100644
index 0000000..18d9810
--- /dev/null
+++ b/packages/file_selector/file_selector_ios/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>IDEDidComputeMac32BitWarning</key>
+	<true/>
+</dict>
+</plist>
diff --git a/packages/file_selector/file_selector_ios/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/packages/file_selector/file_selector_ios/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings
new file mode 100644
index 0000000..f9b0d7c
--- /dev/null
+++ b/packages/file_selector/file_selector_ios/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>PreviewsEnabled</key>
+	<false/>
+</dict>
+</plist>
diff --git a/packages/file_selector/file_selector_ios/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/packages/file_selector/file_selector_ios/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme
new file mode 100644
index 0000000..c842c6b
--- /dev/null
+++ b/packages/file_selector/file_selector_ios/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme
@@ -0,0 +1,97 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Scheme
+   LastUpgradeVersion = "1300"
+   version = "1.3">
+   <BuildAction
+      parallelizeBuildables = "YES"
+      buildImplicitDependencies = "YES">
+      <BuildActionEntries>
+         <BuildActionEntry
+            buildForTesting = "YES"
+            buildForRunning = "YES"
+            buildForProfiling = "YES"
+            buildForArchiving = "YES"
+            buildForAnalyzing = "YES">
+            <BuildableReference
+               BuildableIdentifier = "primary"
+               BlueprintIdentifier = "97C146ED1CF9000F007C117D"
+               BuildableName = "Runner.app"
+               BlueprintName = "Runner"
+               ReferencedContainer = "container:Runner.xcodeproj">
+            </BuildableReference>
+         </BuildActionEntry>
+      </BuildActionEntries>
+   </BuildAction>
+   <TestAction
+      buildConfiguration = "Debug"
+      selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
+      selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
+      shouldUseLaunchSchemeArgsEnv = "YES">
+      <MacroExpansion>
+         <BuildableReference
+            BuildableIdentifier = "primary"
+            BlueprintIdentifier = "97C146ED1CF9000F007C117D"
+            BuildableName = "Runner.app"
+            BlueprintName = "Runner"
+            ReferencedContainer = "container:Runner.xcodeproj">
+         </BuildableReference>
+      </MacroExpansion>
+      <Testables>
+         <TestableReference
+            skipped = "NO">
+            <BuildableReference
+               BuildableIdentifier = "primary"
+               BlueprintIdentifier = "C71AE4B5281C6A090086307A"
+               BuildableName = "RunnerTests.xctest"
+               BlueprintName = "RunnerTests"
+               ReferencedContainer = "container:Runner.xcodeproj">
+            </BuildableReference>
+         </TestableReference>
+      </Testables>
+   </TestAction>
+   <LaunchAction
+      buildConfiguration = "Debug"
+      selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
+      selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
+      launchStyle = "0"
+      useCustomWorkingDirectory = "NO"
+      ignoresPersistentStateOnLaunch = "NO"
+      debugDocumentVersioning = "YES"
+      debugServiceExtension = "internal"
+      allowLocationSimulation = "YES">
+      <BuildableProductRunnable
+         runnableDebuggingMode = "0">
+         <BuildableReference
+            BuildableIdentifier = "primary"
+            BlueprintIdentifier = "97C146ED1CF9000F007C117D"
+            BuildableName = "Runner.app"
+            BlueprintName = "Runner"
+            ReferencedContainer = "container:Runner.xcodeproj">
+         </BuildableReference>
+      </BuildableProductRunnable>
+   </LaunchAction>
+   <ProfileAction
+      buildConfiguration = "Profile"
+      shouldUseLaunchSchemeArgsEnv = "YES"
+      savedToolIdentifier = ""
+      useCustomWorkingDirectory = "NO"
+      debugDocumentVersioning = "YES">
+      <BuildableProductRunnable
+         runnableDebuggingMode = "0">
+         <BuildableReference
+            BuildableIdentifier = "primary"
+            BlueprintIdentifier = "97C146ED1CF9000F007C117D"
+            BuildableName = "Runner.app"
+            BlueprintName = "Runner"
+            ReferencedContainer = "container:Runner.xcodeproj">
+         </BuildableReference>
+      </BuildableProductRunnable>
+   </ProfileAction>
+   <AnalyzeAction
+      buildConfiguration = "Debug">
+   </AnalyzeAction>
+   <ArchiveAction
+      buildConfiguration = "Release"
+      revealArchiveInOrganizer = "YES">
+   </ArchiveAction>
+</Scheme>
diff --git a/packages/file_selector/file_selector_ios/example/ios/Runner.xcworkspace/contents.xcworkspacedata b/packages/file_selector/file_selector_ios/example/ios/Runner.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 0000000..21a3cc1
--- /dev/null
+++ b/packages/file_selector/file_selector_ios/example/ios/Runner.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Workspace
+   version = "1.0">
+   <FileRef
+      location = "group:Runner.xcodeproj">
+   </FileRef>
+   <FileRef
+      location = "group:Pods/Pods.xcodeproj">
+   </FileRef>
+</Workspace>
diff --git a/packages/file_selector/file_selector_ios/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/packages/file_selector/file_selector_ios/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
new file mode 100644
index 0000000..18d9810
--- /dev/null
+++ b/packages/file_selector/file_selector_ios/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>IDEDidComputeMac32BitWarning</key>
+	<true/>
+</dict>
+</plist>
diff --git a/packages/file_selector/file_selector_ios/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/packages/file_selector/file_selector_ios/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings
new file mode 100644
index 0000000..f9b0d7c
--- /dev/null
+++ b/packages/file_selector/file_selector_ios/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>PreviewsEnabled</key>
+	<false/>
+</dict>
+</plist>
diff --git a/packages/file_selector/file_selector_ios/example/ios/Runner/AppDelegate.swift b/packages/file_selector/file_selector_ios/example/ios/Runner/AppDelegate.swift
new file mode 100644
index 0000000..caf9983
--- /dev/null
+++ b/packages/file_selector/file_selector_ios/example/ios/Runner/AppDelegate.swift
@@ -0,0 +1,17 @@
+// 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 UIKit
+import Flutter
+
+@UIApplicationMain
+@objc class AppDelegate: FlutterAppDelegate {
+  override func application(
+    _ application: UIApplication,
+    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
+  ) -> Bool {
+    GeneratedPluginRegistrant.register(with: self)
+    return super.application(application, didFinishLaunchingWithOptions: launchOptions)
+  }
+}
diff --git a/packages/file_selector/file_selector_ios/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/packages/file_selector/file_selector_ios/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json
new file mode 100644
index 0000000..d36b1fa
--- /dev/null
+++ b/packages/file_selector/file_selector_ios/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json
@@ -0,0 +1,122 @@
+{
+  "images" : [
+    {
+      "size" : "20x20",
+      "idiom" : "iphone",
+      "filename" : "Icon-App-20x20@2x.png",
+      "scale" : "2x"
+    },
+    {
+      "size" : "20x20",
+      "idiom" : "iphone",
+      "filename" : "Icon-App-20x20@3x.png",
+      "scale" : "3x"
+    },
+    {
+      "size" : "29x29",
+      "idiom" : "iphone",
+      "filename" : "Icon-App-29x29@1x.png",
+      "scale" : "1x"
+    },
+    {
+      "size" : "29x29",
+      "idiom" : "iphone",
+      "filename" : "Icon-App-29x29@2x.png",
+      "scale" : "2x"
+    },
+    {
+      "size" : "29x29",
+      "idiom" : "iphone",
+      "filename" : "Icon-App-29x29@3x.png",
+      "scale" : "3x"
+    },
+    {
+      "size" : "40x40",
+      "idiom" : "iphone",
+      "filename" : "Icon-App-40x40@2x.png",
+      "scale" : "2x"
+    },
+    {
+      "size" : "40x40",
+      "idiom" : "iphone",
+      "filename" : "Icon-App-40x40@3x.png",
+      "scale" : "3x"
+    },
+    {
+      "size" : "60x60",
+      "idiom" : "iphone",
+      "filename" : "Icon-App-60x60@2x.png",
+      "scale" : "2x"
+    },
+    {
+      "size" : "60x60",
+      "idiom" : "iphone",
+      "filename" : "Icon-App-60x60@3x.png",
+      "scale" : "3x"
+    },
+    {
+      "size" : "20x20",
+      "idiom" : "ipad",
+      "filename" : "Icon-App-20x20@1x.png",
+      "scale" : "1x"
+    },
+    {
+      "size" : "20x20",
+      "idiom" : "ipad",
+      "filename" : "Icon-App-20x20@2x.png",
+      "scale" : "2x"
+    },
+    {
+      "size" : "29x29",
+      "idiom" : "ipad",
+      "filename" : "Icon-App-29x29@1x.png",
+      "scale" : "1x"
+    },
+    {
+      "size" : "29x29",
+      "idiom" : "ipad",
+      "filename" : "Icon-App-29x29@2x.png",
+      "scale" : "2x"
+    },
+    {
+      "size" : "40x40",
+      "idiom" : "ipad",
+      "filename" : "Icon-App-40x40@1x.png",
+      "scale" : "1x"
+    },
+    {
+      "size" : "40x40",
+      "idiom" : "ipad",
+      "filename" : "Icon-App-40x40@2x.png",
+      "scale" : "2x"
+    },
+    {
+      "size" : "76x76",
+      "idiom" : "ipad",
+      "filename" : "Icon-App-76x76@1x.png",
+      "scale" : "1x"
+    },
+    {
+      "size" : "76x76",
+      "idiom" : "ipad",
+      "filename" : "Icon-App-76x76@2x.png",
+      "scale" : "2x"
+    },
+    {
+      "size" : "83.5x83.5",
+      "idiom" : "ipad",
+      "filename" : "Icon-App-83.5x83.5@2x.png",
+      "scale" : "2x"
+    },
+    {
+      "size" : "1024x1024",
+      "idiom" : "ios-marketing",
+      "filename" : "Icon-App-1024x1024@1x.png",
+      "scale" : "1x"
+    }
+  ],
+  "info" : {
+    "version" : 1,
+    "author" : "xcode"
+  }
+}
diff --git a/packages/file_selector/file_selector_ios/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png b/packages/file_selector/file_selector_ios/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png
new file mode 100644
index 0000000..dc9ada4
--- /dev/null
+++ b/packages/file_selector/file_selector_ios/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png
Binary files differ
diff --git a/packages/file_selector/file_selector_ios/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/packages/file_selector/file_selector_ios/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png
new file mode 100644
index 0000000..28c6bf0
--- /dev/null
+++ b/packages/file_selector/file_selector_ios/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png
Binary files differ
diff --git a/packages/file_selector/file_selector_ios/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png b/packages/file_selector/file_selector_ios/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png
new file mode 100644
index 0000000..2ccbfd9
--- /dev/null
+++ b/packages/file_selector/file_selector_ios/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png
Binary files differ
diff --git a/packages/file_selector/file_selector_ios/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/packages/file_selector/file_selector_ios/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png
new file mode 100644
index 0000000..f091b6b
--- /dev/null
+++ b/packages/file_selector/file_selector_ios/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png
Binary files differ
diff --git a/packages/file_selector/file_selector_ios/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png b/packages/file_selector/file_selector_ios/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png
new file mode 100644
index 0000000..4cde121
--- /dev/null
+++ b/packages/file_selector/file_selector_ios/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png
Binary files differ
diff --git a/packages/file_selector/file_selector_ios/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/packages/file_selector/file_selector_ios/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png
new file mode 100644
index 0000000..d0ef06e
--- /dev/null
+++ b/packages/file_selector/file_selector_ios/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png
Binary files differ
diff --git a/packages/file_selector/file_selector_ios/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png b/packages/file_selector/file_selector_ios/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png
new file mode 100644
index 0000000..dcdc230
--- /dev/null
+++ b/packages/file_selector/file_selector_ios/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png
Binary files differ
diff --git a/packages/file_selector/file_selector_ios/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png b/packages/file_selector/file_selector_ios/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png
new file mode 100644
index 0000000..2ccbfd9
--- /dev/null
+++ b/packages/file_selector/file_selector_ios/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png
Binary files differ
diff --git a/packages/file_selector/file_selector_ios/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/packages/file_selector/file_selector_ios/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png
new file mode 100644
index 0000000..c8f9ed8
--- /dev/null
+++ b/packages/file_selector/file_selector_ios/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png
Binary files differ
diff --git a/packages/file_selector/file_selector_ios/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/packages/file_selector/file_selector_ios/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png
new file mode 100644
index 0000000..a6d6b86
--- /dev/null
+++ b/packages/file_selector/file_selector_ios/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png
Binary files differ
diff --git a/packages/file_selector/file_selector_ios/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/packages/file_selector/file_selector_ios/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png
new file mode 100644
index 0000000..a6d6b86
--- /dev/null
+++ b/packages/file_selector/file_selector_ios/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png
Binary files differ
diff --git a/packages/file_selector/file_selector_ios/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/packages/file_selector/file_selector_ios/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png
new file mode 100644
index 0000000..75b2d16
--- /dev/null
+++ b/packages/file_selector/file_selector_ios/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png
Binary files differ
diff --git a/packages/file_selector/file_selector_ios/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/packages/file_selector/file_selector_ios/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png
new file mode 100644
index 0000000..c4df70d
--- /dev/null
+++ b/packages/file_selector/file_selector_ios/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png
Binary files differ
diff --git a/packages/file_selector/file_selector_ios/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png b/packages/file_selector/file_selector_ios/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png
new file mode 100644
index 0000000..6a84f41
--- /dev/null
+++ b/packages/file_selector/file_selector_ios/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png
Binary files differ
diff --git a/packages/file_selector/file_selector_ios/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png b/packages/file_selector/file_selector_ios/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png
new file mode 100644
index 0000000..d0e1f58
--- /dev/null
+++ b/packages/file_selector/file_selector_ios/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png
Binary files differ
diff --git a/packages/file_selector/file_selector_ios/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json b/packages/file_selector/file_selector_ios/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json
new file mode 100644
index 0000000..0bedcf2
--- /dev/null
+++ b/packages/file_selector/file_selector_ios/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json
@@ -0,0 +1,23 @@
+{
+  "images" : [
+    {
+      "idiom" : "universal",
+      "filename" : "LaunchImage.png",
+      "scale" : "1x"
+    },
+    {
+      "idiom" : "universal",
+      "filename" : "LaunchImage@2x.png",
+      "scale" : "2x"
+    },
+    {
+      "idiom" : "universal",
+      "filename" : "LaunchImage@3x.png",
+      "scale" : "3x"
+    }
+  ],
+  "info" : {
+    "version" : 1,
+    "author" : "xcode"
+  }
+}
diff --git a/packages/file_selector/file_selector_ios/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png b/packages/file_selector/file_selector_ios/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png
new file mode 100644
index 0000000..9da19ea
--- /dev/null
+++ b/packages/file_selector/file_selector_ios/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png
Binary files differ
diff --git a/packages/file_selector/file_selector_ios/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png b/packages/file_selector/file_selector_ios/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png
new file mode 100644
index 0000000..9da19ea
--- /dev/null
+++ b/packages/file_selector/file_selector_ios/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png
Binary files differ
diff --git a/packages/file_selector/file_selector_ios/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png b/packages/file_selector/file_selector_ios/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png
new file mode 100644
index 0000000..9da19ea
--- /dev/null
+++ b/packages/file_selector/file_selector_ios/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png
Binary files differ
diff --git a/packages/file_selector/file_selector_ios/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md b/packages/file_selector/file_selector_ios/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md
new file mode 100644
index 0000000..89c2725
--- /dev/null
+++ b/packages/file_selector/file_selector_ios/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md
@@ -0,0 +1,5 @@
+# Launch Screen Assets
+
+You can customize the launch screen with your own desired assets by replacing the image files in this directory.
+
+You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images.
\ No newline at end of file
diff --git a/packages/file_selector/file_selector_ios/example/ios/Runner/Base.lproj/LaunchScreen.storyboard b/packages/file_selector/file_selector_ios/example/ios/Runner/Base.lproj/LaunchScreen.storyboard
new file mode 100644
index 0000000..f2e259c
--- /dev/null
+++ b/packages/file_selector/file_selector_ios/example/ios/Runner/Base.lproj/LaunchScreen.storyboard
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="12121" systemVersion="16G29" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
+    <dependencies>
+        <deployment identifier="iOS"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12089"/>
+    </dependencies>
+    <scenes>
+        <!--View Controller-->
+        <scene sceneID="EHf-IW-A2E">
+            <objects>
+                <viewController id="01J-lp-oVM" sceneMemberID="viewController">
+                    <layoutGuides>
+                        <viewControllerLayoutGuide type="top" id="Ydg-fD-yQy"/>
+                        <viewControllerLayoutGuide type="bottom" id="xbc-2k-c8Z"/>
+                    </layoutGuides>
+                    <view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
+                        <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+                        <subviews>
+                            <imageView opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" image="LaunchImage" translatesAutoresizingMaskIntoConstraints="NO" id="YRO-k0-Ey4">
+                            </imageView>
+                        </subviews>
+                        <color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                        <constraints>
+                            <constraint firstItem="YRO-k0-Ey4" firstAttribute="centerX" secondItem="Ze5-6b-2t3" secondAttribute="centerX" id="1a2-6s-vTC"/>
+                            <constraint firstItem="YRO-k0-Ey4" firstAttribute="centerY" secondItem="Ze5-6b-2t3" secondAttribute="centerY" id="4X2-HB-R7a"/>
+                        </constraints>
+                    </view>
+                </viewController>
+                <placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
+            </objects>
+            <point key="canvasLocation" x="53" y="375"/>
+        </scene>
+    </scenes>
+    <resources>
+        <image name="LaunchImage" width="168" height="185"/>
+    </resources>
+</document>
diff --git a/packages/file_selector/file_selector_ios/example/ios/Runner/Base.lproj/Main.storyboard b/packages/file_selector/file_selector_ios/example/ios/Runner/Base.lproj/Main.storyboard
new file mode 100644
index 0000000..f3c2851
--- /dev/null
+++ b/packages/file_selector/file_selector_ios/example/ios/Runner/Base.lproj/Main.storyboard
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="10117" systemVersion="15F34" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="BYZ-38-t0r">
+    <dependencies>
+        <deployment identifier="iOS"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="10085"/>
+    </dependencies>
+    <scenes>
+        <!--Flutter View Controller-->
+        <scene sceneID="tne-QT-ifu">
+            <objects>
+                <viewController id="BYZ-38-t0r" customClass="FlutterViewController" sceneMemberID="viewController">
+                    <layoutGuides>
+                        <viewControllerLayoutGuide type="top" id="y3c-jy-aDJ"/>
+                        <viewControllerLayoutGuide type="bottom" id="wfy-db-euE"/>
+                    </layoutGuides>
+                    <view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
+                        <rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
+                        <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+                        <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
+                    </view>
+                </viewController>
+                <placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
+            </objects>
+        </scene>
+    </scenes>
+</document>
diff --git a/packages/file_selector/file_selector_ios/example/ios/Runner/Info.plist b/packages/file_selector/file_selector_ios/example/ios/Runner/Info.plist
new file mode 100644
index 0000000..2bf6e92
--- /dev/null
+++ b/packages/file_selector/file_selector_ios/example/ios/Runner/Info.plist
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>CFBundleDevelopmentRegion</key>
+	<string>$(DEVELOPMENT_LANGUAGE)</string>
+	<key>CFBundleDisplayName</key>
+	<string>File Selector Ios</string>
+	<key>CFBundleExecutable</key>
+	<string>$(EXECUTABLE_NAME)</string>
+	<key>CFBundleIdentifier</key>
+	<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
+	<key>CFBundleInfoDictionaryVersion</key>
+	<string>6.0</string>
+	<key>CFBundleName</key>
+	<string>file_selector_ios_example</string>
+	<key>CFBundlePackageType</key>
+	<string>APPL</string>
+	<key>CFBundleShortVersionString</key>
+	<string>$(FLUTTER_BUILD_NAME)</string>
+	<key>CFBundleSignature</key>
+	<string>????</string>
+	<key>CFBundleVersion</key>
+	<string>$(FLUTTER_BUILD_NUMBER)</string>
+	<key>LSRequiresIPhoneOS</key>
+	<true/>
+	<key>UILaunchStoryboardName</key>
+	<string>LaunchScreen</string>
+	<key>UIMainStoryboardFile</key>
+	<string>Main</string>
+	<key>UISupportedInterfaceOrientations</key>
+	<array>
+		<string>UIInterfaceOrientationPortrait</string>
+		<string>UIInterfaceOrientationLandscapeLeft</string>
+		<string>UIInterfaceOrientationLandscapeRight</string>
+	</array>
+	<key>UISupportedInterfaceOrientations~ipad</key>
+	<array>
+		<string>UIInterfaceOrientationPortrait</string>
+		<string>UIInterfaceOrientationPortraitUpsideDown</string>
+		<string>UIInterfaceOrientationLandscapeLeft</string>
+		<string>UIInterfaceOrientationLandscapeRight</string>
+	</array>
+	<key>UIViewControllerBasedStatusBarAppearance</key>
+	<false/>
+	<key>CADisableMinimumFrameDurationOnPhone</key>
+	<true/>
+	<key>UIApplicationSupportsIndirectInputEvents</key>
+	<true/>
+</dict>
+</plist>
diff --git a/packages/file_selector/file_selector_ios/example/ios/Runner/Runner-Bridging-Header.h b/packages/file_selector/file_selector_ios/example/ios/Runner/Runner-Bridging-Header.h
new file mode 100644
index 0000000..eb7e8ba
--- /dev/null
+++ b/packages/file_selector/file_selector_ios/example/ios/Runner/Runner-Bridging-Header.h
@@ -0,0 +1,5 @@
+// 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 "GeneratedPluginRegistrant.h"
diff --git a/packages/file_selector/file_selector_ios/example/ios/RunnerTests/FileSelectorTests.m b/packages/file_selector/file_selector_ios/example/ios/RunnerTests/FileSelectorTests.m
new file mode 100644
index 0000000..a32622a
--- /dev/null
+++ b/packages/file_selector/file_selector_ios/example/ios/RunnerTests/FileSelectorTests.m
@@ -0,0 +1,98 @@
+// 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 file_selector_ios;
+@import file_selector_ios.Test;
+@import XCTest;
+
+#import <OCMock/OCMock.h>
+
+@interface FileSelectorTests : XCTestCase
+
+@end
+
+@implementation FileSelectorTests
+
+- (void)testPickerPresents {
+  FFSFileSelectorPlugin *plugin = [[FFSFileSelectorPlugin alloc] init];
+  UIDocumentPickerViewController *picker =
+      [[UIDocumentPickerViewController alloc] initWithDocumentTypes:@[]
+                                                             inMode:UIDocumentPickerModeImport];
+  id mockPresentingVC = OCMClassMock([UIViewController class]);
+  plugin.documentPickerViewControllerOverride = picker;
+  plugin.presentingViewControllerOverride = mockPresentingVC;
+
+  [plugin openFileSelectorWithConfig:[FFSFileSelectorConfig makeWithUtis:@[]
+                                                     allowMultiSelection:@NO]
+                          completion:^(NSArray<NSString *> *paths, FlutterError *error){
+                          }];
+
+  XCTAssertEqualObjects(picker.delegate, plugin);
+  OCMVerify(times(1), [mockPresentingVC presentViewController:picker
+                                                     animated:[OCMArg any]
+                                                   completion:[OCMArg any]]);
+}
+
+- (void)testReturnsPickedFiles {
+  FFSFileSelectorPlugin *plugin = [[FFSFileSelectorPlugin alloc] init];
+  XCTestExpectation *completionWasCalled = [self expectationWithDescription:@"completion"];
+  UIDocumentPickerViewController *picker =
+      [[UIDocumentPickerViewController alloc] initWithDocumentTypes:@[]
+                                                             inMode:UIDocumentPickerModeImport];
+  plugin.documentPickerViewControllerOverride = picker;
+  [plugin openFileSelectorWithConfig:[FFSFileSelectorConfig makeWithUtis:@[]
+                                                     allowMultiSelection:@YES]
+                          completion:^(NSArray<NSString *> *paths, FlutterError *error) {
+                            NSArray *expectedPaths = @[ @"/file1.txt", @"/file2.txt" ];
+                            XCTAssertEqualObjects(paths, expectedPaths);
+                            [completionWasCalled fulfill];
+                          }];
+  [plugin documentPicker:picker
+      didPickDocumentsAtURLs:@[
+        [NSURL URLWithString:@"file:///file1.txt"], [NSURL URLWithString:@"file:///file2.txt"]
+      ]];
+  [self waitForExpectationsWithTimeout:1.0 handler:nil];
+}
+
+- (void)testReturnsPickedFileLegacy {
+  // Tests that it handles the pre iOS 11 UIDocumentPickerDelegate method.
+  FFSFileSelectorPlugin *plugin = [[FFSFileSelectorPlugin alloc] init];
+  XCTestExpectation *completionWasCalled = [self expectationWithDescription:@"completion"];
+  UIDocumentPickerViewController *picker =
+      [[UIDocumentPickerViewController alloc] initWithDocumentTypes:@[]
+                                                             inMode:UIDocumentPickerModeImport];
+  plugin.documentPickerViewControllerOverride = picker;
+  [plugin openFileSelectorWithConfig:[FFSFileSelectorConfig makeWithUtis:@[]
+                                                     allowMultiSelection:@NO]
+                          completion:^(NSArray<NSString *> *paths, FlutterError *error) {
+                            NSArray *expectedPaths = @[ @"/file1.txt" ];
+                            XCTAssertEqualObjects(paths, expectedPaths);
+                            [completionWasCalled fulfill];
+                          }];
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+  [plugin documentPicker:picker didPickDocumentAtURL:[NSURL URLWithString:@"file:///file1.txt"]];
+#pragma GCC diagnostic pop
+  [self waitForExpectationsWithTimeout:1.0 handler:nil];
+}
+
+- (void)testCancellingPickerReturnsNil {
+  FFSFileSelectorPlugin *plugin = [[FFSFileSelectorPlugin alloc] init];
+  UIDocumentPickerViewController *picker =
+      [[UIDocumentPickerViewController alloc] initWithDocumentTypes:@[]
+                                                             inMode:UIDocumentPickerModeImport];
+  plugin.documentPickerViewControllerOverride = picker;
+
+  XCTestExpectation *completionWasCalled = [self expectationWithDescription:@"completion"];
+  [plugin openFileSelectorWithConfig:[FFSFileSelectorConfig makeWithUtis:@[]
+                                                     allowMultiSelection:@NO]
+                          completion:^(NSArray<NSString *> *paths, FlutterError *error) {
+                            XCTAssertEqual(paths.count, 0);
+                            [completionWasCalled fulfill];
+                          }];
+  [plugin documentPickerWasCancelled:picker];
+  [self waitForExpectationsWithTimeout:1.0 handler:nil];
+}
+
+@end
diff --git a/packages/file_selector/file_selector_ios/example/lib/home_page.dart b/packages/file_selector/file_selector_ios/example/lib/home_page.dart
new file mode 100644
index 0000000..a4b2ae1
--- /dev/null
+++ b/packages/file_selector/file_selector_ios/example/lib/home_page.dart
@@ -0,0 +1,63 @@
+// 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:flutter/material.dart';
+
+/// Home Page of the application.
+class HomePage extends StatelessWidget {
+  /// Default Constructor
+  const HomePage({Key? key}) : super(key: key);
+
+  @override
+  Widget build(BuildContext context) {
+    final ButtonStyle style = ElevatedButton.styleFrom(
+      // TODO(darrenaustin): Migrate to new API once it lands in stable: https://github.com/flutter/flutter/issues/105724
+      // ignore: deprecated_member_use
+      primary: Colors.blue,
+      // ignore: deprecated_member_use
+      onPrimary: Colors.white,
+    );
+    return Scaffold(
+      appBar: AppBar(
+        title: const Text('File Selector Demo Home Page'),
+      ),
+      body: Center(
+        child: Column(
+          mainAxisAlignment: MainAxisAlignment.center,
+          children: <Widget>[
+            ElevatedButton(
+              style: style,
+              child: const Text('Open a text file'),
+              onPressed: () => Navigator.pushNamed(context, '/open/text'),
+            ),
+            const SizedBox(height: 10),
+            ElevatedButton(
+              style: style,
+              child: const Text('Open an image'),
+              onPressed: () => Navigator.pushNamed(context, '/open/image'),
+            ),
+            const SizedBox(height: 10),
+            ElevatedButton(
+              style: style,
+              child: const Text('Open multiple images'),
+              onPressed: () => Navigator.pushNamed(context, '/open/images'),
+            ),
+            const SizedBox(height: 10),
+            ElevatedButton(
+              style: style,
+              child: const Text('Save a file'),
+              onPressed: () => Navigator.pushNamed(context, '/save/text'),
+            ),
+            const SizedBox(height: 10),
+            ElevatedButton(
+              style: style,
+              child: const Text('Open a get directory dialog'),
+              onPressed: () => Navigator.pushNamed(context, '/directory'),
+            ),
+          ],
+        ),
+      ),
+    );
+  }
+}
diff --git a/packages/file_selector/file_selector_ios/example/lib/main.dart b/packages/file_selector/file_selector_ios/example/lib/main.dart
new file mode 100644
index 0000000..929c48f
--- /dev/null
+++ b/packages/file_selector/file_selector_ios/example/lib/main.dart
@@ -0,0 +1,38 @@
+// 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:flutter/material.dart';
+
+import 'home_page.dart';
+import 'open_image_page.dart';
+import 'open_multiple_images_page.dart';
+import 'open_text_page.dart';
+
+void main() {
+  runApp(const MyApp());
+}
+
+/// MyApp is the Main Application.
+class MyApp extends StatelessWidget {
+  /// Default Constructor
+  const MyApp({Key? key}) : super(key: key);
+
+  @override
+  Widget build(BuildContext context) {
+    return MaterialApp(
+      title: 'File Selector Demo',
+      theme: ThemeData(
+        primarySwatch: Colors.blue,
+        visualDensity: VisualDensity.adaptivePlatformDensity,
+      ),
+      home: const HomePage(),
+      routes: <String, WidgetBuilder>{
+        '/open/image': (BuildContext context) => const OpenImagePage(),
+        '/open/images': (BuildContext context) =>
+            const OpenMultipleImagesPage(),
+        '/open/text': (BuildContext context) => const OpenTextPage(),
+      },
+    );
+  }
+}
diff --git a/packages/file_selector/file_selector_ios/example/lib/open_image_page.dart b/packages/file_selector/file_selector_ios/example/lib/open_image_page.dart
new file mode 100644
index 0000000..fd0f4e7
--- /dev/null
+++ b/packages/file_selector/file_selector_ios/example/lib/open_image_page.dart
@@ -0,0 +1,95 @@
+// 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 'dart:io';
+
+import 'package:file_selector_platform_interface/file_selector_platform_interface.dart';
+import 'package:flutter/foundation.dart';
+import 'package:flutter/material.dart';
+
+/// Screen that allows the user to select an image file using
+/// `openFiles`, then displays the selected images in a gallery dialog.
+class OpenImagePage extends StatelessWidget {
+  /// Default Constructor
+  const OpenImagePage({Key? key}) : super(key: key);
+
+  Future<void> _openImageFile(BuildContext context) async {
+    final XTypeGroup typeGroup = XTypeGroup(
+      label: 'images',
+      extensions: <String>['jpg', 'png'],
+      macUTIs: <String>['public.image'],
+    );
+    final XFile? file = await FileSelectorPlatform.instance
+        .openFile(acceptedTypeGroups: <XTypeGroup>[typeGroup]);
+    if (file == null) {
+      // Operation was canceled by the user.
+      return;
+    }
+    final String fileName = file.name;
+    final String filePath = file.path;
+
+    await showDialog<void>(
+      context: context,
+      builder: (BuildContext context) => ImageDisplay(fileName, filePath),
+    );
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    return Scaffold(
+      appBar: AppBar(
+        title: const Text('Open an image'),
+      ),
+      body: Center(
+        child: Column(
+          mainAxisAlignment: MainAxisAlignment.center,
+          children: <Widget>[
+            ElevatedButton(
+              style: ElevatedButton.styleFrom(
+                // TODO(darrenaustin): Migrate to new API once it lands in stable: https://github.com/flutter/flutter/issues/105724
+                // ignore: deprecated_member_use
+                primary: Colors.blue,
+                // ignore: deprecated_member_use
+                onPrimary: Colors.white,
+              ),
+              child: const Text('Press to open an image file(png, jpg)'),
+              onPressed: () => _openImageFile(context),
+            ),
+          ],
+        ),
+      ),
+    );
+  }
+}
+
+/// Widget that displays an image in a dialog.
+class ImageDisplay extends StatelessWidget {
+  /// Default Constructor.
+  const ImageDisplay(this.fileName, this.filePath, {Key? key})
+      : super(key: key);
+
+  /// The name of the selected file.
+  final String fileName;
+
+  /// The path to the selected file.
+  final String filePath;
+
+  @override
+  Widget build(BuildContext context) {
+    return AlertDialog(
+      title: Text(fileName),
+      // On web the filePath is a blob url
+      // while on other platforms it is a system path.
+      content: kIsWeb ? Image.network(filePath) : Image.file(File(filePath)),
+      actions: <Widget>[
+        TextButton(
+          child: const Text('Close'),
+          onPressed: () {
+            Navigator.pop(context);
+          },
+        ),
+      ],
+    );
+  }
+}
diff --git a/packages/file_selector/file_selector_ios/example/lib/open_multiple_images_page.dart b/packages/file_selector/file_selector_ios/example/lib/open_multiple_images_page.dart
new file mode 100644
index 0000000..29b27c1
--- /dev/null
+++ b/packages/file_selector/file_selector_ios/example/lib/open_multiple_images_page.dart
@@ -0,0 +1,107 @@
+// 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 'dart:io';
+
+import 'package:file_selector_platform_interface/file_selector_platform_interface.dart';
+import 'package:flutter/foundation.dart';
+import 'package:flutter/material.dart';
+
+/// Screen that allows the user to select multiple image files using
+/// `openFiles`, then displays the selected images in a gallery dialog.
+class OpenMultipleImagesPage extends StatelessWidget {
+  /// Default Constructor
+  const OpenMultipleImagesPage({Key? key}) : super(key: key);
+
+  Future<void> _openImageFile(BuildContext context) async {
+    final XTypeGroup jpgsTypeGroup = XTypeGroup(
+      label: 'JPEGs',
+      extensions: <String>['jpg', 'jpeg'],
+      macUTIs: <String>['public.jpeg'],
+    );
+    final XTypeGroup pngTypeGroup = XTypeGroup(
+      label: 'PNGs',
+      extensions: <String>['png'],
+      macUTIs: <String>['public.png'],
+    );
+    final List<XFile> files = await FileSelectorPlatform.instance
+        .openFiles(acceptedTypeGroups: <XTypeGroup>[
+      jpgsTypeGroup,
+      pngTypeGroup,
+    ]);
+    if (files.isEmpty) {
+      // Operation was canceled by the user.
+      return;
+    }
+    await showDialog<void>(
+      context: context,
+      builder: (BuildContext context) => MultipleImagesDisplay(files),
+    );
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    return Scaffold(
+      appBar: AppBar(
+        title: const Text('Open multiple images'),
+      ),
+      body: Center(
+        child: Column(
+          mainAxisAlignment: MainAxisAlignment.center,
+          children: <Widget>[
+            ElevatedButton(
+              style: ElevatedButton.styleFrom(
+                // TODO(darrenaustin): Migrate to new API once it lands in stable: https://github.com/flutter/flutter/issues/105724
+                // ignore: deprecated_member_use
+                primary: Colors.blue,
+                // ignore: deprecated_member_use
+                onPrimary: Colors.white,
+              ),
+              child: const Text('Press to open multiple images (png, jpg)'),
+              onPressed: () => _openImageFile(context),
+            ),
+          ],
+        ),
+      ),
+    );
+  }
+}
+
+/// Widget that displays a text file in a dialog.
+class MultipleImagesDisplay extends StatelessWidget {
+  /// Default Constructor.
+  const MultipleImagesDisplay(this.files, {Key? key}) : super(key: key);
+
+  /// The files containing the images.
+  final List<XFile> files;
+
+  @override
+  Widget build(BuildContext context) {
+    return AlertDialog(
+      title: const Text('Gallery'),
+      // On web the filePath is a blob url
+      // while on other platforms it is a system path.
+      content: Center(
+        child: Row(
+          children: <Widget>[
+            ...files.map(
+              (XFile file) => Flexible(
+                  child: kIsWeb
+                      ? Image.network(file.path)
+                      : Image.file(File(file.path))),
+            )
+          ],
+        ),
+      ),
+      actions: <Widget>[
+        TextButton(
+          child: const Text('Close'),
+          onPressed: () {
+            Navigator.pop(context);
+          },
+        ),
+      ],
+    );
+  }
+}
diff --git a/packages/file_selector/file_selector_ios/example/lib/open_text_page.dart b/packages/file_selector/file_selector_ios/example/lib/open_text_page.dart
new file mode 100644
index 0000000..b747aa8
--- /dev/null
+++ b/packages/file_selector/file_selector_ios/example/lib/open_text_page.dart
@@ -0,0 +1,92 @@
+// 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:file_selector_platform_interface/file_selector_platform_interface.dart';
+import 'package:flutter/material.dart';
+
+/// Screen that allows the user to select a text file using `openFile`, then
+/// displays its contents in a dialog.
+class OpenTextPage extends StatelessWidget {
+  /// Default Constructor
+  const OpenTextPage({Key? key}) : super(key: key);
+
+  Future<void> _openTextFile(BuildContext context) async {
+    final XTypeGroup typeGroup = XTypeGroup(
+      label: 'text',
+      extensions: <String>['txt', 'json'],
+      macUTIs: <String>['public.text'],
+    );
+    final XFile? file = await FileSelectorPlatform.instance
+        .openFile(acceptedTypeGroups: <XTypeGroup>[typeGroup]);
+    if (file == null) {
+      // Operation was canceled by the user.
+      return;
+    }
+    final String fileName = file.name;
+    final String fileContent = await file.readAsString();
+
+    await showDialog<void>(
+      context: context,
+      builder: (BuildContext context) => TextDisplay(fileName, fileContent),
+    );
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    return Scaffold(
+      appBar: AppBar(
+        title: const Text('Open a text file'),
+      ),
+      body: Center(
+        child: Column(
+          mainAxisAlignment: MainAxisAlignment.center,
+          children: <Widget>[
+            ElevatedButton(
+              style: ElevatedButton.styleFrom(
+                // TODO(darrenaustin): Migrate to new API once it lands in stable: https://github.com/flutter/flutter/issues/105724
+                // ignore: deprecated_member_use
+                primary: Colors.blue,
+                // ignore: deprecated_member_use
+                onPrimary: Colors.white,
+              ),
+              child: const Text('Press to open a text file (json, txt)'),
+              onPressed: () => _openTextFile(context),
+            ),
+          ],
+        ),
+      ),
+    );
+  }
+}
+
+/// Widget that displays a text file in a dialog.
+class TextDisplay extends StatelessWidget {
+  /// Default Constructor.
+  const TextDisplay(this.fileName, this.fileContent, {Key? key})
+      : super(key: key);
+
+  /// The name of the selected file.
+  final String fileName;
+
+  /// The contents of the text file.
+  final String fileContent;
+
+  @override
+  Widget build(BuildContext context) {
+    return AlertDialog(
+      title: Text(fileName),
+      content: Scrollbar(
+        child: SingleChildScrollView(
+          child: Text(fileContent),
+        ),
+      ),
+      actions: <Widget>[
+        TextButton(
+          child: const Text('Close'),
+          onPressed: () => Navigator.pop(context),
+        ),
+      ],
+    );
+  }
+}
diff --git a/packages/file_selector/file_selector_ios/example/pubspec.yaml b/packages/file_selector/file_selector_ios/example/pubspec.yaml
new file mode 100644
index 0000000..eae4a2b
--- /dev/null
+++ b/packages/file_selector/file_selector_ios/example/pubspec.yaml
@@ -0,0 +1,31 @@
+name: example
+description: Example for file_selector_ios implementation.
+publish_to: 'none'
+version: 1.0.0
+
+environment:
+  sdk: ">=2.14.4 <3.0.0"
+
+dependencies:
+  # The following adds the Cupertino Icons font to your application.
+  # Use with the CupertinoIcons class for iOS style icons.
+  cupertino_icons: ^1.0.2
+  file_selector_ios:
+    # When depending on this package from a real application you should use:
+    #   file_selector_ios: ^x.y.z
+    # See https://dart.dev/tools/pub/dependencies#version-constraints
+    # The example app is bundled with the plugin so we use a path dependency on
+    # the parent directory to use the current plugin's version.
+    path: ..
+  file_selector_platform_interface: ^2.0.0
+  flutter:
+    sdk: flutter
+
+dev_dependencies:
+  flutter_test:
+    sdk: flutter
+  integration_test:
+    sdk: flutter
+
+flutter:
+  uses-material-design: true
\ No newline at end of file
diff --git a/packages/file_selector/file_selector_ios/example/test_driver/integration_test.dart b/packages/file_selector/file_selector_ios/example/test_driver/integration_test.dart
new file mode 100644
index 0000000..4f10f2a
--- /dev/null
+++ b/packages/file_selector/file_selector_ios/example/test_driver/integration_test.dart
@@ -0,0 +1,7 @@
+// 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:integration_test/integration_test_driver.dart';
+
+Future<void> main() => integrationDriver();
diff --git a/packages/file_selector/file_selector_ios/ios/.gitignore b/packages/file_selector/file_selector_ios/ios/.gitignore
new file mode 100644
index 0000000..0c88507
--- /dev/null
+++ b/packages/file_selector/file_selector_ios/ios/.gitignore
@@ -0,0 +1,38 @@
+.idea/
+.vagrant/
+.sconsign.dblite
+.svn/
+
+.DS_Store
+*.swp
+profile
+
+DerivedData/
+build/
+GeneratedPluginRegistrant.h
+GeneratedPluginRegistrant.m
+
+.generated/
+
+*.pbxuser
+*.mode1v3
+*.mode2v3
+*.perspectivev3
+
+!default.pbxuser
+!default.mode1v3
+!default.mode2v3
+!default.perspectivev3
+
+xcuserdata
+
+*.moved-aside
+
+*.pyc
+*sync/
+Icon?
+.tags*
+
+/Flutter/Generated.xcconfig
+/Flutter/ephemeral/
+/Flutter/flutter_export_environment.sh
\ No newline at end of file
diff --git a/packages/file_selector/file_selector_ios/ios/Assets/.gitkeep b/packages/file_selector/file_selector_ios/ios/Assets/.gitkeep
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/packages/file_selector/file_selector_ios/ios/Assets/.gitkeep
diff --git a/packages/file_selector/file_selector_ios/ios/Classes/FFSFileSelectorPlugin.h b/packages/file_selector/file_selector_ios/ios/Classes/FFSFileSelectorPlugin.h
new file mode 100644
index 0000000..ca7ca56
--- /dev/null
+++ b/packages/file_selector/file_selector_ios/ios/Classes/FFSFileSelectorPlugin.h
@@ -0,0 +1,8 @@
+// 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 <Flutter/Flutter.h>
+
+@interface FFSFileSelectorPlugin : NSObject <FlutterPlugin>
+@end
diff --git a/packages/file_selector/file_selector_ios/ios/Classes/FFSFileSelectorPlugin.m b/packages/file_selector/file_selector_ios/ios/Classes/FFSFileSelectorPlugin.m
new file mode 100644
index 0000000..e77585a
--- /dev/null
+++ b/packages/file_selector/file_selector_ios/ios/Classes/FFSFileSelectorPlugin.m
@@ -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.
+
+#import "FFSFileSelectorPlugin.h"
+#import "FFSFileSelectorPlugin_Test.h"
+#import "messages.g.h"
+
+#import <objc/runtime.h>
+
+@implementation FFSFileSelectorPlugin
+
+#pragma mark - FFSFileSelectorApi
+
+- (void)openFileSelectorWithConfig:(FFSFileSelectorConfig *)config
+                        completion:(void (^)(NSArray<NSString *> *_Nullable,
+                                             FlutterError *_Nullable))completion {
+  UIDocumentPickerViewController *documentPicker =
+      self.documentPickerViewControllerOverride
+          ?: [[UIDocumentPickerViewController alloc]
+                 initWithDocumentTypes:config.utis
+                                inMode:UIDocumentPickerModeImport];
+  documentPicker.delegate = self;
+  if (@available(iOS 11.0, *)) {
+    documentPicker.allowsMultipleSelection = config.allowMultiSelection.boolValue;
+  }
+
+  UIViewController *presentingVC =
+      self.presentingViewControllerOverride
+          ?: UIApplication.sharedApplication.delegate.window.rootViewController;
+  if (presentingVC) {
+    objc_setAssociatedObject(documentPicker, @selector(openFileSelectorWithConfig:completion:),
+                             completion, OBJC_ASSOCIATION_COPY_NONATOMIC);
+    [presentingVC presentViewController:documentPicker animated:YES completion:nil];
+  } else {
+    completion(nil, [FlutterError errorWithCode:@"error"
+                                        message:@"Missing root view controller."
+                                        details:nil]);
+  }
+}
+
+#pragma mark - FlutterPlugin
+
++ (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar> *)registrar {
+  FFSFileSelectorPlugin *plugin = [[FFSFileSelectorPlugin alloc] init];
+  FFSFileSelectorApiSetup(registrar.messenger, plugin);
+}
+
+#pragma mark - UIDocumentPickerDelegate
+
+// This method is only called in iOS < 11.0. The new codepath is
+// documentPicker:didPickDocumentsAtURLs:, implemented below.
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-implementations"
+- (void)documentPicker:(UIDocumentPickerViewController *)controller
+    didPickDocumentAtURL:(NSURL *)url {
+  [self sendBackResults:@[ url.path ] error:nil forPicker:controller];
+}
+#pragma clang diagnostic pop
+
+- (void)documentPicker:(UIDocumentPickerViewController *)controller
+    didPickDocumentsAtURLs:(NSArray<NSURL *> *)urls {
+  NSMutableArray *paths = [NSMutableArray arrayWithCapacity:urls.count];
+  for (NSURL *url in urls) {
+    [paths addObject:url.path];
+  };
+  [self sendBackResults:paths error:nil forPicker:controller];
+}
+
+- (void)documentPickerWasCancelled:(UIDocumentPickerViewController *)controller {
+  [self sendBackResults:@[] error:nil forPicker:controller];
+}
+
+#pragma mark - Helper Methods
+
+- (void)sendBackResults:(NSArray<NSString *> *)results
+                  error:(FlutterError *)error
+              forPicker:(UIDocumentPickerViewController *)picker {
+  void (^completionBlock)(NSArray<NSString *> *, FlutterError *) =
+      objc_getAssociatedObject(picker, @selector(openFileSelectorWithConfig:completion:));
+  if (completionBlock) {
+    completionBlock(results, error);
+    objc_setAssociatedObject(picker, @selector(openFileSelectorWithConfig:completion:), nil,
+                             OBJC_ASSOCIATION_ASSIGN);
+  }
+}
+
+@end
diff --git a/packages/file_selector/file_selector_ios/ios/Classes/FFSFileSelectorPlugin_Test.h b/packages/file_selector/file_selector_ios/ios/Classes/FFSFileSelectorPlugin_Test.h
new file mode 100644
index 0000000..f71a8ae
--- /dev/null
+++ b/packages/file_selector/file_selector_ios/ios/Classes/FFSFileSelectorPlugin_Test.h
@@ -0,0 +1,22 @@
+// 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 "FFSFileSelectorPlugin.h"
+
+#import "messages.g.h"
+
+// This header is available in the Test module. Import via "@import file_selector_ios.Test;".
+@interface FFSFileSelectorPlugin () <FFSFileSelectorApi, UIDocumentPickerDelegate>
+
+/**
+ * Overrides the view controller used for presenting the document picker.
+ */
+@property(nonatomic) UIViewController *_Nullable presentingViewControllerOverride;
+
+/**
+ * Overrides the UIDocumentPickerViewController used for file picking.
+ */
+@property(nonatomic) UIDocumentPickerViewController *_Nullable documentPickerViewControllerOverride;
+
+@end
diff --git a/packages/file_selector/file_selector_ios/ios/Classes/FileSelectorPlugin.modulemap b/packages/file_selector/file_selector_ios/ios/Classes/FileSelectorPlugin.modulemap
new file mode 100644
index 0000000..4ff4026
--- /dev/null
+++ b/packages/file_selector/file_selector_ios/ios/Classes/FileSelectorPlugin.modulemap
@@ -0,0 +1,10 @@
+framework module file_selector_ios {
+  umbrella header "file_selector_ios-umbrella.h"
+
+  export *
+  module * { export * }
+
+  explicit module Test {
+    header "FFSFileSelectorPlugin_Test.h"
+  }
+}
diff --git a/packages/file_selector/file_selector_ios/ios/Classes/file_selector_ios-umbrella.h b/packages/file_selector/file_selector_ios/ios/Classes/file_selector_ios-umbrella.h
new file mode 100644
index 0000000..d79d364
--- /dev/null
+++ b/packages/file_selector/file_selector_ios/ios/Classes/file_selector_ios-umbrella.h
@@ -0,0 +1,6 @@
+// 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 <Foundation/Foundation.h>
+#import <file_selector_ios/FFSFileSelectorPlugin.h>
diff --git a/packages/file_selector/file_selector_ios/ios/Classes/messages.g.h b/packages/file_selector/file_selector_ios/ios/Classes/messages.g.h
new file mode 100644
index 0000000..a04b411
--- /dev/null
+++ b/packages/file_selector/file_selector_ios/ios/Classes/messages.g.h
@@ -0,0 +1,37 @@
+// 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.2.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
+
+@class FFSFileSelectorConfig;
+
+@interface FFSFileSelectorConfig : NSObject
+/// `init` unavailable to enforce nonnull fields, see the `make` class method.
+- (instancetype)init NS_UNAVAILABLE;
++ (instancetype)makeWithUtis:(NSArray<NSString *> *)utis
+         allowMultiSelection:(NSNumber *)allowMultiSelection;
+@property(nonatomic, strong) NSArray<NSString *> *utis;
+@property(nonatomic, strong) NSNumber *allowMultiSelection;
+@end
+
+/// The codec used by FFSFileSelectorApi.
+NSObject<FlutterMessageCodec> *FFSFileSelectorApiGetCodec(void);
+
+@protocol FFSFileSelectorApi
+- (void)openFileSelectorWithConfig:(FFSFileSelectorConfig *)config
+                        completion:(void (^)(NSArray<NSString *> *_Nullable,
+                                             FlutterError *_Nullable))completion;
+@end
+
+extern void FFSFileSelectorApiSetup(id<FlutterBinaryMessenger> binaryMessenger,
+                                    NSObject<FFSFileSelectorApi> *_Nullable api);
+
+NS_ASSUME_NONNULL_END
diff --git a/packages/file_selector/file_selector_ios/ios/Classes/messages.g.m b/packages/file_selector/file_selector_ios/ios/Classes/messages.g.m
new file mode 100644
index 0000000..d4046d2
--- /dev/null
+++ b/packages/file_selector/file_selector_ios/ios/Classes/messages.g.m
@@ -0,0 +1,143 @@
+// 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.2.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,
+  };
+}
+static id GetNullableObject(NSDictionary *dict, id key) {
+  id result = dict[key];
+  return (result == [NSNull null]) ? nil : result;
+}
+static id GetNullableObjectAtIndex(NSArray *array, NSInteger key) {
+  id result = array[key];
+  return (result == [NSNull null]) ? nil : result;
+}
+
+@interface FFSFileSelectorConfig ()
++ (FFSFileSelectorConfig *)fromMap:(NSDictionary *)dict;
++ (nullable FFSFileSelectorConfig *)nullableFromMap:(NSDictionary *)dict;
+- (NSDictionary *)toMap;
+@end
+
+@implementation FFSFileSelectorConfig
++ (instancetype)makeWithUtis:(NSArray<NSString *> *)utis
+         allowMultiSelection:(NSNumber *)allowMultiSelection {
+  FFSFileSelectorConfig *pigeonResult = [[FFSFileSelectorConfig alloc] init];
+  pigeonResult.utis = utis;
+  pigeonResult.allowMultiSelection = allowMultiSelection;
+  return pigeonResult;
+}
++ (FFSFileSelectorConfig *)fromMap:(NSDictionary *)dict {
+  FFSFileSelectorConfig *pigeonResult = [[FFSFileSelectorConfig alloc] init];
+  pigeonResult.utis = GetNullableObject(dict, @"utis");
+  NSAssert(pigeonResult.utis != nil, @"");
+  pigeonResult.allowMultiSelection = GetNullableObject(dict, @"allowMultiSelection");
+  NSAssert(pigeonResult.allowMultiSelection != nil, @"");
+  return pigeonResult;
+}
++ (nullable FFSFileSelectorConfig *)nullableFromMap:(NSDictionary *)dict {
+  return (dict) ? [FFSFileSelectorConfig fromMap:dict] : nil;
+}
+- (NSDictionary *)toMap {
+  return @{
+    @"utis" : (self.utis ?: [NSNull null]),
+    @"allowMultiSelection" : (self.allowMultiSelection ?: [NSNull null]),
+  };
+}
+@end
+
+@interface FFSFileSelectorApiCodecReader : FlutterStandardReader
+@end
+@implementation FFSFileSelectorApiCodecReader
+- (nullable id)readValueOfType:(UInt8)type {
+  switch (type) {
+    case 128:
+      return [FFSFileSelectorConfig fromMap:[self readValue]];
+
+    default:
+      return [super readValueOfType:type];
+  }
+}
+@end
+
+@interface FFSFileSelectorApiCodecWriter : FlutterStandardWriter
+@end
+@implementation FFSFileSelectorApiCodecWriter
+- (void)writeValue:(id)value {
+  if ([value isKindOfClass:[FFSFileSelectorConfig class]]) {
+    [self writeByte:128];
+    [self writeValue:[value toMap]];
+  } else {
+    [super writeValue:value];
+  }
+}
+@end
+
+@interface FFSFileSelectorApiCodecReaderWriter : FlutterStandardReaderWriter
+@end
+@implementation FFSFileSelectorApiCodecReaderWriter
+- (FlutterStandardWriter *)writerWithData:(NSMutableData *)data {
+  return [[FFSFileSelectorApiCodecWriter alloc] initWithData:data];
+}
+- (FlutterStandardReader *)readerWithData:(NSData *)data {
+  return [[FFSFileSelectorApiCodecReader alloc] initWithData:data];
+}
+@end
+
+NSObject<FlutterMessageCodec> *FFSFileSelectorApiGetCodec() {
+  static dispatch_once_t sPred = 0;
+  static FlutterStandardMessageCodec *sSharedObject = nil;
+  dispatch_once(&sPred, ^{
+    FFSFileSelectorApiCodecReaderWriter *readerWriter =
+        [[FFSFileSelectorApiCodecReaderWriter alloc] init];
+    sSharedObject = [FlutterStandardMessageCodec codecWithReaderWriter:readerWriter];
+  });
+  return sSharedObject;
+}
+
+void FFSFileSelectorApiSetup(id<FlutterBinaryMessenger> binaryMessenger,
+                             NSObject<FFSFileSelectorApi> *api) {
+  {
+    FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc]
+           initWithName:@"dev.flutter.pigeon.FileSelectorApi.openFile"
+        binaryMessenger:binaryMessenger
+                  codec:FFSFileSelectorApiGetCodec()];
+    if (api) {
+      NSCAssert([api respondsToSelector:@selector(openFileSelectorWithConfig:completion:)],
+                @"FFSFileSelectorApi api (%@) doesn't respond to "
+                @"@selector(openFileSelectorWithConfig:completion:)",
+                api);
+      [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
+        NSArray *args = message;
+        FFSFileSelectorConfig *arg_config = GetNullableObjectAtIndex(args, 0);
+        [api openFileSelectorWithConfig:arg_config
+                             completion:^(NSArray<NSString *> *_Nullable output,
+                                          FlutterError *_Nullable error) {
+                               callback(wrapResult(output, error));
+                             }];
+      }];
+    } else {
+      [channel setMessageHandler:nil];
+    }
+  }
+}
diff --git a/packages/file_selector/file_selector_ios/ios/file_selector_ios.podspec b/packages/file_selector/file_selector_ios/ios/file_selector_ios.podspec
new file mode 100644
index 0000000..bb96b3c
--- /dev/null
+++ b/packages/file_selector/file_selector_ios/ios/file_selector_ios.podspec
@@ -0,0 +1,24 @@
+#
+# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html.
+# Run `pod lib lint file_selector_ios.podspec` to validate before publishing.
+#
+Pod::Spec.new do |s|
+  s.name             = 'file_selector_ios'
+  s.version          = '0.0.1'
+  s.summary          = 'iOS implementation of file_selector.'
+  s.description      = <<-DESC
+Displays the native iOS document picker.
+                       DESC
+  s.homepage         = 'https://github.com/flutter/plugins/tree/main/packages/file_selector'
+  s.license          = { :type => 'BSD', :file => '../LICENSE' }
+  s.author           = { 'Flutter Dev Team' => 'flutter-dev@googlegroups.com' }
+  s.source           = { :http => 'https://github.com/flutter/plugins/tree/main/packages/file_selector/file_selector_ios' }
+  s.source_files = 'Classes/**/*.{h,m}'
+  s.module_map = 'Classes/FileSelectorPlugin.modulemap'
+  s.dependency 'Flutter'
+  s.platform = :ios, '9.0'
+
+  # Flutter.framework does not contain a i386 slice.
+  s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'i386' }
+  s.swift_version = '5.0'
+end
diff --git a/packages/file_selector/file_selector_ios/lib/file_selector_ios.dart b/packages/file_selector/file_selector_ios/lib/file_selector_ios.dart
new file mode 100644
index 0000000..e75f67e
--- /dev/null
+++ b/packages/file_selector/file_selector_ios/lib/file_selector_ios.dart
@@ -0,0 +1,64 @@
+// 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:file_selector_platform_interface/file_selector_platform_interface.dart';
+
+import 'src/messages.g.dart';
+
+/// An implementation of [FileSelectorPlatform] for iOS.
+class FileSelectorIOS extends FileSelectorPlatform {
+  final FileSelectorApi _hostApi = FileSelectorApi();
+
+  /// Registers the iOS implementation.
+  static void registerWith() {
+    FileSelectorPlatform.instance = FileSelectorIOS();
+  }
+
+  @override
+  Future<XFile?> openFile({
+    List<XTypeGroup>? acceptedTypeGroups,
+    String? initialDirectory,
+    String? confirmButtonText,
+  }) async {
+    final List<String> path = (await _hostApi.openFile(FileSelectorConfig(
+            utis: _allowedUtiListFromTypeGroups(acceptedTypeGroups),
+            allowMultiSelection: false)))
+        .cast<String>();
+    return path.isEmpty ? null : XFile(path.first);
+  }
+
+  @override
+  Future<List<XFile>> openFiles({
+    List<XTypeGroup>? acceptedTypeGroups,
+    String? initialDirectory,
+    String? confirmButtonText,
+  }) async {
+    final List<String> pathList = (await _hostApi.openFile(FileSelectorConfig(
+            utis: _allowedUtiListFromTypeGroups(acceptedTypeGroups),
+            allowMultiSelection: true)))
+        .cast<String>();
+    return pathList.map((String path) => XFile(path)).toList();
+  }
+
+  // Converts the type group list into a list of all allowed UTIs, since
+  // iOS doesn't support filter groups.
+  List<String> _allowedUtiListFromTypeGroups(List<XTypeGroup>? typeGroups) {
+    if (typeGroups == null || typeGroups.isEmpty) {
+      return <String>[];
+    }
+    final List<String> allowedUTIs = <String>[];
+    for (final XTypeGroup typeGroup in typeGroups) {
+      // If any group allows everything, no filtering should be done.
+      if (typeGroup.allowsAny) {
+        return <String>[];
+      }
+      if (typeGroup.macUTIs?.isEmpty ?? true) {
+        throw ArgumentError('The provided type group $typeGroup should either '
+            'allow all files, or have a non-empty "macUTIs"');
+      }
+      allowedUTIs.addAll(typeGroup.macUTIs!);
+    }
+    return allowedUTIs;
+  }
+}
diff --git a/packages/file_selector/file_selector_ios/lib/src/messages.g.dart b/packages/file_selector/file_selector_ios/lib/src/messages.g.dart
new file mode 100644
index 0000000..4218474
--- /dev/null
+++ b/packages/file_selector/file_selector_ios/lib/src/messages.g.dart
@@ -0,0 +1,101 @@
+// 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.2.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, unnecessary_import
+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 FileSelectorConfig {
+  FileSelectorConfig({
+    required this.utis,
+    required this.allowMultiSelection,
+  });
+
+  List<String?> utis;
+  bool allowMultiSelection;
+
+  Object encode() {
+    final Map<Object?, Object?> pigeonMap = <Object?, Object?>{};
+    pigeonMap['utis'] = utis;
+    pigeonMap['allowMultiSelection'] = allowMultiSelection;
+    return pigeonMap;
+  }
+
+  static FileSelectorConfig decode(Object message) {
+    final Map<Object?, Object?> pigeonMap = message as Map<Object?, Object?>;
+    return FileSelectorConfig(
+      utis: (pigeonMap['utis'] as List<Object?>?)!.cast<String?>(),
+      allowMultiSelection: pigeonMap['allowMultiSelection']! as bool,
+    );
+  }
+}
+
+class _FileSelectorApiCodec extends StandardMessageCodec {
+  const _FileSelectorApiCodec();
+  @override
+  void writeValue(WriteBuffer buffer, Object? value) {
+    if (value is FileSelectorConfig) {
+      buffer.putUint8(128);
+      writeValue(buffer, value.encode());
+    } else {
+      super.writeValue(buffer, value);
+    }
+  }
+
+  @override
+  Object? readValueOfType(int type, ReadBuffer buffer) {
+    switch (type) {
+      case 128:
+        return FileSelectorConfig.decode(readValue(buffer)!);
+
+      default:
+        return super.readValueOfType(type, buffer);
+    }
+  }
+}
+
+class FileSelectorApi {
+  /// Constructor for [FileSelectorApi].  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.
+  FileSelectorApi({BinaryMessenger? binaryMessenger})
+      : _binaryMessenger = binaryMessenger;
+
+  final BinaryMessenger? _binaryMessenger;
+
+  static const MessageCodec<Object?> codec = _FileSelectorApiCodec();
+
+  Future<List<String?>> openFile(FileSelectorConfig arg_config) async {
+    final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
+        'dev.flutter.pigeon.FileSelectorApi.openFile', codec,
+        binaryMessenger: _binaryMessenger);
+    final Map<Object?, Object?>? replyMap =
+        await channel.send(<Object?>[arg_config]) 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 if (replyMap['result'] == null) {
+      throw PlatformException(
+        code: 'null-error',
+        message: 'Host platform returned null value for non-null return value.',
+      );
+    } else {
+      return (replyMap['result'] as List<Object?>?)!.cast<String?>();
+    }
+  }
+}
diff --git a/packages/file_selector/file_selector_ios/pigeons/copyright.txt b/packages/file_selector/file_selector_ios/pigeons/copyright.txt
new file mode 100644
index 0000000..fb682b1
--- /dev/null
+++ b/packages/file_selector/file_selector_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.
\ No newline at end of file
diff --git a/packages/file_selector/file_selector_ios/pigeons/messages.dart b/packages/file_selector/file_selector_ios/pigeons/messages.dart
new file mode 100644
index 0000000..d0ea73c
--- /dev/null
+++ b/packages/file_selector/file_selector_ios/pigeons/messages.dart
@@ -0,0 +1,29 @@
+// 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(
+  dartOut: 'lib/src/messages.g.dart',
+  dartTestOut: 'test/test_api.dart',
+  objcHeaderOut: 'ios/Classes/messages.g.h',
+  objcSourceOut: 'ios/Classes/messages.g.m',
+  objcOptions: ObjcOptions(
+    prefix: 'FFS',
+  ),
+  copyrightHeader: 'pigeons/copyright.txt',
+))
+class FileSelectorConfig {
+  FileSelectorConfig(
+      {this.utis = const <String?>[], this.allowMultiSelection = false});
+  List<String?> utis;
+  bool allowMultiSelection;
+}
+
+@HostApi(dartHostTestHandler: 'TestFileSelectorApi')
+abstract class FileSelectorApi {
+  @async
+  @ObjCSelector('openFileSelectorWithConfig:')
+  List<String> openFile(FileSelectorConfig config);
+}
diff --git a/packages/file_selector/file_selector_ios/pubspec.yaml b/packages/file_selector/file_selector_ios/pubspec.yaml
new file mode 100644
index 0000000..1e4056d
--- /dev/null
+++ b/packages/file_selector/file_selector_ios/pubspec.yaml
@@ -0,0 +1,30 @@
+name: file_selector_ios
+description: iOS implementation of the file_selector plugin.
+repository: https://github.com/flutter/plugins/tree/main/packages/file_selector/file_selector_ios
+issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+file_selector%22
+version: 0.5.0
+
+environment:
+  sdk: ">=2.14.4 <3.0.0"
+  flutter: ">=2.8.0"
+
+flutter:
+  plugin:
+    implements: file_selector
+    platforms:
+      ios:
+        dartPluginClass: FileSelectorIOS
+        pluginClass: FFSFileSelectorPlugin
+
+dependencies:
+  file_selector_platform_interface: ^2.1.0
+  flutter:
+    sdk: flutter
+
+dev_dependencies:
+  build_runner: 2.1.11
+  flutter_test:
+    sdk: flutter
+  mockito: ^5.1.0
+  pigeon: ^3.2.5
+  
diff --git a/packages/file_selector/file_selector_ios/test/file_selector_ios_test.dart b/packages/file_selector/file_selector_ios/test/file_selector_ios_test.dart
new file mode 100644
index 0000000..f9ef406
--- /dev/null
+++ b/packages/file_selector/file_selector_ios/test/file_selector_ios_test.dart
@@ -0,0 +1,136 @@
+// 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:file_selector_ios/file_selector_ios.dart';
+import 'package:file_selector_ios/src/messages.g.dart';
+import 'package:file_selector_platform_interface/file_selector_platform_interface.dart';
+import 'package:flutter/foundation.dart';
+import 'package:flutter_test/flutter_test.dart';
+import 'package:mockito/annotations.dart';
+import 'package:mockito/mockito.dart';
+
+import 'file_selector_ios_test.mocks.dart';
+import 'test_api.dart';
+
+@GenerateMocks(<Type>[TestFileSelectorApi])
+void main() {
+  TestWidgetsFlutterBinding.ensureInitialized();
+
+  final FileSelectorIOS plugin = FileSelectorIOS();
+  late MockTestFileSelectorApi mockApi;
+
+  setUp(() {
+    mockApi = MockTestFileSelectorApi();
+    TestFileSelectorApi.setup(mockApi);
+  });
+
+  test('registered instance', () {
+    FileSelectorIOS.registerWith();
+    expect(FileSelectorPlatform.instance, isA<FileSelectorIOS>());
+  });
+
+  group('openFile', () {
+    setUp(() {
+      when(mockApi.openFile(any)).thenAnswer((_) async => <String>['foo']);
+    });
+
+    test('passes the accepted type groups correctly', () async {
+      final XTypeGroup group = XTypeGroup(
+        label: 'text',
+        extensions: <String>['txt'],
+        mimeTypes: <String>['text/plain'],
+        macUTIs: <String>['public.text'],
+      );
+
+      final XTypeGroup groupTwo = XTypeGroup(
+          label: 'image',
+          extensions: <String>['jpg'],
+          mimeTypes: <String>['image/jpg'],
+          macUTIs: <String>['public.image'],
+          webWildCards: <String>['image/*']);
+
+      await plugin.openFile(acceptedTypeGroups: <XTypeGroup>[group, groupTwo]);
+
+      final VerificationResult result = verify(mockApi.openFile(captureAny));
+      final FileSelectorConfig config =
+          result.captured[0] as FileSelectorConfig;
+
+      // iOS only accepts macUTIs.
+      expect(listEquals(config.utis, <String>['public.text', 'public.image']),
+          isTrue);
+      expect(config.allowMultiSelection, isFalse);
+    });
+    test('throws for a type group that does not support iOS', () async {
+      final XTypeGroup group = XTypeGroup(
+        label: 'images',
+        webWildCards: <String>['images/*'],
+      );
+
+      await expectLater(
+          plugin.openFile(acceptedTypeGroups: <XTypeGroup>[group]),
+          throwsArgumentError);
+    });
+
+    test('allows a wildcard group', () async {
+      final XTypeGroup group = XTypeGroup(
+        label: 'text',
+      );
+
+      await expectLater(
+          plugin.openFile(acceptedTypeGroups: <XTypeGroup>[group]), completes);
+    });
+  });
+
+  group('openFiles', () {
+    setUp(() {
+      when(mockApi.openFile(any)).thenAnswer((_) async => <String>['foo']);
+    });
+
+    test('passes the accepted type groups correctly', () async {
+      final XTypeGroup group = XTypeGroup(
+        label: 'text',
+        extensions: <String>['txt'],
+        mimeTypes: <String>['text/plain'],
+        macUTIs: <String>['public.text'],
+      );
+
+      final XTypeGroup groupTwo = XTypeGroup(
+          label: 'image',
+          extensions: <String>['jpg'],
+          mimeTypes: <String>['image/jpg'],
+          macUTIs: <String>['public.image'],
+          webWildCards: <String>['image/*']);
+
+      await plugin.openFiles(acceptedTypeGroups: <XTypeGroup>[group, groupTwo]);
+
+      final VerificationResult result = verify(mockApi.openFile(captureAny));
+      final FileSelectorConfig config =
+          result.captured[0] as FileSelectorConfig;
+
+      // iOS only accepts macUTIs.
+      expect(listEquals(config.utis, <String>['public.text', 'public.image']),
+          isTrue);
+      expect(config.allowMultiSelection, isTrue);
+    });
+    test('throws for a type group that does not support iOS', () async {
+      final XTypeGroup group = XTypeGroup(
+        label: 'images',
+        webWildCards: <String>['images/*'],
+      );
+
+      await expectLater(
+          plugin.openFiles(acceptedTypeGroups: <XTypeGroup>[group]),
+          throwsArgumentError);
+    });
+
+    test('allows a wildcard group', () async {
+      final XTypeGroup group = XTypeGroup(
+        label: 'text',
+      );
+
+      await expectLater(
+          plugin.openFiles(acceptedTypeGroups: <XTypeGroup>[group]), completes);
+    });
+  });
+}
diff --git a/packages/file_selector/file_selector_ios/test/file_selector_ios_test.mocks.dart b/packages/file_selector/file_selector_ios/test/file_selector_ios_test.mocks.dart
new file mode 100644
index 0000000..38c91b4
--- /dev/null
+++ b/packages/file_selector/file_selector_ios/test/file_selector_ios_test.mocks.dart
@@ -0,0 +1,38 @@
+// Mocks generated by Mockito 5.3.0 from annotations
+// in file_selector_ios/example/ios/.symlinks/plugins/file_selector_ios/test/file_selector_ios_test.dart.
+// Do not manually edit this file.
+
+// ignore_for_file: no_leading_underscores_for_library_prefixes
+import 'dart:async' as _i3;
+
+import 'package:file_selector_ios/src/messages.g.dart' as _i4;
+import 'package:mockito/mockito.dart' as _i1;
+
+import 'test_api.dart' as _i2;
+
+// ignore_for_file: type=lint
+// ignore_for_file: avoid_redundant_argument_values
+// ignore_for_file: avoid_setters_without_getters
+// ignore_for_file: comment_references
+// ignore_for_file: implementation_imports
+// ignore_for_file: invalid_use_of_visible_for_testing_member
+// ignore_for_file: prefer_const_constructors
+// ignore_for_file: unnecessary_parenthesis
+// ignore_for_file: camel_case_types
+// ignore_for_file: subtype_of_sealed_class
+
+/// A class which mocks [TestFileSelectorApi].
+///
+/// See the documentation for Mockito's code generation for more information.
+class MockTestFileSelectorApi extends _i1.Mock
+    implements _i2.TestFileSelectorApi {
+  MockTestFileSelectorApi() {
+    _i1.throwOnMissingStub(this);
+  }
+
+  @override
+  _i3.Future<List<String?>> openFile(_i4.FileSelectorConfig? config) =>
+      (super.noSuchMethod(Invocation.method(#openFile, [config]),
+              returnValue: _i3.Future<List<String?>>.value(<String?>[]))
+          as _i3.Future<List<String?>>);
+}
diff --git a/packages/file_selector/file_selector_ios/test/test_api.dart b/packages/file_selector/file_selector_ios/test/test_api.dart
new file mode 100644
index 0000000..69f6c19
--- /dev/null
+++ b/packages/file_selector/file_selector_ios/test/test_api.dart
@@ -0,0 +1,70 @@
+// 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.2.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, unnecessary_import
+// ignore_for_file: avoid_relative_lib_imports
+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';
+
+// This line has been hand-edited due to
+// https://github.com/flutter/flutter/issues/97744
+// ignore: directives_ordering
+import 'package:file_selector_ios/src/messages.g.dart';
+
+class _TestFileSelectorApiCodec extends StandardMessageCodec {
+  const _TestFileSelectorApiCodec();
+  @override
+  void writeValue(WriteBuffer buffer, Object? value) {
+    if (value is FileSelectorConfig) {
+      buffer.putUint8(128);
+      writeValue(buffer, value.encode());
+    } else {
+      super.writeValue(buffer, value);
+    }
+  }
+
+  @override
+  Object? readValueOfType(int type, ReadBuffer buffer) {
+    switch (type) {
+      case 128:
+        return FileSelectorConfig.decode(readValue(buffer)!);
+
+      default:
+        return super.readValueOfType(type, buffer);
+    }
+  }
+}
+
+abstract class TestFileSelectorApi {
+  static const MessageCodec<Object?> codec = _TestFileSelectorApiCodec();
+
+  Future<List<String?>> openFile(FileSelectorConfig config);
+  static void setup(TestFileSelectorApi? api,
+      {BinaryMessenger? binaryMessenger}) {
+    {
+      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
+          'dev.flutter.pigeon.FileSelectorApi.openFile', codec,
+          binaryMessenger: binaryMessenger);
+      if (api == null) {
+        channel.setMockMessageHandler(null);
+      } else {
+        channel.setMockMessageHandler((Object? message) async {
+          assert(message != null,
+              'Argument for dev.flutter.pigeon.FileSelectorApi.openFile was null.');
+          final List<Object?> args = (message as List<Object?>?)!;
+          final FileSelectorConfig? arg_config =
+              (args[0] as FileSelectorConfig?);
+          assert(arg_config != null,
+              'Argument for dev.flutter.pigeon.FileSelectorApi.openFile was null, expected non-null FileSelectorConfig.');
+          final List<String?> output = await api.openFile(arg_config!);
+          return <Object?, Object?>{'result': output};
+        });
+      }
+    }
+  }
+}
diff --git a/script/configs/exclude_integration_ios.yaml b/script/configs/exclude_integration_ios.yaml
index 06283ae..3df22b9 100644
--- a/script/configs/exclude_integration_ios.yaml
+++ b/script/configs/exclude_integration_ios.yaml
@@ -2,3 +2,5 @@
 - in_app_purchase_storekit
 # Currently missing: https://github.com/flutter/flutter/issues/82208
 - ios_platform_images
+# Can't use Flutter integration tests due to native modal UI.
+- file_selector_ios
\ No newline at end of file