Revert "Revert "Allow any iOS app to be added to an existing host app (#70647)" (#70739)" (#70740)
This reverts commit aab9a76ee4cd97199e9d21118a0a3cfbda80b899.
diff --git a/packages/flutter_tools/lib/src/commands/build_ios_framework.dart b/packages/flutter_tools/lib/src/commands/build_ios_framework.dart
index 48cfd18..1c73a36 100644
--- a/packages/flutter_tools/lib/src/commands/build_ios_framework.dart
+++ b/packages/flutter_tools/lib/src/commands/build_ios_framework.dart
@@ -113,7 +113,7 @@
final String name = 'ios-framework';
@override
- final String description = 'Produces a .framework directory for a Flutter module '
+ final String description = 'Produces .frameworks for a Flutter project '
'and its plugins for integration into existing, plain Xcode projects.\n'
'This can only be run on macOS hosts.';
@@ -144,10 +144,6 @@
Future<void> validateCommand() async {
await super.validateCommand();
_project = FlutterProject.current();
- if (!_project.isModule) {
- throwToolExit('Building frameworks for iOS is only supported from a module.');
- }
-
if (!_platform.isMacOS) {
throwToolExit('Building frameworks for iOS is only supported on the Mac.');
}
@@ -178,7 +174,7 @@
}
if (!_project.ios.existsSync()) {
- throwToolExit('Module does not support iOS');
+ throwToolExit('Project does not support iOS');
}
final Directory outputDirectory = globals.fs.directory(globals.fs.path.absolute(globals.fs.path.normalize(outputArgument)));
@@ -233,6 +229,23 @@
}
globals.printStatus('Frameworks written to ${outputDirectory.path}.');
+
+ if (!_project.isModule && hasPlugins(_project)) {
+ // Apps do not generate a FlutterPluginRegistrant.framework. Users will need
+ // to copy the GeneratedPluginRegistrant class to their project manually.
+ final File pluginRegistrantHeader = _project.ios.pluginRegistrantHeader;
+ final File pluginRegistrantImplementation =
+ _project.ios.pluginRegistrantImplementation;
+ pluginRegistrantHeader.copySync(
+ outputDirectory.childFile(pluginRegistrantHeader.basename).path);
+ pluginRegistrantImplementation.copySync(outputDirectory
+ .childFile(pluginRegistrantImplementation.basename)
+ .path);
+ globals.printStatus(
+ '\nCopy the ${globals.fs.path.basenameWithoutExtension(pluginRegistrantHeader.path)} class into your project.\n'
+ 'See https://flutter.dev/docs/development/add-to-app/ios/add-flutter-screen#create-a-flutterengine for more information.');
+ }
+
return FlutterCommandResult.success();
}
@@ -459,6 +472,7 @@
xcodeBuildConfiguration,
'SYMROOT=${iPhoneBuildOutput.path}',
'BITCODE_GENERATION_MODE=$bitcodeGenerationMode',
+ 'ENABLE_BITCODE=YES', // Support host apps with bitcode enabled.
'ONLY_ACTIVE_ARCH=NO', // No device targeted, so build all valid architectures.
'BUILD_LIBRARY_FOR_DISTRIBUTION=YES',
];
@@ -483,6 +497,7 @@
'-configuration',
xcodeBuildConfiguration,
'SYMROOT=${simulatorBuildOutput.path}',
+ 'ENABLE_BITCODE=YES', // Support host apps with bitcode enabled.
'ARCHS=x86_64',
'ONLY_ACTIVE_ARCH=NO', // No device targeted, so build all valid architectures.
'BUILD_LIBRARY_FOR_DISTRIBUTION=YES',
diff --git a/packages/flutter_tools/lib/src/plugins.dart b/packages/flutter_tools/lib/src/plugins.dart
index 543b0fa..3883862 100644
--- a/packages/flutter_tools/lib/src/plugins.dart
+++ b/packages/flutter_tools/lib/src/plugins.dart
@@ -897,36 +897,24 @@
'framework': 'Flutter',
'plugins': iosPlugins,
};
- final String registryDirectory = project.ios.pluginRegistrantHost.path;
if (project.isModule) {
- final String registryClassesDirectory = globals.fs.path.join(registryDirectory, 'Classes');
+ final String registryDirectory = project.ios.pluginRegistrantHost.path;
_renderTemplateToFile(
_pluginRegistrantPodspecTemplate,
context,
globals.fs.path.join(registryDirectory, 'FlutterPluginRegistrant.podspec'),
);
- _renderTemplateToFile(
- _objcPluginRegistryHeaderTemplate,
- context,
- globals.fs.path.join(registryClassesDirectory, 'GeneratedPluginRegistrant.h'),
- );
- _renderTemplateToFile(
- _objcPluginRegistryImplementationTemplate,
- context,
- globals.fs.path.join(registryClassesDirectory, 'GeneratedPluginRegistrant.m'),
- );
- } else {
- _renderTemplateToFile(
- _objcPluginRegistryHeaderTemplate,
- context,
- globals.fs.path.join(registryDirectory, 'GeneratedPluginRegistrant.h'),
- );
- _renderTemplateToFile(
- _objcPluginRegistryImplementationTemplate,
- context,
- globals.fs.path.join(registryDirectory, 'GeneratedPluginRegistrant.m'),
- );
}
+ _renderTemplateToFile(
+ _objcPluginRegistryHeaderTemplate,
+ context,
+ project.ios.pluginRegistrantHeader.path,
+ );
+ _renderTemplateToFile(
+ _objcPluginRegistryImplementationTemplate,
+ context,
+ project.ios.pluginRegistrantImplementation.path,
+ );
}
/// The relative path from a project's main CMake file to the plugin symlink
diff --git a/packages/flutter_tools/lib/src/project.dart b/packages/flutter_tools/lib/src/project.dart
index 9e36c46..1ee6b9d 100644
--- a/packages/flutter_tools/lib/src/project.dart
+++ b/packages/flutter_tools/lib/src/project.dart
@@ -665,15 +665,12 @@
)
);
if (framework.existsSync()) {
- final Directory engineDest = ephemeralDirectory
- .childDirectory('Flutter')
- .childDirectory('engine');
final File podspec = framework.parent.childFile('Flutter.podspec');
globals.fsUtils.copyDirectorySync(
framework,
- engineDest.childDirectory('Flutter.framework'),
+ engineCopyDirectory.childDirectory('Flutter.framework'),
);
- podspec.copySync(engineDest.childFile('Flutter.podspec').path);
+ podspec.copySync(engineCopyDirectory.childFile('Flutter.podspec').path);
}
}
@@ -704,6 +701,22 @@
: hostAppRoot.childDirectory(_hostAppProjectName);
}
+ File get pluginRegistrantHeader {
+ final Directory registryDirectory = isModule ? pluginRegistrantHost.childDirectory('Classes') : pluginRegistrantHost;
+ return registryDirectory.childFile('GeneratedPluginRegistrant.h');
+ }
+
+ File get pluginRegistrantImplementation {
+ final Directory registryDirectory = isModule ? pluginRegistrantHost.childDirectory('Classes') : pluginRegistrantHost;
+ return registryDirectory.childFile('GeneratedPluginRegistrant.m');
+ }
+
+ Directory get engineCopyDirectory {
+ return isModule
+ ? ephemeralDirectory.childDirectory('Flutter').childDirectory('engine')
+ : hostAppRoot.childDirectory('Flutter');
+ }
+
Future<void> _overwriteFromTemplate(String path, Directory target) async {
final Template template = await Template.fromName(
path,