From bce1706f1ca15248fb92d6000a8c4db3183a80b0 Mon Sep 17 00:00:00 2001 From: Mirko Mucaria Date: Thu, 17 Jun 2021 23:14:03 +0200 Subject: [PATCH] Fix watchOS build when companion app is configured with xcode variable (#84519) --- AUTHORS | 1 + .../ios/Runner.xcodeproj/project.pbxproj | 3 +++ .../ios/watch Extension/Info.plist | 2 +- .../ios/watch/Info.plist | 2 +- packages/flutter_tools/lib/src/project.dart | 19 +++++++++++++++++-- .../test/general.shard/project_test.dart | 18 ++++++++++++++++++ 6 files changed, 41 insertions(+), 4 deletions(-) diff --git a/AUTHORS b/AUTHORS index f2c94a6df3..3b0e2a5414 100644 --- a/AUTHORS +++ b/AUTHORS @@ -79,3 +79,4 @@ Seongyun Kim Ludwik Trammer Marian Triebe Alexis Rouillard +Mirko Mucaria 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 124d9f4b65..118ad3798a 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 @@ -570,6 +570,7 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + APP_BUNDLE_IDENTIFIER = io.flutter.extensionTest; CLANG_ANALYZER_NONNULL = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; @@ -828,6 +829,7 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + APP_BUNDLE_IDENTIFIER = io.flutter.extensionTest; CLANG_ANALYZER_NONNULL = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; @@ -883,6 +885,7 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + APP_BUNDLE_IDENTIFIER = io.flutter.extensionTest; CLANG_ANALYZER_NONNULL = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; diff --git a/dev/integration_tests/ios_app_with_extensions/ios/watch Extension/Info.plist b/dev/integration_tests/ios_app_with_extensions/ios/watch Extension/Info.plist index 3063ec4ba9..1aa92a5b21 100644 --- a/dev/integration_tests/ios_app_with_extensions/ios/watch Extension/Info.plist +++ b/dev/integration_tests/ios_app_with_extensions/ios/watch Extension/Info.plist @@ -25,7 +25,7 @@ NSExtensionAttributes WKAppBundleIdentifier - io.flutter.extensionTest.watchkitapp + $(APP_BUNDLE_IDENTIFIER).watchkitapp NSExtensionPointIdentifier com.apple.watchkit 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 a1c6ef0c27..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 @@ -26,7 +26,7 @@ UIInterfaceOrientationPortraitUpsideDown WKCompanionAppBundleIdentifier - io.flutter.extensionTest + $(APP_BUNDLE_IDENTIFIER) WKWatchKitApp diff --git a/packages/flutter_tools/lib/src/project.dart b/packages/flutter_tools/lib/src/project.dart index f4e403f148..1639017440 100644 --- a/packages/flutter_tools/lib/src/project.dart +++ b/packages/flutter_tools/lib/src/project.dart @@ -689,8 +689,23 @@ class IosProject extends FlutterProjectPlatform implements XcodeBasedProject { final File infoFile = hostAppRoot.childDirectory(target).childFile('Info.plist'); // The Info.plist file of a target contains the key WKCompanionAppBundleIdentifier, // if it is a watchOS companion app. - if (infoFile.existsSync() && globals.plistParser.getValueFromFile(infoFile.path, 'WKCompanionAppBundleIdentifier') == bundleIdentifier) { - return true; + if (infoFile.existsSync()) { + final String? fromPlist = globals.plistParser.getValueFromFile(infoFile.path, 'WKCompanionAppBundleIdentifier'); + if (bundleIdentifier == fromPlist) { + return true; + } + + // The key WKCompanionAppBundleIdentifier might contain an xcode variable + // that needs to be substituted before comparing it with bundle id + if (fromPlist != null && fromPlist.contains(r'$')) { + final Map? allBuildSettings = await buildSettingsForBuildInfo(buildInfo); + if (allBuildSettings != null) { + final String substituedVariable = substituteXcodeVariables(fromPlist, allBuildSettings); + if (substituedVariable == bundleIdentifier) { + return true; + } + } + } } } return false; diff --git a/packages/flutter_tools/test/general.shard/project_test.dart b/packages/flutter_tools/test/general.shard/project_test.dart index b0ea3f1014..1fd1893544 100644 --- a/packages/flutter_tools/test/general.shard/project_test.dart +++ b/packages/flutter_tools/test/general.shard/project_test.dart @@ -697,6 +697,24 @@ apply plugin: 'kotlin-android' XcodeProjectInterpreter: () => mockXcodeProjectInterpreter, FlutterProjectFactory: () => flutterProjectFactory, }); + + testUsingContext('has watch companion with build settings', () async { + final FlutterProject project = await someProject(); + project.ios.xcodeProject.createSync(); + 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(['WatchTarget'], null), isTrue); + }, overrides: { + FileSystem: () => fs, + ProcessManager: () => FakeProcessManager.any(), + PlistParser: () => testPlistParser, + XcodeProjectInterpreter: () => mockXcodeProjectInterpreter, + FlutterProjectFactory: () => flutterProjectFactory, + }); }); }); }