Revert "Allow any iOS app to be added to an existing host app (#70647)" (#70739)

This reverts commit abdd65fc29d8d97cb2e057c2b50688d6e5baa88b.
diff --git a/dev/devicelab/bin/tasks/build_ios_framework_module_test.dart b/dev/devicelab/bin/tasks/build_ios_framework_module_test.dart
index d35ed54..cbd8b6d 100644
--- a/dev/devicelab/bin/tasks/build_ios_framework_module_test.dart
+++ b/dev/devicelab/bin/tasks/build_ios_framework_module_test.dart
@@ -17,439 +17,392 @@
     section('Create module project');
 
     final Directory tempDir = Directory.systemTemp.createTempSync('flutter_module_test.');
+    final Directory projectDir = Directory(path.join(tempDir.path, 'hello'));
     try {
       await inDirectory(tempDir, () async {
-        section('Test module template');
-
-        final Directory moduleProjectDir =
-            Directory(path.join(tempDir.path, 'hello_module'));
         await flutter(
           'create',
+          options: <String>['--org', 'io.flutter.devicelab', '--template', 'module', 'hello'],
+        );
+      });
+
+      section('Add plugins');
+
+      final File pubspec = File(path.join(projectDir.path, 'pubspec.yaml'));
+      String content = pubspec.readAsStringSync();
+      content = content.replaceFirst(
+        '\ndependencies:\n',
+        '\ndependencies:\n  device_info: 0.4.1\n  package_info: 0.4.0+9\n',
+      );
+      pubspec.writeAsStringSync(content, flush: true);
+      await inDirectory(projectDir, () async {
+        await flutter(
+          'packages',
+          options: <String>['get'],
+        );
+      });
+
+      // First, build the module in Debug to copy the debug version of Flutter.framework.
+      // This proves "flutter build ios-framework" re-copies the relevant Flutter.framework,
+      // otherwise building plugins with bitcode will fail linking because the debug version
+      // of Flutter.framework does not contain bitcode.
+      await inDirectory(projectDir, () async {
+        await flutter(
+          'build',
           options: <String>[
-            '--org',
-            'io.flutter.devicelab',
-            '--template',
-            'module',
-            'hello_module'
+            'ios',
+            '--debug',
+            '--no-codesign',
           ],
         );
+      });
 
-        await _testBuildIosFramework(moduleProjectDir, isModule: true);
+      // This builds all build modes' frameworks by default
+      section('Build frameworks');
 
-        section('Test app template');
+      const String outputDirectoryName = 'flutter-frameworks';
 
-        final Directory projectDir =
-            Directory(path.join(tempDir.path, 'hello_project'));
+      await inDirectory(projectDir, () async {
         await flutter(
-          'create',
-          options: <String>['--org', 'io.flutter.devicelab', 'hello_project'],
+          'build',
+          options: <String>[
+            'ios-framework',
+            '--universal',
+            '--output=$outputDirectoryName'
+          ],
+        );
+      });
+
+      final String outputPath = path.join(projectDir.path, outputDirectoryName);
+
+      section('Check debug build has Dart snapshot as asset');
+
+      checkFileExists(path.join(
+        outputPath,
+        'Debug',
+        'App.framework',
+        'flutter_assets',
+        'vm_snapshot_data',
+      ));
+
+      section('Check debug build has no Dart AOT');
+
+      // There's still an App.framework with a dylib, but it's empty.
+      checkFileExists(path.join(
+        outputPath,
+        'Debug',
+        'App.framework',
+        'App',
+      ));
+
+      final String debugAppFrameworkPath = path.join(
+        outputPath,
+        'Debug',
+        'App.framework',
+        'App',
+      );
+      final String aotSymbols = await dylibSymbols(debugAppFrameworkPath);
+
+      if (aotSymbols.contains('architecture') ||
+          aotSymbols.contains('_kDartVmSnapshot')) {
+        throw TaskResult.failure('Debug App.framework contains AOT');
+      }
+      await _checkFrameworkArchs(debugAppFrameworkPath, 'Debug');
+
+      // Xcode changed the name of this generated directory in Xcode 12.
+      const String xcode11ArmDirectoryName = 'ios-armv7_arm64';
+      const String xcode12ArmDirectoryName = 'ios-arm64_armv7';
+
+      final String xcode11AppFrameworkDirectory = path.join(
+        outputPath,
+        'Debug',
+        'App.xcframework',
+        xcode11ArmDirectoryName,
+        'App.framework',
+        'App',
+      );
+      final String xcode12AppFrameworkDirectory = path.join(
+        outputPath,
+        'Debug',
+        'App.xcframework',
+        xcode12ArmDirectoryName,
+        'App.framework',
+        'App',
+      );
+
+      // This seemed easier than an explicit Xcode version check.
+      String xcodeArmDirectoryName;
+      if (exists(File(xcode11AppFrameworkDirectory))) {
+        xcodeArmDirectoryName = xcode11ArmDirectoryName;
+      } else if (exists(File(xcode12AppFrameworkDirectory))) {
+        xcodeArmDirectoryName = xcode12ArmDirectoryName;
+      } else {
+        throw const FileSystemException('Expected App.framework binary to exist.');
+      }
+
+      checkFileExists(path.join(
+        outputPath,
+        'Debug',
+        'App.xcframework',
+        'ios-x86_64-simulator',
+        'App.framework',
+        'App',
+      ));
+
+      section('Check profile, release builds has Dart AOT dylib');
+
+      for (final String mode in <String>['Profile', 'Release']) {
+        final String appFrameworkPath = path.join(
+          outputPath,
+          mode,
+          'App.framework',
+          'App',
         );
 
-        await _testBuildIosFramework(projectDir);
+        await _checkFrameworkArchs(appFrameworkPath, mode);
+        await _checkBitcode(appFrameworkPath, mode);
+
+        final String aotSymbols = await dylibSymbols(appFrameworkPath);
+
+        if (!aotSymbols.contains('_kDartVmSnapshot')) {
+          throw TaskResult.failure('$mode App.framework missing Dart AOT');
+        }
+
+        checkFileNotExists(path.join(
+          outputPath,
+          mode,
+          'App.framework',
+          'flutter_assets',
+          'vm_snapshot_data',
+        ));
+
+        checkFileExists(path.join(
+          outputPath,
+          mode,
+          'App.xcframework',
+          xcodeArmDirectoryName,
+          'App.framework',
+          'App',
+        ));
+
+        checkFileNotExists(path.join(
+          outputPath,
+          mode,
+          'App.xcframework',
+          'ios-x86_64-simulator',
+          'App.framework',
+          'App',
+        ));
+      }
+
+      section("Check all modes' engine dylib");
+
+      for (final String mode in <String>['Debug', 'Profile', 'Release']) {
+        final String engineFrameworkPath = path.join(
+          outputPath,
+          mode,
+          'Flutter.framework',
+          'Flutter',
+        );
+
+        await _checkFrameworkArchs(engineFrameworkPath, mode);
+        await _checkBitcode(engineFrameworkPath, mode);
+
+        checkFileExists(path.join(
+          outputPath,
+          mode,
+          'Flutter.xcframework',
+          xcodeArmDirectoryName,
+          'Flutter.framework',
+          'Flutter',
+        ));
+        final String simulatorFrameworkPath = path.join(
+          outputPath,
+          mode,
+          'Flutter.xcframework',
+          'ios-x86_64-simulator',
+          'Flutter.framework',
+          'Flutter',
+        );
+        if (mode == 'Debug') {
+          checkFileExists(simulatorFrameworkPath);
+        } else {
+          checkFileNotExists(simulatorFrameworkPath);
+        }
+      }
+
+      section("Check all modes' engine header");
+
+      for (final String mode in <String>['Debug', 'Profile', 'Release']) {
+        checkFileExists(path.join(outputPath, mode, 'Flutter.framework', 'Headers', 'Flutter.h'));
+      }
+
+      section('Check all modes have plugins');
+
+      for (final String mode in <String>['Debug', 'Profile', 'Release']) {
+        final String pluginFrameworkPath = path.join(
+          outputPath,
+          mode,
+          'device_info.framework',
+          'device_info',
+        );
+        await _checkFrameworkArchs(pluginFrameworkPath, mode);
+        await _checkBitcode(pluginFrameworkPath, mode);
+
+        checkFileExists(path.join(
+          outputPath,
+          mode,
+          'device_info.xcframework',
+          xcodeArmDirectoryName,
+          'device_info.framework',
+          'device_info',
+        ));
+
+        checkFileExists(path.join(
+          outputPath,
+          mode,
+          'device_info.xcframework',
+          xcodeArmDirectoryName,
+          'device_info.framework',
+          'Headers',
+          'DeviceInfoPlugin.h',
+        ));
+
+        final String simulatorFrameworkPath = path.join(
+          outputPath,
+          mode,
+          'device_info.xcframework',
+          'ios-x86_64-simulator',
+          'device_info.framework',
+          'device_info',
+        );
+
+        final String simulatorFrameworkHeaderPath = path.join(
+          outputPath,
+          mode,
+          'device_info.xcframework',
+          'ios-x86_64-simulator',
+          'device_info.framework',
+          'Headers',
+          'DeviceInfoPlugin.h',
+        );
+
+        if (mode == 'Debug') {
+          checkFileExists(simulatorFrameworkPath);
+          checkFileExists(simulatorFrameworkHeaderPath);
+        } else {
+          checkFileNotExists(simulatorFrameworkPath);
+          checkFileNotExists(simulatorFrameworkHeaderPath);
+        }
+      }
+
+      section('Check all modes have generated plugin registrant');
+
+      for (final String mode in <String>['Debug', 'Profile', 'Release']) {
+        final String registrantFrameworkPath = path.join(
+          outputPath,
+          mode,
+          'FlutterPluginRegistrant.framework',
+          'FlutterPluginRegistrant'
+        );
+
+        await _checkFrameworkArchs(registrantFrameworkPath, mode);
+        await _checkBitcode(registrantFrameworkPath, mode);
+
+        checkFileExists(path.join(
+          outputPath,
+          mode,
+          'FlutterPluginRegistrant.framework',
+          'Headers',
+          'GeneratedPluginRegistrant.h',
+        ));
+        checkFileExists(path.join(
+          outputPath,
+          mode,
+          'FlutterPluginRegistrant.xcframework',
+          xcodeArmDirectoryName,
+          'FlutterPluginRegistrant.framework',
+          'Headers',
+          'GeneratedPluginRegistrant.h',
+        ));
+        final String simulatorHeaderPath = path.join(
+          outputPath,
+          mode,
+          'FlutterPluginRegistrant.xcframework',
+          'ios-x86_64-simulator',
+          'FlutterPluginRegistrant.framework',
+          'Headers',
+          'GeneratedPluginRegistrant.h',
+        );
+        if (mode == 'Debug') {
+          checkFileExists(simulatorHeaderPath);
+        } else {
+          checkFileNotExists(simulatorHeaderPath);
+        }
+      }
+
+      // This builds all build modes' frameworks by default
+      section('Build podspec');
+
+      const String cocoapodsOutputDirectoryName = 'flutter-frameworks-cocoapods';
+
+      await inDirectory(projectDir, () async {
+        await flutter(
+          'build',
+          options: <String>[
+            'ios-framework',
+            '--cocoapods',
+            '--universal',
+            '--force', // Allow podspec creation on master.
+            '--output=$cocoapodsOutputDirectoryName'
+          ],
+        );
       });
 
+      final String cocoapodsOutputPath = path.join(projectDir.path, cocoapodsOutputDirectoryName);
+      for (final String mode in <String>['Debug', 'Profile', 'Release']) {
+        checkFileExists(path.join(
+          cocoapodsOutputPath,
+          mode,
+          'Flutter.podspec',
+        ));
+
+        checkDirectoryExists(path.join(
+          cocoapodsOutputPath,
+          mode,
+          'App.framework',
+        ));
+
+        checkDirectoryExists(path.join(
+          cocoapodsOutputPath,
+          mode,
+          'FlutterPluginRegistrant.framework',
+        ));
+
+        checkDirectoryExists(path.join(
+          cocoapodsOutputPath,
+          mode,
+          'device_info.framework',
+        ));
+
+        checkDirectoryExists(path.join(
+          cocoapodsOutputPath,
+          mode,
+          'package_info.framework',
+        ));
+      }
+
       return TaskResult.success(null);
     } on TaskResult catch (taskResult) {
       return taskResult;
     } catch (e) {
       return TaskResult.failure(e.toString());
     } finally {
-      // rmTree(tempDir);
+      rmTree(tempDir);
     }
   });
 }
 
-Future<void> _testBuildIosFramework(Directory projectDir, { bool isModule = false}) async {
-  section('Add plugins');
-
-  final File pubspec = File(path.join(projectDir.path, 'pubspec.yaml'));
-  String content = pubspec.readAsStringSync();
-  content = content.replaceFirst(
-    '\ndependencies:\n',
-    '\ndependencies:\n  device_info: 0.4.1\n  package_info: 0.4.0+9\n',
-  );
-  pubspec.writeAsStringSync(content, flush: true);
-  await inDirectory(projectDir, () async {
-    await flutter(
-      'packages',
-      options: <String>['get'],
-    );
-  });
-
-  // First, build the module in Debug to copy the debug version of Flutter.framework.
-  // This proves "flutter build ios-framework" re-copies the relevant Flutter.framework,
-  // otherwise building plugins with bitcode will fail linking because the debug version
-  // of Flutter.framework does not contain bitcode.
-  await inDirectory(projectDir, () async {
-    await flutter(
-      'build',
-      options: <String>[
-        'ios',
-        '--debug',
-        '--no-codesign',
-      ],
-    );
-  });
-
-  // This builds all build modes' frameworks by default
-  section('Build frameworks');
-
-  const String outputDirectoryName = 'flutter-frameworks';
-
-  await inDirectory(projectDir, () async {
-    await flutter(
-      'build',
-      options: <String>[
-        'ios-framework',
-        '--universal',
-        '--output=$outputDirectoryName'
-      ],
-    );
-  });
-
-  final String outputPath = path.join(projectDir.path, outputDirectoryName);
-
-  section('Check debug build has Dart snapshot as asset');
-
-  checkFileExists(path.join(
-    outputPath,
-    'Debug',
-    'App.framework',
-    'flutter_assets',
-    'vm_snapshot_data',
-  ));
-
-  section('Check debug build has no Dart AOT');
-
-  // There's still an App.framework with a dylib, but it's empty.
-  checkFileExists(path.join(
-    outputPath,
-    'Debug',
-    'App.framework',
-    'App',
-  ));
-
-  final String debugAppFrameworkPath = path.join(
-    outputPath,
-    'Debug',
-    'App.framework',
-    'App',
-  );
-  final String aotSymbols = await dylibSymbols(debugAppFrameworkPath);
-
-  if (aotSymbols.contains('architecture') ||
-      aotSymbols.contains('_kDartVmSnapshot')) {
-    throw TaskResult.failure('Debug App.framework contains AOT');
-  }
-  await _checkFrameworkArchs(debugAppFrameworkPath, 'Debug');
-
-  // Xcode changed the name of this generated directory in Xcode 12.
-  const String xcode11ArmDirectoryName = 'ios-armv7_arm64';
-  const String xcode12ArmDirectoryName = 'ios-arm64_armv7';
-
-  final String xcode11AppFrameworkDirectory = path.join(
-    outputPath,
-    'Debug',
-    'App.xcframework',
-    xcode11ArmDirectoryName,
-    'App.framework',
-    'App',
-  );
-  final String xcode12AppFrameworkDirectory = path.join(
-    outputPath,
-    'Debug',
-    'App.xcframework',
-    xcode12ArmDirectoryName,
-    'App.framework',
-    'App',
-  );
-
-  // This seemed easier than an explicit Xcode version check.
-  String xcodeArmDirectoryName;
-  if (exists(File(xcode11AppFrameworkDirectory))) {
-    xcodeArmDirectoryName = xcode11ArmDirectoryName;
-  } else if (exists(File(xcode12AppFrameworkDirectory))) {
-    xcodeArmDirectoryName = xcode12ArmDirectoryName;
-  } else {
-    throw const FileSystemException('Expected App.framework binary to exist.');
-  }
-
-  checkFileExists(path.join(
-    outputPath,
-    'Debug',
-    'App.xcframework',
-    'ios-x86_64-simulator',
-    'App.framework',
-    'App',
-  ));
-
-  section('Check profile, release builds has Dart AOT dylib');
-
-  for (final String mode in <String>['Profile', 'Release']) {
-    final String appFrameworkPath = path.join(
-      outputPath,
-      mode,
-      'App.framework',
-      'App',
-    );
-
-    await _checkFrameworkArchs(appFrameworkPath, mode);
-    await _checkBitcode(appFrameworkPath, mode);
-
-    final String aotSymbols = await dylibSymbols(appFrameworkPath);
-
-    if (!aotSymbols.contains('_kDartVmSnapshot')) {
-      throw TaskResult.failure('$mode App.framework missing Dart AOT');
-    }
-
-    checkFileNotExists(path.join(
-      outputPath,
-      mode,
-      'App.framework',
-      'flutter_assets',
-      'vm_snapshot_data',
-    ));
-
-    checkFileExists(path.join(
-      outputPath,
-      mode,
-      'App.xcframework',
-      xcodeArmDirectoryName,
-      'App.framework',
-      'App',
-    ));
-
-    checkFileNotExists(path.join(
-      outputPath,
-      mode,
-      'App.xcframework',
-      'ios-x86_64-simulator',
-      'App.framework',
-      'App',
-    ));
-  }
-
-  section("Check all modes' engine dylib");
-
-  for (final String mode in <String>['Debug', 'Profile', 'Release']) {
-    final String engineFrameworkPath = path.join(
-      outputPath,
-      mode,
-      'Flutter.framework',
-      'Flutter',
-    );
-
-    await _checkFrameworkArchs(engineFrameworkPath, mode);
-    await _checkBitcode(engineFrameworkPath, mode);
-
-    checkFileExists(path.join(
-      outputPath,
-      mode,
-      'Flutter.xcframework',
-      xcodeArmDirectoryName,
-      'Flutter.framework',
-      'Flutter',
-    ));
-    final String simulatorFrameworkPath = path.join(
-      outputPath,
-      mode,
-      'Flutter.xcframework',
-      'ios-x86_64-simulator',
-      'Flutter.framework',
-      'Flutter',
-    );
-    if (mode == 'Debug') {
-      checkFileExists(simulatorFrameworkPath);
-    } else {
-      checkFileNotExists(simulatorFrameworkPath);
-    }
-  }
-
-  section("Check all modes' engine header");
-
-  for (final String mode in <String>['Debug', 'Profile', 'Release']) {
-    checkFileExists(path.join(outputPath, mode, 'Flutter.framework', 'Headers', 'Flutter.h'));
-  }
-
-  section('Check all modes have plugins');
-
-  for (final String mode in <String>['Debug', 'Profile', 'Release']) {
-    final String pluginFrameworkPath = path.join(
-      outputPath,
-      mode,
-      'device_info.framework',
-      'device_info',
-    );
-    await _checkFrameworkArchs(pluginFrameworkPath, mode);
-    await _checkBitcode(pluginFrameworkPath, mode);
-
-    checkFileExists(path.join(
-      outputPath,
-      mode,
-      'device_info.xcframework',
-      xcodeArmDirectoryName,
-      'device_info.framework',
-      'device_info',
-    ));
-
-    checkFileExists(path.join(
-      outputPath,
-      mode,
-      'device_info.xcframework',
-      xcodeArmDirectoryName,
-      'device_info.framework',
-      'Headers',
-      'DeviceInfoPlugin.h',
-    ));
-
-    final String simulatorFrameworkPath = path.join(
-      outputPath,
-      mode,
-      'device_info.xcframework',
-      'ios-x86_64-simulator',
-      'device_info.framework',
-      'device_info',
-    );
-
-    final String simulatorFrameworkHeaderPath = path.join(
-      outputPath,
-      mode,
-      'device_info.xcframework',
-      'ios-x86_64-simulator',
-      'device_info.framework',
-      'Headers',
-      'DeviceInfoPlugin.h',
-    );
-
-    if (mode == 'Debug') {
-      checkFileExists(simulatorFrameworkPath);
-      checkFileExists(simulatorFrameworkHeaderPath);
-    } else {
-      checkFileNotExists(simulatorFrameworkPath);
-      checkFileNotExists(simulatorFrameworkHeaderPath);
-    }
-  }
-
-  section('Check all modes have generated plugin registrant');
-
-  for (final String mode in <String>['Debug', 'Profile', 'Release']) {
-    if (!isModule) {
-      continue;
-    }
-    final String registrantFrameworkPath = path.join(
-      outputPath,
-      mode,
-      'FlutterPluginRegistrant.framework',
-      'FlutterPluginRegistrant'
-    );
-
-    await _checkFrameworkArchs(registrantFrameworkPath, mode);
-    await _checkBitcode(registrantFrameworkPath, mode);
-
-    checkFileExists(path.join(
-      outputPath,
-      mode,
-      'FlutterPluginRegistrant.framework',
-      'Headers',
-      'GeneratedPluginRegistrant.h',
-    ));
-    checkFileExists(path.join(
-      outputPath,
-      mode,
-      'FlutterPluginRegistrant.xcframework',
-      xcodeArmDirectoryName,
-      'FlutterPluginRegistrant.framework',
-      'Headers',
-      'GeneratedPluginRegistrant.h',
-    ));
-    final String simulatorHeaderPath = path.join(
-      outputPath,
-      mode,
-      'FlutterPluginRegistrant.xcframework',
-      'ios-x86_64-simulator',
-      'FlutterPluginRegistrant.framework',
-      'Headers',
-      'GeneratedPluginRegistrant.h',
-    );
-    if (mode == 'Debug') {
-      checkFileExists(simulatorHeaderPath);
-    } else {
-      checkFileNotExists(simulatorHeaderPath);
-    }
-  }
-
-  // This builds all build modes' frameworks by default
-  section('Build podspec');
-
-  const String cocoapodsOutputDirectoryName = 'flutter-frameworks-cocoapods';
-
-  await inDirectory(projectDir, () async {
-    await flutter(
-      'build',
-      options: <String>[
-        'ios-framework',
-        '--cocoapods',
-        '--universal',
-        '--force', // Allow podspec creation on master.
-        '--output=$cocoapodsOutputDirectoryName'
-      ],
-    );
-  });
-
-  final String cocoapodsOutputPath = path.join(projectDir.path, cocoapodsOutputDirectoryName);
-  for (final String mode in <String>['Debug', 'Profile', 'Release']) {
-    checkFileExists(path.join(
-      cocoapodsOutputPath,
-      mode,
-      'Flutter.podspec',
-    ));
-
-    checkDirectoryExists(path.join(
-      cocoapodsOutputPath,
-      mode,
-      'App.framework',
-    ));
-
-    if (Directory(path.join(
-          cocoapodsOutputPath,
-          mode,
-          'FlutterPluginRegistrant.framework',
-        )).existsSync() !=
-        isModule) {
-      throw TaskResult.failure(
-          'Unexpected FlutterPluginRegistrant.framework.');
-    }
-
-    checkDirectoryExists(path.join(
-      cocoapodsOutputPath,
-      mode,
-      'device_info.framework',
-    ));
-
-    checkDirectoryExists(path.join(
-      cocoapodsOutputPath,
-      mode,
-      'package_info.framework',
-    ));
-  }
-
-  if (File(path.join(
-        outputPath,
-        'GeneratedPluginRegistrant.h',
-      )).existsSync() ==
-      isModule) {
-    throw TaskResult.failure('Unexpected GeneratedPluginRegistrant.h.');
-  }
-
-  if (File(path.join(
-        outputPath,
-        'GeneratedPluginRegistrant.m',
-      )).existsSync() ==
-      isModule) {
-    throw TaskResult.failure('Unexpected GeneratedPluginRegistrant.m.');
-  }
-}
-
 Future<void> _checkFrameworkArchs(String frameworkPath, String mode) async {
   checkFileExists(frameworkPath);
 
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 1c73a36..48cfd18 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 .frameworks for a Flutter project '
+  final String description = 'Produces a .framework directory for a Flutter module '
       'and its plugins for integration into existing, plain Xcode projects.\n'
       'This can only be run on macOS hosts.';
 
@@ -144,6 +144,10 @@
   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.');
     }
@@ -174,7 +178,7 @@
     }
 
     if (!_project.ios.existsSync()) {
-      throwToolExit('Project does not support iOS');
+      throwToolExit('Module does not support iOS');
     }
 
     final Directory outputDirectory = globals.fs.directory(globals.fs.path.absolute(globals.fs.path.normalize(outputArgument)));
@@ -229,23 +233,6 @@
     }
 
     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();
   }
 
@@ -472,7 +459,6 @@
         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',
       ];
@@ -497,7 +483,6 @@
           '-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 3883862..543b0fa 100644
--- a/packages/flutter_tools/lib/src/plugins.dart
+++ b/packages/flutter_tools/lib/src/plugins.dart
@@ -897,24 +897,36 @@
     'framework': 'Flutter',
     'plugins': iosPlugins,
   };
+  final String registryDirectory = project.ios.pluginRegistrantHost.path;
   if (project.isModule) {
-    final String registryDirectory = project.ios.pluginRegistrantHost.path;
+    final String registryClassesDirectory = globals.fs.path.join(registryDirectory, 'Classes');
     _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 1ee6b9d..9e36c46 100644
--- a/packages/flutter_tools/lib/src/project.dart
+++ b/packages/flutter_tools/lib/src/project.dart
@@ -665,12 +665,15 @@
       )
     );
     if (framework.existsSync()) {
+      final Directory engineDest = ephemeralDirectory
+          .childDirectory('Flutter')
+          .childDirectory('engine');
       final File podspec = framework.parent.childFile('Flutter.podspec');
       globals.fsUtils.copyDirectorySync(
         framework,
-        engineCopyDirectory.childDirectory('Flutter.framework'),
+        engineDest.childDirectory('Flutter.framework'),
       );
-      podspec.copySync(engineCopyDirectory.childFile('Flutter.podspec').path);
+      podspec.copySync(engineDest.childFile('Flutter.podspec').path);
     }
   }
 
@@ -701,22 +704,6 @@
         : 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,