From 9f5c6553bcbd53cc012869504a9c9d89c4133577 Mon Sep 17 00:00:00 2001 From: Jenn Magder Date: Tue, 25 Oct 2022 13:33:35 -0700 Subject: [PATCH] Revert "Check for watch companion in build settings (#113956)" (#114035) This reverts commit e13372188ffab27f8efaad0f56320c169d36fc74. --- .../ios/Runner.xcodeproj/project.pbxproj | 3 - .../ios/watch/Info.plist | 2 + packages/flutter_tools/lib/src/ios/mac.dart | 7 +- .../flutter_tools/lib/src/ios/xcodeproj.dart | 11 +- .../flutter_tools/lib/src/xcode_project.dart | 48 +---- .../general.shard/ios/xcodeproj_test.dart | 70 ------- .../test/general.shard/project_test.dart | 179 ++---------------- 7 files changed, 29 insertions(+), 291 deletions(-) diff --git a/dev/integration_tests/ios_app_with_extensions/ios/Runner.xcodeproj/project.pbxproj b/dev/integration_tests/ios_app_with_extensions/ios/Runner.xcodeproj/project.pbxproj index 4c623d7178..f3e42206ae 100644 --- a/dev/integration_tests/ios_app_with_extensions/ios/Runner.xcodeproj/project.pbxproj +++ b/dev/integration_tests/ios_app_with_extensions/ios/Runner.xcodeproj/project.pbxproj @@ -727,7 +727,6 @@ GCC_C_LANGUAGE_STANDARD = gnu11; IBSC_MODULE = watch_Extension; INFOPLIST_FILE = watch/Info.plist; - INFOPLIST_KEY_WKCompanionAppBundleIdentifier = io.flutter.extensionTest; MARKETING_VERSION = 1.0.0; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; @@ -758,7 +757,6 @@ GCC_C_LANGUAGE_STANDARD = gnu11; IBSC_MODULE = watch_Extension; INFOPLIST_FILE = watch/Info.plist; - INFOPLIST_KEY_WKCompanionAppBundleIdentifier = io.flutter.extensionTest; MARKETING_VERSION = 1.0.0; MTL_FAST_MATH = YES; OTHER_LDFLAGS = ""; @@ -787,7 +785,6 @@ GCC_C_LANGUAGE_STANDARD = gnu11; IBSC_MODULE = watch_Extension; INFOPLIST_FILE = watch/Info.plist; - INFOPLIST_KEY_WKCompanionAppBundleIdentifier = io.flutter.extensionTest; MARKETING_VERSION = 1.0.0; MTL_FAST_MATH = YES; OTHER_LDFLAGS = ""; diff --git a/dev/integration_tests/ios_app_with_extensions/ios/watch/Info.plist b/dev/integration_tests/ios_app_with_extensions/ios/watch/Info.plist index a53975e00f..62d335f672 100644 --- a/dev/integration_tests/ios_app_with_extensions/ios/watch/Info.plist +++ b/dev/integration_tests/ios_app_with_extensions/ios/watch/Info.plist @@ -25,6 +25,8 @@ UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown + WKCompanionAppBundleIdentifier + $(APP_BUNDLE_IDENTIFIER) WKWatchKitApp diff --git a/packages/flutter_tools/lib/src/ios/mac.dart b/packages/flutter_tools/lib/src/ios/mac.dart index d4725e3f34..c023f1809f 100644 --- a/packages/flutter_tools/lib/src/ios/mac.dart +++ b/packages/flutter_tools/lib/src/ios/mac.dart @@ -265,10 +265,9 @@ Future buildXcodeProject({ // Check if the project contains a watchOS companion app. final bool hasWatchCompanion = await app.project.containsWatchCompanion( - targets: projectInfo.targets, - schemes: projectInfo.schemes, - buildInfo: buildInfo, - deviceId: deviceID, + projectInfo.targets, + buildInfo, + deviceID, ); if (hasWatchCompanion) { // The -sdk argument has to be omitted if a watchOS companion app exists. diff --git a/packages/flutter_tools/lib/src/ios/xcodeproj.dart b/packages/flutter_tools/lib/src/ios/xcodeproj.dart index afe88e8502..4e6f5b6adc 100644 --- a/packages/flutter_tools/lib/src/ios/xcodeproj.dart +++ b/packages/flutter_tools/lib/src/ios/xcodeproj.dart @@ -198,11 +198,7 @@ class XcodeProjectInterpreter { if (buildContext.environmentType == EnvironmentType.simulator) ...['-sdk', 'iphonesimulator'], '-destination', - if (buildContext.isWatch == true && buildContext.environmentType == EnvironmentType.physical) - 'generic/platform=watchOS' - else if (buildContext.isWatch == true) - 'generic/platform=watchOS Simulator' - else if (deviceId != null) + if (deviceId != null) 'id=$deviceId' else if (buildContext.environmentType == EnvironmentType.physical) 'generic/platform=iOS' @@ -380,14 +376,12 @@ class XcodeProjectBuildContext { this.configuration, this.environmentType = EnvironmentType.physical, this.deviceId, - this.isWatch = false, }); final String? scheme; final String? configuration; final EnvironmentType environmentType; final String? deviceId; - final bool isWatch; @override int get hashCode => Object.hash(scheme, configuration, environmentType, deviceId); @@ -401,8 +395,7 @@ class XcodeProjectBuildContext { other.scheme == scheme && other.configuration == configuration && other.deviceId == deviceId && - other.environmentType == environmentType && - other.isWatch == isWatch; + other.environmentType == environmentType; } } diff --git a/packages/flutter_tools/lib/src/xcode_project.dart b/packages/flutter_tools/lib/src/xcode_project.dart index 69131d0e2b..1b0e328b9b 100644 --- a/packages/flutter_tools/lib/src/xcode_project.dart +++ b/packages/flutter_tools/lib/src/xcode_project.dart @@ -256,8 +256,6 @@ class IosProject extends XcodeBasedProject { BuildInfo? buildInfo, { EnvironmentType environmentType = EnvironmentType.physical, String? deviceId, - String? scheme, - bool isWatch = false, }) async { if (!existsSync()) { return null; @@ -267,11 +265,9 @@ class IosProject extends XcodeBasedProject { return null; } + final String? scheme = info.schemeFor(buildInfo); if (scheme == null) { - scheme = info.schemeFor(buildInfo); - if (scheme == null) { - info.reportFlavorNotFoundAndExit(); - } + info.reportFlavorNotFoundAndExit(); } final String? configuration = (await projectInfo())?.buildConfigurationFor( @@ -283,7 +279,6 @@ class IosProject extends XcodeBasedProject { scheme: scheme, configuration: configuration, deviceId: deviceId, - isWatch: isWatch, ); final Map? currentBuildSettings = _buildSettingsByBuildContext[buildContext]; if (currentBuildSettings == null) { @@ -332,12 +327,7 @@ class IosProject extends XcodeBasedProject { } /// Check if one the [targets] of the project is a watchOS companion app target. - Future containsWatchCompanion({ - required List targets, - required List schemes, - required BuildInfo buildInfo, - String? deviceId, - }) async { + Future containsWatchCompanion(List targets, BuildInfo buildInfo, String? deviceId) async { final String? bundleIdentifier = await productBundleIdentifier(buildInfo); // A bundle identifier is required for a companion app. if (bundleIdentifier == null) { @@ -346,8 +336,8 @@ class IosProject extends XcodeBasedProject { for (final String target in targets) { // Create Info.plist file of the target. final File infoFile = hostAppRoot.childDirectory(target).childFile('Info.plist'); - // In older versions of Xcode, if the target was a watchOS companion app, - // the Info.plist file of the target contained the key WKCompanionAppBundleIdentifier. + // The Info.plist file of a target contains the key WKCompanionAppBundleIdentifier, + // if it is a watchOS companion app. if (infoFile.existsSync()) { final String? fromPlist = globals.plistParser.getStringValueFromFile(infoFile.path, 'WKCompanionAppBundleIdentifier'); if (bundleIdentifier == fromPlist) { @@ -367,34 +357,6 @@ class IosProject extends XcodeBasedProject { } } } - - // If key not found in Info.plist above, do more expensive check of build settings. - // In newer versions of Xcode, the build settings of the watchOS companion - // app's scheme should contain the key INFOPLIST_KEY_WKCompanionAppBundleIdentifier. - final bool watchIdentifierFound = xcodeProjectInfoFile.readAsStringSync().contains('WKCompanionAppBundleIdentifier'); - if (watchIdentifierFound == false) { - return false; - } - for (final String scheme in schemes) { - final Map? allBuildSettings = await buildSettingsForBuildInfo( - buildInfo, - deviceId: deviceId, - scheme: scheme, - isWatch: true, - ); - if (allBuildSettings != null) { - final String? fromBuild = allBuildSettings['INFOPLIST_KEY_WKCompanionAppBundleIdentifier']; - if (bundleIdentifier == fromBuild) { - return true; - } - if (fromBuild != null && fromBuild.contains(r'$')) { - final String substitutedVariable = substituteXcodeVariables(fromBuild, allBuildSettings); - if (substitutedVariable == bundleIdentifier) { - return true; - } - } - } - } return false; } diff --git a/packages/flutter_tools/test/general.shard/ios/xcodeproj_test.dart b/packages/flutter_tools/test/general.shard/ios/xcodeproj_test.dart index f4bc973506..de496685fa 100644 --- a/packages/flutter_tools/test/general.shard/ios/xcodeproj_test.dart +++ b/packages/flutter_tools/test/general.shard/ios/xcodeproj_test.dart @@ -395,76 +395,6 @@ void main() { ProcessManager: () => FakeProcessManager.any(), }); - testUsingContext('build settings uses watch destination if isWatch is true', () async { - platform.environment = const {}; - - fakeProcessManager.addCommands([ - kWhichSysctlCommand, - kx64CheckCommand, - FakeCommand( - command: [ - 'xcrun', - 'xcodebuild', - '-project', - '/', - '-destination', - 'generic/platform=watchOS', - '-showBuildSettings', - 'BUILD_DIR=${fileSystem.path.absolute('build', 'ios')}', - ], - exitCode: 1, - ), - ]); - - expect( - await xcodeProjectInterpreter.getBuildSettings( - '', - buildContext: const XcodeProjectBuildContext(isWatch: true), - ), - const {}, - ); - expect(fakeProcessManager, hasNoRemainingExpectations); - }, overrides: { - FileSystem: () => fileSystem, - ProcessManager: () => FakeProcessManager.any(), - }); - - testUsingContext('build settings uses watch simulator destination if isWatch is true and environment type is simulator', () async { - platform.environment = const {}; - - fakeProcessManager.addCommands([ - kWhichSysctlCommand, - kx64CheckCommand, - FakeCommand( - command: [ - 'xcrun', - 'xcodebuild', - '-project', - '/', - '-sdk', - 'iphonesimulator', - '-destination', - 'generic/platform=watchOS Simulator', - '-showBuildSettings', - 'BUILD_DIR=${fileSystem.path.absolute('build', 'ios')}', - ], - exitCode: 1, - ), - ]); - - expect( - await xcodeProjectInterpreter.getBuildSettings( - '', - buildContext: const XcodeProjectBuildContext(environmentType: EnvironmentType.simulator, isWatch: true), - ), - const {}, - ); - expect(fakeProcessManager, hasNoRemainingExpectations); - }, overrides: { - FileSystem: () => fileSystem, - ProcessManager: () => FakeProcessManager.any(), - }); - testWithoutContext('xcodebuild clean contains Flutter Xcode environment variables', () async { platform.environment = const { 'FLUTTER_XCODE_CODE_SIGN_STYLE': 'Manual', diff --git a/packages/flutter_tools/test/general.shard/project_test.dart b/packages/flutter_tools/test/general.shard/project_test.dart index 3c4189b648..27ab853701 100644 --- a/packages/flutter_tools/test/general.shard/project_test.dart +++ b/packages/flutter_tools/test/general.shard/project_test.dart @@ -458,8 +458,7 @@ apply plugin: 'kotlin-android' testWithMocks('from build settings, if no plist', () async { final FlutterProject project = await someProject(); project.ios.xcodeProject.createSync(); - const XcodeProjectBuildContext buildContext = XcodeProjectBuildContext(scheme: 'Runner'); - xcodeProjectInterpreter.buildSettingsByBuildContext[buildContext] = { + xcodeProjectInterpreter.buildSettings = { 'PRODUCT_BUNDLE_IDENTIFIER': 'io.flutter.someProject', }; xcodeProjectInterpreter.xcodeProjectInfo = XcodeProjectInfo([], [], ['Runner'], logger); @@ -487,8 +486,7 @@ apply plugin: 'kotlin-android' testWithMocks('from build settings and plist, if default variable', () async { final FlutterProject project = await someProject(); project.ios.xcodeProject.createSync(); - const XcodeProjectBuildContext buildContext = XcodeProjectBuildContext(scheme: 'Runner'); - xcodeProjectInterpreter.buildSettingsByBuildContext[buildContext] = { + xcodeProjectInterpreter.buildSettings = { 'PRODUCT_BUNDLE_IDENTIFIER': 'io.flutter.someProject', }; xcodeProjectInterpreter.xcodeProjectInfo = XcodeProjectInfo([], [], ['Runner'], logger); @@ -501,8 +499,7 @@ apply plugin: 'kotlin-android' final FlutterProject project = await someProject(); project.ios.xcodeProject.createSync(); project.ios.defaultHostInfoPlist.createSync(recursive: true); - const XcodeProjectBuildContext buildContext = XcodeProjectBuildContext(scheme: 'Runner'); - xcodeProjectInterpreter.buildSettingsByBuildContext[buildContext] = { + xcodeProjectInterpreter.buildSettings = { 'PRODUCT_BUNDLE_IDENTIFIER': 'io.flutter.someProject', 'SUFFIX': 'suffix', }; @@ -537,8 +534,7 @@ apply plugin: 'kotlin-android' testWithMocks('handles case insensitive flavor', () async { final FlutterProject project = await someProject(); project.ios.xcodeProject.createSync(); - const XcodeProjectBuildContext buildContext = XcodeProjectBuildContext(scheme: 'Free'); - xcodeProjectInterpreter.buildSettingsByBuildContext[buildContext] = { + xcodeProjectInterpreter.buildSettings = { 'PRODUCT_BUNDLE_IDENTIFIER': 'io.flutter.someProject', }; xcodeProjectInterpreter.xcodeProjectInfo =XcodeProjectInfo([], [], ['Free'], logger); @@ -607,8 +603,7 @@ apply plugin: 'kotlin-android' testUsingContext('app product name xcodebuild settings', () async { final FlutterProject project = await someProject(); project.ios.xcodeProject.createSync(); - const XcodeProjectBuildContext buildContext = XcodeProjectBuildContext(scheme: 'Runner'); - mockXcodeProjectInterpreter.buildSettingsByBuildContext[buildContext] = { + mockXcodeProjectInterpreter.buildSettings = { 'FULL_PRODUCT_NAME': 'My App.app', }; mockXcodeProjectInterpreter.xcodeProjectInfo = XcodeProjectInfo([], [], ['Runner'], logger); @@ -710,15 +705,7 @@ apply plugin: 'kotlin-android' testUsingContext('cannot find bundle identifier', () async { final FlutterProject project = await someProject(); - expect( - await project.ios.containsWatchCompanion( - targets: ['WatchTarget'], - schemes: [], - buildInfo: BuildInfo.debug, - deviceId: '123', - ), - isFalse, - ); + expect(await project.ios.containsWatchCompanion(['WatchTarget'], BuildInfo.debug, '123'), isFalse); }, overrides: { FileSystem: () => fs, ProcessManager: () => FakeProcessManager.any(), @@ -729,8 +716,7 @@ apply plugin: 'kotlin-android' group('with bundle identifier', () { setUp(() { - const XcodeProjectBuildContext buildContext = XcodeProjectBuildContext(scheme: 'Runner'); - mockXcodeProjectInterpreter.buildSettingsByBuildContext[buildContext] = { + mockXcodeProjectInterpreter.buildSettings = { 'PRODUCT_BUNDLE_IDENTIFIER': 'io.flutter.someProject', }; mockXcodeProjectInterpreter.xcodeProjectInfo = XcodeProjectInfo([], [], ['Runner'], logger); @@ -738,15 +724,7 @@ apply plugin: 'kotlin-android' testUsingContext('no Info.plist in target', () async { final FlutterProject project = await someProject(); - expect( - await project.ios.containsWatchCompanion( - targets: ['WatchTarget'], - schemes: [], - buildInfo: BuildInfo.debug, - deviceId: '123', - ), - isFalse, - ); + expect(await project.ios.containsWatchCompanion(['WatchTarget'], BuildInfo.debug, '123'), isFalse); }, overrides: { FileSystem: () => fs, ProcessManager: () => FakeProcessManager.any(), @@ -759,15 +737,7 @@ apply plugin: 'kotlin-android' final FlutterProject project = await someProject(); project.ios.hostAppRoot.childDirectory('WatchTarget').childFile('Info.plist').createSync(recursive: true); - expect( - await project.ios.containsWatchCompanion( - targets: ['WatchTarget'], - schemes: [], - buildInfo: BuildInfo.debug, - deviceId: '123', - ), - isFalse, - ); + expect(await project.ios.containsWatchCompanion(['WatchTarget'], BuildInfo.debug, '123'), isFalse); }, overrides: { FileSystem: () => fs, ProcessManager: () => FakeProcessManager.any(), @@ -781,15 +751,7 @@ apply plugin: 'kotlin-android' project.ios.hostAppRoot.childDirectory('WatchTarget').childFile('Info.plist').createSync(recursive: true); testPlistParser.setProperty('WKCompanionAppBundleIdentifier', 'io.flutter.someOTHERproject'); - expect( - await project.ios.containsWatchCompanion( - targets: ['WatchTarget'], - schemes: [], - buildInfo: BuildInfo.debug, - deviceId: '123', - ), - isFalse, - ); + expect(await project.ios.containsWatchCompanion(['WatchTarget'], BuildInfo.debug, '123'), isFalse); }, overrides: { FileSystem: () => fs, ProcessManager: () => FakeProcessManager.any(), @@ -798,21 +760,13 @@ apply plugin: 'kotlin-android' FlutterProjectFactory: () => flutterProjectFactory, }); - testUsingContext('has watch companion in plist', () async { + testUsingContext('has watch companion', () async { final FlutterProject project = await someProject(); project.ios.xcodeProject.createSync(); project.ios.hostAppRoot.childDirectory('WatchTarget').childFile('Info.plist').createSync(recursive: true); testPlistParser.setProperty('WKCompanionAppBundleIdentifier', 'io.flutter.someProject'); - expect( - await project.ios.containsWatchCompanion( - targets: ['WatchTarget'], - schemes: [], - buildInfo: BuildInfo.debug, - deviceId: '123', - ), - isTrue, - ); + expect(await project.ios.containsWatchCompanion(['WatchTarget'], BuildInfo.debug, '123'), isTrue); }, overrides: { FileSystem: () => fs, ProcessManager: () => FakeProcessManager.any(), @@ -821,112 +775,16 @@ apply plugin: 'kotlin-android' FlutterProjectFactory: () => flutterProjectFactory, }); - testUsingContext('has watch companion in plist with xcode variable', () async { + testUsingContext('has watch companion with build settings', () async { final FlutterProject project = await someProject(); project.ios.xcodeProject.createSync(); - const XcodeProjectBuildContext buildContext = XcodeProjectBuildContext( - scheme: 'Runner', - deviceId: '123', - ); - mockXcodeProjectInterpreter.buildSettingsByBuildContext[buildContext] = { + mockXcodeProjectInterpreter.buildSettings = { 'PRODUCT_BUNDLE_IDENTIFIER': 'io.flutter.someProject', }; project.ios.hostAppRoot.childDirectory('WatchTarget').childFile('Info.plist').createSync(recursive: true); testPlistParser.setProperty('WKCompanionAppBundleIdentifier', r'$(PRODUCT_BUNDLE_IDENTIFIER)'); - expect( - await project.ios.containsWatchCompanion( - targets: ['WatchTarget'], - schemes: [], - buildInfo: BuildInfo.debug, - deviceId: '123', - ), - isTrue, - ); - }, overrides: { - FileSystem: () => fs, - ProcessManager: () => FakeProcessManager.any(), - PlistParser: () => testPlistParser, - XcodeProjectInterpreter: () => mockXcodeProjectInterpreter, - FlutterProjectFactory: () => flutterProjectFactory, - }); - - testUsingContext('has watch companion in other scheme build settings', () async { - final FlutterProject project = await someProject(); - project.ios.xcodeProject.createSync(); - project.ios.xcodeProjectInfoFile.writeAsStringSync(''' - Build settings for action build and target "WatchTarget": - INFOPLIST_KEY_WKCompanionAppBundleIdentifier = io.flutter.someProject -'''); - - const XcodeProjectBuildContext buildContext = XcodeProjectBuildContext( - scheme: 'Runner', - deviceId: '123', - ); - mockXcodeProjectInterpreter.buildSettingsByBuildContext[buildContext] = { - 'PRODUCT_BUNDLE_IDENTIFIER': 'io.flutter.someProject', - }; - - const XcodeProjectBuildContext watchBuildContext = XcodeProjectBuildContext( - scheme: 'WatchScheme', - deviceId: '123', - isWatch: true, - ); - mockXcodeProjectInterpreter.buildSettingsByBuildContext[watchBuildContext] = { - 'INFOPLIST_KEY_WKCompanionAppBundleIdentifier': 'io.flutter.someProject', - }; - - expect( - await project.ios.containsWatchCompanion( - targets: ['Runner', 'WatchTarget'], - schemes: ['Runner', 'WatchScheme'], - buildInfo: BuildInfo.debug, - deviceId: '123', - ), - isTrue, - ); - }, overrides: { - FileSystem: () => fs, - ProcessManager: () => FakeProcessManager.any(), - PlistParser: () => testPlistParser, - XcodeProjectInterpreter: () => mockXcodeProjectInterpreter, - FlutterProjectFactory: () => flutterProjectFactory, - }); - - testUsingContext('has watch companion in other scheme build settings with xcode variable', () async { - final FlutterProject project = await someProject(); - project.ios.xcodeProject.createSync(); - project.ios.xcodeProjectInfoFile.writeAsStringSync(r''' - Build settings for action build and target "WatchTarget": - INFOPLIST_KEY_WKCompanionAppBundleIdentifier = $(PRODUCT_BUNDLE_IDENTIFIER) -'''); - const XcodeProjectBuildContext buildContext = XcodeProjectBuildContext( - scheme: 'Runner', - deviceId: '123' - ); - mockXcodeProjectInterpreter.buildSettingsByBuildContext[buildContext] = { - 'PRODUCT_BUNDLE_IDENTIFIER': 'io.flutter.someProject', - }; - - const XcodeProjectBuildContext watchBuildContext = XcodeProjectBuildContext( - scheme: 'WatchScheme', - deviceId: '123', - isWatch: true, - ); - mockXcodeProjectInterpreter.buildSettingsByBuildContext[watchBuildContext] = { - 'PRODUCT_BUNDLE_IDENTIFIER': 'io.flutter.someProject', - 'INFOPLIST_KEY_WKCompanionAppBundleIdentifier': r'$(PRODUCT_BUNDLE_IDENTIFIER)', - }; - - expect( - await project.ios.containsWatchCompanion( - targets: ['Runner', 'WatchTarget'], - schemes: ['Runner', 'WatchScheme'], - buildInfo: BuildInfo.debug, - deviceId: '123', - ), - isTrue, - ); + expect(await project.ios.containsWatchCompanion(['WatchTarget'], BuildInfo.debug, '123'), isTrue); }, overrides: { FileSystem: () => fs, ProcessManager: () => FakeProcessManager.any(), @@ -1217,7 +1075,7 @@ File androidPluginRegistrant(Directory parent) { } class FakeXcodeProjectInterpreter extends Fake implements XcodeProjectInterpreter { - final Map> buildSettingsByBuildContext = >{}; + Map buildSettings = {}; late XcodeProjectInfo xcodeProjectInfo; @override @@ -1225,10 +1083,7 @@ class FakeXcodeProjectInterpreter extends Fake implements XcodeProjectInterprete XcodeProjectBuildContext? buildContext, Duration timeout = const Duration(minutes: 1), }) async { - if (buildSettingsByBuildContext[buildContext] == null) { - return {}; - } - return buildSettingsByBuildContext[buildContext]!; + return buildSettings; } @override