Embed Flutter and App frameworks for add-to-app on iOS (#102538)

diff --git a/dev/devicelab/bin/tasks/module_test_ios.dart b/dev/devicelab/bin/tasks/module_test_ios.dart
index 832647f..7c43b71 100644
--- a/dev/devicelab/bin/tasks/module_test_ios.dart
+++ b/dev/devicelab/bin/tasks/module_test_ios.dart
@@ -59,7 +59,8 @@
         );
       });
 
-      checkDirectoryExists(path.join(projectDir.path, '.ios', 'Flutter', 'engine', 'Flutter.xcframework'));
+      // Check the tool is no longer copying to the legacy xcframework location.
+      checkDirectoryNotExists(path.join(projectDir.path, '.ios', 'Flutter', 'engine', 'Flutter.xcframework'));
 
       final Directory ephemeralIOSHostApp = Directory(path.join(
         projectDir.path,
@@ -79,32 +80,6 @@
         );
       }
 
-      section('Build ephemeral host app when SDK is on external disk');
-
-      // Pretend the SDK was on an external drive with stray "._" files in the xcframework
-      // and build again.
-      Directory(path.join(
-        projectDir.path,
-        '.ios',
-        'Flutter',
-        'engine',
-        'Flutter.xcframework',
-        '._ios-arm64_x86_64-simulator',
-      )).createSync(recursive: true);
-
-      await inDirectory(projectDir, () async {
-        await flutter(
-          'build',
-          options: <String>['ios', '--no-codesign', '--simulator', '--debug'],
-        );
-      });
-
-      section('Clean build');
-
-      await inDirectory(projectDir, () async {
-        await flutter('clean');
-      });
-
       section('Build ephemeral host app in profile mode without CocoaPods');
 
       await inDirectory(projectDir, () async {
@@ -114,8 +89,6 @@
         );
       });
 
-      checkDirectoryExists(path.join(projectDir.path, '.ios', 'Flutter', 'engine', 'Flutter.xcframework'));
-
       if (!exists(ephemeralIOSHostApp)) {
         return TaskResult.failure('Failed to build ephemeral host .app');
       }
@@ -211,7 +184,6 @@
           options: <String>['ios', '--no-codesign', '-v'],
         );
       });
-      checkDirectoryExists(path.join(projectDir.path, '.ios', 'Flutter', 'engine', 'Flutter.xcframework'));
 
       final bool ephemeralHostAppWithCocoaPodsBuilt = exists(ephemeralIOSHostApp);
 
@@ -265,8 +237,6 @@
       final File objectiveCAnalyticsOutputFile = File(path.join(tempDir.path, 'analytics-objc.log'));
       final Directory objectiveCBuildDirectory = Directory(path.join(tempDir.path, 'build-objc'));
 
-      final File dummyAppFramework = File(path.join(projectDir.path, '.ios', 'Flutter', 'App.framework', 'App'));
-      checkFileNotExists(dummyAppFramework.path);
       await inDirectory(objectiveCHostApp, () async {
         section('Validate iOS Objective-C host app Podfile');
 
@@ -305,7 +275,7 @@
 
         final File hostPodfileLockFile = File(path.join(objectiveCHostApp.path, 'Podfile.lock'));
         final String hostPodfileLockOutput = hostPodfileLockFile.readAsStringSync();
-        if (!hostPodfileLockOutput.contains(':path: "../hello/.ios/Flutter/engine"')
+        if (!hostPodfileLockOutput.contains(':path: "../hello/.ios/Flutter"')
             || !hostPodfileLockOutput.contains(':path: "../hello/.ios/Flutter/FlutterPluginRegistrant"')
             || !hostPodfileLockOutput.contains(':path: "../hello/.ios/.symlinks/plugins/url_launcher_ios/ios"')
             || !hostPodfileLockOutput.contains(':path: "../hello/.ios/.symlinks/plugins/google_sign_in/ios"')
@@ -315,13 +285,9 @@
           throw TaskResult.failure('Building host app Podfile.lock does not contain expected pods');
         }
 
-        // Just running "pod install" should create a fake App.framework so CocoaPods recognizes
-        // it as a framework that needs to be embedded, before Flutter actually creates it.
-        checkFileExists(dummyAppFramework.path);
-        final String? version = await minPhoneOSVersion(dummyAppFramework.path);
-        if (version != '11.0') {
-          throw TaskResult.failure('Minimum version set to $version, expected 11.0');
-        }
+        // Check the tool is no longer copying to the legacy App.framework location.
+        final File dummyAppFramework = File(path.join(projectDir.path, '.ios', 'Flutter', 'App.framework', 'App'));
+        checkFileNotExists(dummyAppFramework.path);
 
         section('Build iOS Objective-C host app');
 
diff --git a/packages/flutter_tools/bin/podhelper.rb b/packages/flutter_tools/bin/podhelper.rb
index c3798c6..49a3c5b 100644
--- a/packages/flutter_tools/bin/podhelper.rb
+++ b/packages/flutter_tools/bin/podhelper.rb
@@ -161,7 +161,8 @@
   ios_application_path ||= File.dirname(defined_in_file.realpath) if self.respond_to?(:defined_in_file)
   raise 'Could not find iOS application path' unless ios_application_path
 
-  copied_podspec_path = File.expand_path('Flutter.podspec', File.join(ios_application_path, 'Flutter'))
+  podspec_directory = File.join(ios_application_path, 'Flutter')
+  copied_podspec_path = File.expand_path('Flutter.podspec', podspec_directory)
 
   # Generate a fake podspec to represent the Flutter framework.
   # This is only necessary because plugin podspecs contain `s.dependency 'Flutter'`, and if this Podfile
@@ -190,7 +191,7 @@
   }
 
   # Keep pod path relative so it can be checked into Podfile.lock.
-  pod 'Flutter', :path => 'Flutter'
+  pod 'Flutter', :path => flutter_relative_path_from_podfile(podspec_directory)
 end
 
 # Same as flutter_install_ios_engine_pod for macOS.
@@ -260,7 +261,9 @@
       File.symlink(plugin_path, symlink)
 
       # Keep pod path relative so it can be checked into Podfile.lock.
-      pod plugin_name, :path => File.join(relative_symlink_dir, 'plugins', plugin_name, platform)
+      relative = flutter_relative_path_from_podfile(symlink)
+
+      pod plugin_name, :path => File.join(relative, platform)
     end
   end
 end
@@ -279,3 +282,12 @@
   return [] unless dependencies_hash['plugins'].has_key?('ios')
   dependencies_hash['plugins'][platform] || []
 end
+
+def flutter_relative_path_from_podfile(path)
+  # defined_in_file is set by CocoaPods and is a Pathname to the Podfile.
+  project_directory_pathname = defined_in_file.dirname
+
+  pathname = Pathname.new File.expand_path(path)
+  relative = pathname.relative_path_from project_directory_pathname
+  relative.to_s
+end
diff --git a/packages/flutter_tools/bin/xcode_backend.dart b/packages/flutter_tools/bin/xcode_backend.dart
index a0df456..a93fd41 100644
--- a/packages/flutter_tools/bin/xcode_backend.dart
+++ b/packages/flutter_tools/bin/xcode_backend.dart
@@ -321,28 +321,7 @@
       targetPath = environment['FLUTTER_TARGET']!;
     }
 
-    String derivedDir = '$sourceRoot/Flutter}';
-    if (existsDir('$projectPath/.ios')) {
-      derivedDir = '$projectPath/.ios/Flutter';
-    }
-
-    // Use FLUTTER_BUILD_MODE if it's set, otherwise use the Xcode build configuration name
-    // This means that if someone wants to use an Xcode build config other than Debug/Profile/Release,
-    // they _must_ set FLUTTER_BUILD_MODE so we know what type of artifact to build.
-
     final String buildMode = parseFlutterBuildMode();
-    String artifactVariant = 'unknown';
-    switch (buildMode) {
-      case 'release':
-        artifactVariant = 'ios-release';
-        break;
-      case 'profile':
-        artifactVariant = 'ios-profile';
-        break;
-      case 'debug':
-        artifactVariant = 'ios';
-        break;
-    }
 
     // Warn the user if not archiving (ACTION=install) in release mode.
     final String? action = environment['ACTION'];
@@ -353,47 +332,12 @@
         '--release", then re-run Archive from Xcode.',
       );
     }
-    final String frameworkPath = '${environmentEnsure('FLUTTER_ROOT')}/bin/cache/artifacts/engine/$artifactVariant';
 
-    String flutterFramework = '$frameworkPath/Flutter.xcframework';
-
-    final String? localEngine = environment['LOCAL_ENGINE'];
-    if (localEngine != null) {
-      if (!localEngine.toLowerCase().contains(buildMode)) {
-        echoError('========================================================================');
-        echoError("ERROR: Requested build with Flutter local engine at '$localEngine'");
-        echoError("This engine is not compatible with FLUTTER_BUILD_MODE: '$buildMode'.");
-        echoError('You can fix this by updating the LOCAL_ENGINE environment variable, or');
-        echoError('by running:');
-        echoError('  flutter build ios --local-engine=ios_$buildMode');
-        echoError('or');
-        echoError('  flutter build ios --local-engine=ios_${buildMode}_unopt');
-        echoError('========================================================================');
-        exitApp(-1);
-      }
-      flutterFramework = '${environmentEnsure('FLUTTER_ENGINE')}/out/$localEngine/Flutter.xcframework';
-    }
     String bitcodeFlag = '';
     if (environment['ENABLE_BITCODE'] == 'YES' && environment['ACTION'] == 'install') {
       bitcodeFlag = 'true';
     }
 
-    // TODO(jmagman): use assemble copied engine in add-to-app.
-    if (existsDir('$projectPath/.ios')) {
-      runSync(
-        'rsync',
-        <String>[
-          '-av',
-          '--delete',
-          '--filter',
-          '- .DS_Store',
-          flutterFramework,
-          '$derivedDir/engine',
-        ],
-        verbose: verbose,
-      );
-    }
-
     final List<String> flutterArgs = <String>[];
 
     if (verbose) {
diff --git a/packages/flutter_tools/lib/src/xcode_project.dart b/packages/flutter_tools/lib/src/xcode_project.dart
index 6faec24..0a375a7 100644
--- a/packages/flutter_tools/lib/src/xcode_project.dart
+++ b/packages/flutter_tools/lib/src/xcode_project.dart
@@ -2,7 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-import 'artifacts.dart';
 import 'base/error_handling_io.dart';
 import 'base/file_system.dart';
 import 'base/utils.dart';
@@ -399,29 +398,6 @@
           ephemeralModuleDirectory,
         );
       }
-      // Use release mode so host project can link on bitcode variant.
-      _copyEngineArtifactToProject(BuildMode.release, EnvironmentType.physical);
-    }
-  }
-
-  void _copyEngineArtifactToProject(BuildMode mode, EnvironmentType environmentType) {
-    // Copy framework from engine cache. The actual build mode
-    // doesn't actually matter as it will be overwritten by xcode_backend.sh.
-    // However, cocoapods will run before that script and requires something
-    // to be in this location.
-    final Directory framework = globals.fs.directory(
-      globals.artifacts?.getArtifactPath(
-        Artifact.flutterXcframework,
-        platform: TargetPlatform.ios,
-        mode: mode,
-        environmentType: environmentType,
-      )
-    );
-    if (framework.existsSync()) {
-      copyDirectory(
-        framework,
-        engineCopyDirectory.childDirectory('Flutter.xcframework'),
-      );
     }
   }
 
@@ -467,12 +443,6 @@
     return registryDirectory.childFile('GeneratedPluginRegistrant.m');
   }
 
-  Directory get engineCopyDirectory {
-    return isModule
-        ? ephemeralModuleDirectory.childDirectory('Flutter').childDirectory('engine')
-        : hostAppRoot.childDirectory('Flutter');
-  }
-
   Future<void> _overwriteFromTemplate(String path, Directory target) async {
     final Template template = await Template.fromName(
       path,
diff --git a/packages/flutter_tools/templates/module/ios/host_app_ephemeral/Flutter/engine/Flutter.podspec.tmpl b/packages/flutter_tools/templates/module/ios/host_app_ephemeral/Flutter/engine/Flutter.podspec.tmpl
deleted file mode 100644
index 9af7295..0000000
--- a/packages/flutter_tools/templates/module/ios/host_app_ephemeral/Flutter/engine/Flutter.podspec.tmpl
+++ /dev/null
@@ -1,20 +0,0 @@
-#
-# NOTE: This podspec is NOT to be published. It is only used as a local source!
-#
-
-Pod::Spec.new do |s|
-  s.name             = 'Flutter'
-  s.version          = '1.0.0'
-  s.summary          = 'A UI toolkit for beautiful and fast apps.'
-  s.description      = <<-DESC
-Flutter is Google's UI toolkit for building beautiful, fast apps for mobile, web, desktop, and embedded devices from a single codebase.
-This pod vends the iOS Flutter engine framework. It is compatible with application frameworks created with this version of the engine and tools.
-                       DESC
-  s.homepage         = 'https://flutter.dev'
-  s.license          = 'BSD'
-  s.author           = { 'Flutter Dev Team' => 'flutter-dev@googlegroups.com' }
-  s.source           = { :git => 'https://github.com/flutter/engine', :tag => s.version.to_s }
-  s.documentation_url     = 'https://flutter.dev/docs'
-  s.ios.deployment_target = '11.0'
-  s.vendored_frameworks = 'Flutter.xcframework'
-end
diff --git a/packages/flutter_tools/templates/module/ios/library/Flutter.tmpl/podhelper.rb.tmpl b/packages/flutter_tools/templates/module/ios/library/Flutter.tmpl/podhelper.rb.tmpl
index 0360932..ff895ae 100644
--- a/packages/flutter_tools/templates/module/ios/library/Flutter.tmpl/podhelper.rb.tmpl
+++ b/packages/flutter_tools/templates/module/ios/library/Flutter.tmpl/podhelper.rb.tmpl
@@ -31,7 +31,7 @@
   require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)
 
   flutter_application_path ||= File.join('..', '..')
-  install_flutter_engine_pod
+  install_flutter_engine_pod(flutter_application_path)
   install_flutter_plugin_pods(flutter_application_path)
   install_flutter_application_pod(flutter_application_path)
 end
@@ -42,30 +42,12 @@
 #   target 'MyApp' do
 #     install_flutter_engine_pod
 #   end
-def install_flutter_engine_pod
-  current_directory = File.expand_path('..', __FILE__)
-  engine_dir = File.expand_path('engine', current_directory)
-  framework_name = 'Flutter.xcframework'
-  copied_engine = File.expand_path(framework_name, engine_dir)
-  if !File.exist?(copied_engine)
-    # Copy the debug engine to have something to link against if the xcode backend script has not run yet.
-    # CocoaPods will not embed the framework on pod install (before any build phases can generate) if the dylib does not exist.
-    release_framework_dir = File.join(flutter_root, 'bin', 'cache', 'artifacts', 'engine', 'ios-release')
-    unless Dir.exist?(release_framework_dir)
-      # iOS artifacts have not been downloaded.
-      raise "#{release_framework_dir} must exist. Make sure \"flutter precache --ios\" has been run at least once"
-    end
-    FileUtils.cp_r(File.join(release_framework_dir, framework_name), engine_dir)
-  end
+def install_flutter_engine_pod(flutter_application_path = nil)
+  flutter_application_path ||= File.join('..', '..')
+  ios_application_path = File.join(flutter_application_path, '.ios')
 
-  # Keep pod path relative so it can be checked into Podfile.lock.
-  # Process will be run from project directory.
-  engine_pathname = Pathname.new engine_dir
-  # defined_in_file is a Pathname to the Podfile set by CocoaPods.
-  project_directory_pathname = defined_in_file.dirname
-  relative = engine_pathname.relative_path_from project_directory_pathname
-
-  pod 'Flutter', :path => relative.to_s, :inhibit_warnings => true
+  # flutter_install_ios_engine_pod is in Flutter root podhelper.rb
+  flutter_install_ios_engine_pod(ios_application_path)
 end
 
 # Install Flutter plugin pods.
@@ -79,33 +61,13 @@
 #                                          MyApp/my_flutter/.ios/Flutter/../..
 def install_flutter_plugin_pods(flutter_application_path)
   flutter_application_path ||= File.join('..', '..')
+  ios_application_path = File.join(flutter_application_path, '.ios')
+  # flutter_install_plugin_pods is in Flutter root podhelper.rb
+  flutter_install_plugin_pods(ios_application_path, '.symlinks', 'ios')
 
   # Keep pod path relative so it can be checked into Podfile.lock.
-  # Process will be run from project directory.
-  ios_project_directory_pathname = Pathname.new File.expand_path(File.join('..', '..'), __FILE__)
-  # defined_in_file is set by CocoaPods and is a Pathname to the Podfile.
-  project_directory_pathname = defined_in_file.dirname
-  relative = ios_project_directory_pathname.relative_path_from project_directory_pathname
+  relative = flutter_relative_path_from_podfile(ios_application_path)
   pod 'FlutterPluginRegistrant', :path => File.join(relative, 'Flutter', 'FlutterPluginRegistrant'), :inhibit_warnings => true
-
-  symlinks_dir = File.join(relative, '.symlinks', 'plugins')
-  FileUtils.mkdir_p(symlinks_dir)
-
-  plugins_file = File.expand_path('.flutter-plugins-dependencies', flutter_application_path)
-
-  # flutter_parse_plugins_file is in Flutter root podhelper.rb
-  plugin_pods = flutter_parse_plugins_file(plugins_file, 'ios')
-  plugin_pods.each do |plugin_hash|
-    plugin_name = plugin_hash['name']
-    plugin_path = plugin_hash['path']
-    has_native_build = plugin_hash.fetch('native_build', true)
-    if (plugin_name && plugin_path && has_native_build)
-      symlink = File.join(symlinks_dir, plugin_name)
-      FileUtils.rm_f(symlink)
-      File.symlink(plugin_path, symlink)
-      pod plugin_name, :path => File.join(symlink, 'ios'), :inhibit_warnings => true
-    end
-  end
 end
 
 # Install Flutter application pod.
@@ -118,30 +80,24 @@
 #                                          Optional, defaults to two levels up from the directory of this script.
 #                                          MyApp/my_flutter/.ios/Flutter/../..
 def install_flutter_application_pod(flutter_application_path)
-  current_directory_pathname = Pathname.new File.expand_path('..', __FILE__)
-  app_framework_dir = File.expand_path('App.framework', current_directory_pathname.to_path)
-  app_framework_dylib = File.join(app_framework_dir, 'App')
-  if !File.exist?(app_framework_dylib)
-    # Fake an App.framework to have something to link against if the xcode backend script has not run yet.
-    # CocoaPods will not embed the framework on pod install (before any build phases can run) if the dylib does not exist.
-    # Create a dummy dylib.
-    FileUtils.mkdir_p(app_framework_dir)
-    sdk_path = `xcrun --sdk iphoneos --show-sdk-path`.strip
-    `echo "static const int Moo = 88;" | xcrun clang -x c -arch arm64 -dynamiclib -miphoneos-version-min=11.0 -isysroot "#{sdk_path}" -o "#{app_framework_dylib}" -`
-  end
+  flutter_application_path ||= File.join('..', '..')
 
-  # Keep pod and script phase paths relative so they can be checked into source control.
-  # Process will be run from project directory.
+  export_script_directory = File.join(flutter_application_path, '.ios', 'Flutter')
 
-  # defined_in_file is set by CocoaPods and is a Pathname to the Podfile.
-  project_directory_pathname = defined_in_file.dirname
-  relative = current_directory_pathname.relative_path_from project_directory_pathname
-  pod '{{projectName}}', :path => relative.to_s, :inhibit_warnings => true
+  # Keep script phase paths relative so they can be checked into source control.
+  relative = flutter_relative_path_from_podfile(export_script_directory)
 
   flutter_export_environment_path = File.join('${SRCROOT}', relative, 'flutter_export_environment.sh');
+
+  # Compile App.framework and move it and Flutter.framework to "BUILT_PRODUCTS_DIR"
   script_phase :name => 'Run Flutter Build {{projectName}} Script',
     :script => "set -e\nset -u\nsource \"#{flutter_export_environment_path}\"\nexport VERBOSE_SCRIPT_LOGGING=1 && \"$FLUTTER_ROOT\"/packages/flutter_tools/bin/xcode_backend.sh build",
     :execution_position => :before_compile
+
+  # Embed App.framework AND Flutter.framework.
+  script_phase :name => 'Embed Flutter Build {{projectName}} Script',
+    :script => "set -e\nset -u\nsource \"#{flutter_export_environment_path}\"\nexport VERBOSE_SCRIPT_LOGGING=1 && \"$FLUTTER_ROOT\"/packages/flutter_tools/bin/xcode_backend.sh embed_and_thin",
+    :execution_position => :after_compile
 end
 
 def flutter_root
diff --git a/packages/flutter_tools/templates/module/ios/library/Flutter.tmpl/projectName.podspec.tmpl b/packages/flutter_tools/templates/module/ios/library/Flutter.tmpl/projectName.podspec.tmpl
deleted file mode 100644
index c9f6cd5..0000000
--- a/packages/flutter_tools/templates/module/ios/library/Flutter.tmpl/projectName.podspec.tmpl
+++ /dev/null
@@ -1,13 +0,0 @@
-Pod::Spec.new do |s|
-  s.name                  = '{{projectName}}'
-  s.version               = '0.0.1'
-  s.summary               = 'Flutter module'
-  s.description           = 'Flutter module - {{projectName}}'
-  s.homepage              = 'https://flutter.dev'
-  s.license               = { :type => 'BSD' }
-  s.author                = { 'Flutter Dev Team' => 'flutter-dev@googlegroups.com' }
-  s.source                = { :path => '.' }
-  s.ios.deployment_target = '11.0'
-  s.vendored_frameworks   = 'App.framework'
-  s.dependency 'Flutter'
-end
diff --git a/packages/flutter_tools/templates/template_manifest.json b/packages/flutter_tools/templates/template_manifest.json
index fe0c148..edf9c0c 100644
--- a/packages/flutter_tools/templates/template_manifest.json
+++ b/packages/flutter_tools/templates/template_manifest.json
@@ -186,7 +186,6 @@
         "templates/module/ios/host_app_ephemeral/Config.tmpl/Debug.xcconfig",
         "templates/module/ios/host_app_ephemeral/Config.tmpl/Flutter.xcconfig",
         "templates/module/ios/host_app_ephemeral/Config.tmpl/Release.xcconfig",
-        "templates/module/ios/host_app_ephemeral/Flutter/engine/Flutter.podspec.tmpl",
         "templates/module/ios/host_app_ephemeral/Runner.tmpl/AppDelegate.h",
         "templates/module/ios/host_app_ephemeral/Runner.tmpl/AppDelegate.m",
         "templates/module/ios/host_app_ephemeral/Runner.tmpl/Assets.xcassets/AppIcon.appiconset/Contents.json",
@@ -228,7 +227,6 @@
         "templates/module/ios/host_app_ephemeral_cocoapods/Runner.tmpl/AppDelegate.m",
         "templates/module/ios/library/Flutter.tmpl/AppFrameworkInfo.plist",
         "templates/module/ios/library/Flutter.tmpl/podhelper.rb.tmpl",
-        "templates/module/ios/library/Flutter.tmpl/projectName.podspec.tmpl",
         "templates/module/ios/library/Flutter.tmpl/README.md",
         "templates/module/README.md",
 
diff --git a/packages/flutter_tools/test/commands.shard/permeable/create_test.dart b/packages/flutter_tools/test/commands.shard/permeable/create_test.dart
index fe69d00..4848f87 100644
--- a/packages/flutter_tools/test/commands.shard/permeable/create_test.dart
+++ b/packages/flutter_tools/test/commands.shard/permeable/create_test.dart
@@ -222,8 +222,6 @@
       '.android/app/',
       '.gitignore',
       '.ios/Flutter',
-      '.ios/Flutter/flutter_project.podspec',
-      '.ios/Flutter/engine/Flutter.podspec',
       '.metadata',
       'analysis_options.yaml',
       'lib/main.dart',
@@ -1163,13 +1161,6 @@
     // Do not override host app build settings.
     expect(buildPhaseScript, isNot(contains('SYMROOT')));
 
-    // Generated podspec
-    final String podspecPath = globals.fs.path.join('.ios', 'Flutter', 'flutter_project.podspec');
-    expectExists(podspecPath);
-    final File podspecFile = globals.fs.file(globals.fs.path.join(projectDir.path, podspecPath));
-    final String podspec = podspecFile.readAsStringSync();
-    expect(podspec, contains('Flutter module - flutter_project'));
-
     // App identification
     final String xcodeProjectPath = globals.fs.path.join('.ios', 'Runner.xcodeproj', 'project.pbxproj');
     expectExists(xcodeProjectPath);
diff --git a/packages/flutter_tools/test/general.shard/project_test.dart b/packages/flutter_tools/test/general.shard/project_test.dart
index 66478c7..3068cb0 100644
--- a/packages/flutter_tools/test/general.shard/project_test.dart
+++ b/packages/flutter_tools/test/general.shard/project_test.dart
@@ -318,7 +318,6 @@
         final Directory flutter = project.ios.hostAppRoot.childDirectory('Flutter');
         expectExists(flutter.childFile('podhelper.rb'));
         expectExists(flutter.childFile('flutter_export_environment.sh'));
-        expectExists(flutter.childFile('${project.manifest.appName}.podspec'));
         expectExists(flutter.childFile('Generated.xcconfig'));
         final Directory pluginRegistrantClasses = flutter
             .childDirectory('FlutterPluginRegistrant')
diff --git a/packages/flutter_tools/test/integration.shard/xcode_backend_test.dart b/packages/flutter_tools/test/integration.shard/xcode_backend_test.dart
index c0fe24d..e9ef0fa 100644
--- a/packages/flutter_tools/test/integration.shard/xcode_backend_test.dart
+++ b/packages/flutter_tools/test/integration.shard/xcode_backend_test.dart
@@ -26,23 +26,6 @@
   'CONFIGURATION': 'Debug',
 };
 
-// Can't use a debug engine build with a release build.
-const Map<String, String> localEngineDebugBuildModeRelease = <String, String>{
-  'SOURCE_ROOT': '../examples/hello_world',
-  'FLUTTER_ROOT': '../..',
-  'LOCAL_ENGINE': '/engine/src/out/ios_debug_unopt',
-  'CONFIGURATION': 'Release',
-};
-
-// Can't use a debug build with a profile engine.
-const Map<String, String> localEngineProfileBuildModeRelease = <String, String>{
-  'SOURCE_ROOT': '../examples/hello_world',
-  'FLUTTER_ROOT': '../..',
-  'LOCAL_ENGINE': '/engine/src/out/ios_profile',
-  'CONFIGURATION': 'Debug',
-  'FLUTTER_BUILD_MODE': 'Debug',
-};
-
 void main() {
   Future<void> expectXcodeBackendFails(Map<String, String> environment) async {
     final ProcessResult result = await Process.run(
@@ -70,8 +53,6 @@
   test('Xcode backend fails for on unsupported configuration combinations', () async {
     await expectXcodeBackendFails(unknownConfiguration);
     await expectXcodeBackendFails(unknownFlutterBuildMode);
-    await expectXcodeBackendFails(localEngineDebugBuildModeRelease);
-    await expectXcodeBackendFails(localEngineProfileBuildModeRelease);
   }, skip: !io.Platform.isMacOS); // [intended] requires macos toolchain.
 
   test('Xcode backend warns archiving a non-release build.', () async {