From aab9a76ee4cd97199e9d21118a0a3cfbda80b899 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Tue, 17 Nov 2020 21:40:28 -0800 Subject: [PATCH] Revert "Allow any iOS app to be added to an existing host app (#70647)" (#70739) This reverts commit abdd65fc29d8d97cb2e057c2b50688d6e5baa88b. --- .../build_ios_framework_module_test.dart | 769 ++++++++---------- .../lib/src/commands/build_ios_framework.dart | 27 +- packages/flutter_tools/lib/src/plugins.dart | 34 +- packages/flutter_tools/lib/src/project.dart | 23 +- 4 files changed, 395 insertions(+), 458 deletions(-) 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 d35ed54260..cbd8b6d86d 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 @@ Future main() async { 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: ['--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: ['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: [ - '--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: ['--org', 'io.flutter.devicelab', 'hello_project'], + 'build', + options: [ + '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 ['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 ['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 ['Debug', 'Profile', 'Release']) { + checkFileExists(path.join(outputPath, mode, 'Flutter.framework', 'Headers', 'Flutter.h')); + } + + section('Check all modes have plugins'); + + for (final String mode in ['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 ['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: [ + '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 ['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 _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: ['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: [ - '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: [ - '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 ['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 ['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 ['Debug', 'Profile', 'Release']) { - checkFileExists(path.join(outputPath, mode, 'Flutter.framework', 'Headers', 'Flutter.h')); - } - - section('Check all modes have plugins'); - - for (final String mode in ['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 ['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: [ - '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 ['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 _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 1c73a36281..48cfd18b2a 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 @@ class BuildIOSFrameworkCommand extends BuildSubCommand { 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 @@ class BuildIOSFrameworkCommand extends BuildSubCommand { Future 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 @@ class BuildIOSFrameworkCommand extends BuildSubCommand { } 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 @@ class BuildIOSFrameworkCommand extends BuildSubCommand { } 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 @@ end 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 @@ end '-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 38838627f6..543b0fa801 100644 --- a/packages/flutter_tools/lib/src/plugins.dart +++ b/packages/flutter_tools/lib/src/plugins.dart @@ -897,24 +897,36 @@ Future _writeIOSPluginRegistrant(FlutterProject project, List plug '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 1ee6b9d638..9e36c46f72 100644 --- a/packages/flutter_tools/lib/src/project.dart +++ b/packages/flutter_tools/lib/src/project.dart @@ -665,12 +665,15 @@ class IosProject extends FlutterProjectPlatform implements XcodeBasedProject { ) ); 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 @@ class IosProject extends FlutterProjectPlatform implements XcodeBasedProject { : 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 _overwriteFromTemplate(String path, Directory target) async { final Template template = await Template.fromName( path,