From 74c6237abc6510d0fa217a7e2aff8e2b17cd8ff5 Mon Sep 17 00:00:00 2001 From: Victor Maraccini Date: Wed, 1 May 2019 14:21:43 -0300 Subject: [PATCH] Fix bundle id on iOS launch using flutter run (#31039) --- .../flutter_tools/lib/src/ios/simulators.dart | 11 ++++++- .../test/ios/simulators_test.dart | 31 +++++++++++++++++++ 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/packages/flutter_tools/lib/src/ios/simulators.dart b/packages/flutter_tools/lib/src/ios/simulators.dart index 3596c6edf78..428e154b676 100644 --- a/packages/flutter_tools/lib/src/ios/simulators.dart +++ b/packages/flutter_tools/lib/src/ios/simulators.dart @@ -23,6 +23,7 @@ import '../project.dart'; import '../protocol_discovery.dart'; import 'ios_workflow.dart'; import 'mac.dart'; +import 'plist_utils.dart'; const String _xcrunPath = '/usr/bin/xcrun'; @@ -343,7 +344,15 @@ class IOSSimulator extends Device { // Launch the updated application in the simulator. try { - await SimControl.instance.launch(id, package.id, args); + // Use the built application's Info.plist to get the bundle identifier, + // which should always yield the correct value and does not require + // parsing the xcodeproj or configuration files. + // See https://github.com/flutter/flutter/issues/31037 for more information. + final IOSApp iosApp = package; + final String plistPath = fs.path.join(iosApp.simulatorBundlePath, 'Info.plist'); + final String bundleIdentifier = iosWorkflow.getPlistValueFromFile(plistPath, kCFBundleIdentifierKey); + + await SimControl.instance.launch(id, bundleIdentifier, args); } catch (error) { printError('$error'); return LaunchResult.failed(); diff --git a/packages/flutter_tools/test/ios/simulators_test.dart b/packages/flutter_tools/test/ios/simulators_test.dart index aedbd723d6f..61dd6afda11 100644 --- a/packages/flutter_tools/test/ios/simulators_test.dart +++ b/packages/flutter_tools/test/ios/simulators_test.dart @@ -6,10 +6,12 @@ import 'dart:async'; import 'dart:io' show ProcessResult, Process; import 'package:file/file.dart'; +import 'package:flutter_tools/src/build_info.dart'; import 'package:file/memory.dart'; import 'package:flutter_tools/src/device.dart'; import 'package:flutter_tools/src/application_package.dart'; import 'package:flutter_tools/src/base/file_system.dart'; +import 'package:flutter_tools/src/ios/ios_workflow.dart'; import 'package:flutter_tools/src/ios/mac.dart'; import 'package:flutter_tools/src/ios/simulators.dart'; import 'package:flutter_tools/src/project.dart'; @@ -26,6 +28,8 @@ class MockIMobileDevice extends Mock implements IMobileDevice {} class MockProcess extends Mock implements Process {} class MockProcessManager extends Mock implements ProcessManager {} class MockXcode extends Mock implements Xcode {} +class MockSimControl extends Mock implements SimControl {} +class MockIOSWorkflow extends Mock implements IOSWorkflow {} void main() { FakePlatform osx; @@ -417,6 +421,33 @@ void main() { }); }); + group('startApp', () { + SimControl simControl; + + setUp(() { + simControl = MockSimControl(); + }); + + testUsingContext("startApp uses compiled app's Info.plist to find CFBundleIdentifier", () async { + final IOSSimulator device = IOSSimulator('x', name: 'iPhone SE', category: 'iOS 11.2'); + when(iosWorkflow.getPlistValueFromFile(any, any)).thenReturn('correct'); + + final Directory mockDir = fs.currentDirectory; + final IOSApp package = PrebuiltIOSApp(projectBundleId: 'incorrect', bundleName: 'name', bundleDir: mockDir); + + const BuildInfo mockInfo = BuildInfo(BuildMode.debug, 'flavor'); + final DebuggingOptions mockOptions = DebuggingOptions.disabled(mockInfo); + await device.startApp(package, prebuiltApplication: true, debuggingOptions: mockOptions); + + verify(simControl.launch(any, 'correct', any)); + }, + overrides: { + SimControl: () => simControl, + IOSWorkflow: () => MockIOSWorkflow() + }, + ); + }); + testUsingContext('IOSDevice.isSupportedForProject is true on module project', () async { fs.file('pubspec.yaml') ..createSync()