From 856a90e67c9284124d44d2be6c785bacd3a1c772 Mon Sep 17 00:00:00 2001 From: Jenn Magder Date: Fri, 8 Nov 2019 18:00:01 -0800 Subject: [PATCH] Add swift_versions to plugin template podspec, include default CocoaPod version (#44324) --- dev/devicelab/bin/tasks/plugin_lint_mac.dart | 142 +++++++++++++++++- .../projectName.podspec.tmpl | 0 .../ios-swift.tmpl/Classes/pluginClass.m.tmpl | 7 + .../ios-swift.tmpl/projectName.podspec.tmpl | 23 +++ .../macos.tmpl/projectName.podspec.tmpl | 1 + 5 files changed, 169 insertions(+), 4 deletions(-) rename packages/flutter_tools/templates/plugin/{ios.tmpl => ios-objc.tmpl}/projectName.podspec.tmpl (100%) create mode 100644 packages/flutter_tools/templates/plugin/ios-swift.tmpl/projectName.podspec.tmpl diff --git a/dev/devicelab/bin/tasks/plugin_lint_mac.dart b/dev/devicelab/bin/tasks/plugin_lint_mac.dart index ec49c82acb0f3..eb846214a057f 100644 --- a/dev/devicelab/bin/tasks/plugin_lint_mac.dart +++ b/dev/devicelab/bin/tasks/plugin_lint_mac.dart @@ -13,10 +13,11 @@ import 'package:path/path.dart' as path; /// to confirm the plugin module can be imported into an app. Future main() async { await task(() async { - section('Create Objective-C iOS plugin'); final Directory tempDir = Directory.systemTemp.createTempSync('flutter_plugin_test.'); try { + section('Create Objective-C plugin'); + const String objcPluginName = 'test_plugin_objc'; await inDirectory(tempDir, () async { await flutter( @@ -31,8 +32,10 @@ Future main() async { ); }); - final String objcPodspecPath = path.join(tempDir.path, objcPluginName, 'ios', '$objcPluginName.podspec'); - section('Lint Objective-C iOS plugin as framework'); + section('Lint Objective-C iOS podspec plugin as framework'); + + final String objcPluginPath = path.join(tempDir.path, objcPluginName); + final String objcPodspecPath = path.join(objcPluginPath, 'ios', '$objcPluginName.podspec'); await inDirectory(tempDir, () async { await exec( 'pod', @@ -45,7 +48,8 @@ Future main() async { ); }); - section('Lint Objective-C iOS plugin as library'); + section('Lint Objective-C iOS podspec plugin as library'); + await inDirectory(tempDir, () async { await exec( 'pod', @@ -59,6 +63,136 @@ Future main() async { ); }); + section('Create Swift plugin'); + + const String swiftPluginName = 'test_plugin_swift'; + await inDirectory(tempDir, () async { + await flutter( + 'create', + options: [ + '--org', + 'io.flutter.devicelab', + '--template=plugin', + '--ios-language=swift', + swiftPluginName, + ], + ); + }); + + section('Create Objective-C application'); + + const String objcAppName = 'test_app_objc'; + await inDirectory(tempDir, () async { + await flutter( + 'create', + options: [ + '--org', + 'io.flutter.devicelab', + '--ios-language=objc', + objcAppName, + ], + ); + }); + + section('Build Objective-C application with Swift and Objective-C plugins as libraries'); + + final String objcAppPath = path.join(tempDir.path, objcAppName); + + final String swiftPluginPath = path.join(tempDir.path, swiftPluginName); + final File objcPubspec = File(path.join(objcAppPath, 'pubspec.yaml')); + String podspecContent = objcPubspec.readAsStringSync(); + podspecContent = podspecContent.replaceFirst( + '\ndependencies:\n', + '\ndependencies:\n $objcPluginName:\n path: $objcPluginPath\n $swiftPluginName:\n path: $swiftPluginPath\n', + ); + objcPubspec.writeAsStringSync(podspecContent, flush: true); + + await inDirectory(objcAppPath, () async { + await flutter( + 'build', + options: [ + 'ios', + '--no-codesign' + ], + // TODO(jmagman): Make Objective-C applications handle Swift libraries https://github.com/flutter/flutter/issues/16049 + canFail: true + ); + }); + + final File objcPodfile = File(path.join(objcAppPath, 'ios', 'Podfile')); + String objcPodfileContent = objcPodfile.readAsStringSync(); + if (objcPodfileContent.contains('use_frameworks!')) { + return TaskResult.failure('Expected default Objective-C Podfile to not contain use_frameworks'); + } + + section('Build Objective-C application with Swift and Objective-C plugins as frameworks'); + + objcPodfileContent = 'use_frameworks!\n' + objcPodfileContent; + objcPodfile.writeAsStringSync(objcPodfileContent, flush: true); + + await inDirectory(objcAppPath, () async { + await flutter( + 'build', + options: [ + 'ios', + '--no-codesign' + ], + ); + }); + + section('Create Swift application'); + + const String swiftAppName = 'test_app_swift'; + await inDirectory(tempDir, () async { + await flutter( + 'create', + options: [ + '--org', + 'io.flutter.devicelab', + '--ios-language=swift', + swiftAppName, + ], + ); + }); + + section('Build Swift application with Swift and Objective-C plugins as frameworks'); + + final String swiftAppPath = path.join(tempDir.path, swiftAppName); + + final File swiftPubspec = File(path.join(swiftAppPath, 'pubspec.yaml')); + swiftPubspec.writeAsStringSync(podspecContent, flush: true); + + await inDirectory(swiftAppPath, () async { + await flutter( + 'build', + options: [ + 'ios', + '--no-codesign' + ], + ); + }); + + final File swiftPodfile = File(path.join(swiftAppPath, 'ios', 'Podfile')); + String swiftPodfileContent = swiftPodfile.readAsStringSync(); + if (!swiftPodfileContent.contains('use_frameworks!')) { + return TaskResult.failure('Expected default Swift Podfile to contain use_frameworks'); + } + + section('Build Swift application with Swift and Objective-C plugins as libraries'); + + swiftPodfileContent = swiftPodfileContent.replaceAll('use_frameworks!', ''); + swiftPodfile.writeAsStringSync(swiftPodfileContent, flush: true); + + await inDirectory(swiftAppPath, () async { + await flutter( + 'build', + options: [ + 'ios', + '--no-codesign' + ], + ); + }); + return TaskResult.success(null); } catch (e) { return TaskResult.failure(e.toString()); diff --git a/packages/flutter_tools/templates/plugin/ios.tmpl/projectName.podspec.tmpl b/packages/flutter_tools/templates/plugin/ios-objc.tmpl/projectName.podspec.tmpl similarity index 100% rename from packages/flutter_tools/templates/plugin/ios.tmpl/projectName.podspec.tmpl rename to packages/flutter_tools/templates/plugin/ios-objc.tmpl/projectName.podspec.tmpl diff --git a/packages/flutter_tools/templates/plugin/ios-swift.tmpl/Classes/pluginClass.m.tmpl b/packages/flutter_tools/templates/plugin/ios-swift.tmpl/Classes/pluginClass.m.tmpl index 6d606768441aa..4e16e6c0d14c0 100644 --- a/packages/flutter_tools/templates/plugin/ios-swift.tmpl/Classes/pluginClass.m.tmpl +++ b/packages/flutter_tools/templates/plugin/ios-swift.tmpl/Classes/pluginClass.m.tmpl @@ -1,5 +1,12 @@ #import "{{pluginClass}}.h" +#if __has_include(<{{projectName}}/{{projectName}}-Swift.h>) #import <{{projectName}}/{{projectName}}-Swift.h> +#else +// Support project import fallback if the generated compatibility header +// is not copied when this plugin is created as a library. +// https://forums.swift.org/t/swift-static-libraries-dont-copy-generated-objective-c-header/19816 +#import "{{projectName}}-Swift.h" +#endif @implementation {{pluginClass}} + (void)registerWithRegistrar:(NSObject*)registrar { diff --git a/packages/flutter_tools/templates/plugin/ios-swift.tmpl/projectName.podspec.tmpl b/packages/flutter_tools/templates/plugin/ios-swift.tmpl/projectName.podspec.tmpl new file mode 100644 index 0000000000000..1a60d143b7b91 --- /dev/null +++ b/packages/flutter_tools/templates/plugin/ios-swift.tmpl/projectName.podspec.tmpl @@ -0,0 +1,23 @@ +# +# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html. +# Run `pod lib lint {{projectName}}.podspec' to validate before publishing. +# +Pod::Spec.new do |s| + s.name = '{{projectName}}' + s.version = '0.0.1' + s.summary = '{{description}}' + s.description = <<-DESC +{{description}} + DESC + s.homepage = 'http://example.com' + s.license = { :file => '../LICENSE' } + s.author = { 'Your Company' => 'email@example.com' } + s.source = { :path => '.' } + s.source_files = 'Classes/**/*' + s.dependency 'Flutter' + s.platform = :ios, '8.0' + + # Flutter.framework does not contain a i386 slice. Only x86_64 simulators are supported. + s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'VALID_ARCHS[sdk=iphonesimulator*]' => 'x86_64' } + s.swift_version = '5.0' +end diff --git a/packages/flutter_tools/templates/plugin/macos.tmpl/projectName.podspec.tmpl b/packages/flutter_tools/templates/plugin/macos.tmpl/projectName.podspec.tmpl index ada388da68ef0..5de1fbedb23af 100644 --- a/packages/flutter_tools/templates/plugin/macos.tmpl/projectName.podspec.tmpl +++ b/packages/flutter_tools/templates/plugin/macos.tmpl/projectName.podspec.tmpl @@ -18,4 +18,5 @@ Pod::Spec.new do |s| s.platform = :osx, '10.11' s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES' } + s.swift_version = '5.0' end