diff --git a/packages/flutter_tools/lib/src/ios/mac.dart b/packages/flutter_tools/lib/src/ios/mac.dart index 567d5ed6d0d..0a7348383b5 100644 --- a/packages/flutter_tools/lib/src/ios/mac.dart +++ b/packages/flutter_tools/lib/src/ios/mac.dart @@ -574,37 +574,14 @@ Future diagnoseXcodeBuildFailure(XcodeBuildResult result, Usage flutterUsa ).send(); } - // Building for iOS Simulator, but the linked and embedded framework 'App.framework' was built for iOS. - // or - // Building for iOS, but the linked and embedded framework 'App.framework' was built for iOS Simulator. - if ((result.stdout?.contains('Building for iOS') ?? false) - && (result.stdout?.contains('but the linked and embedded framework') ?? false) - && (result.stdout?.contains('was built for iOS') ?? false)) { - logger.printError(''); - logger.printError('Your Xcode project requires migration. See https://flutter.dev/docs/development/ios-project-migration for details.'); - logger.printError(''); - logger.printError('You can temporarily work around this issue by running:'); - logger.printError(' flutter clean'); - return; - } - if (xcodeBuildExecution != null - && xcodeBuildExecution.environmentType == EnvironmentType.physical - && (result.stdout?.contains('BCEROR') ?? false) - // May need updating if Xcode changes its outputs. - && (result.stdout?.contains("Xcode couldn't find a provisioning profile matching") ?? false)) { - logger.printError(noProvisioningProfileInstruction, emphasis: true); - return; - } - // Make sure the user has specified one of: - // * DEVELOPMENT_TEAM (automatic signing) - // * PROVISIONING_PROFILE (manual signing) - if (xcodeBuildExecution != null && - xcodeBuildExecution.environmentType == EnvironmentType.physical && - !['DEVELOPMENT_TEAM', 'PROVISIONING_PROFILE'].any( - xcodeBuildExecution.buildSettings.containsKey)) { - logger.printError(noDevelopmentTeamInstruction, emphasis: true); - return; + // Handle errors. + final bool issueDetected = _handleIssues(result.xcResult, logger, xcodeBuildExecution); + + if (!issueDetected && xcodeBuildExecution != null) { + // Fallback to use stdout to detect and print issues. + _parseIssueInStdout(xcodeBuildExecution, logger, result); } + if (xcodeBuildExecution != null && xcodeBuildExecution.environmentType == EnvironmentType.physical && (xcodeBuildExecution.buildSettings['PRODUCT_BUNDLE_IDENTIFIER']?.contains('com.example') ?? false)) { @@ -614,19 +591,6 @@ Future diagnoseXcodeBuildFailure(XcodeBuildResult result, Usage flutterUsa logger.printError(' open ios/Runner.xcworkspace'); return; } - - // Handle xcresult errors. - final XCResult? xcResult = result.xcResult; - if (xcResult == null) { - return; - } - if (!xcResult.parseSuccess) { - globals.printTrace('XCResult parsing error: ${xcResult.parsingErrorMessage}'); - return; - } - for (final XCResultIssue issue in xcResult.issues) { - _handleXCResultIssue(issue: issue, logger: logger); - } } /// xcodebuild parameter (see man xcodebuild for details). @@ -724,7 +688,7 @@ bool upgradePbxProjWithFlutterAssets(IosProject project, Logger logger) { return true; } -void _handleXCResultIssue({required XCResultIssue issue, required Logger logger}) { +_XCResultIssueHandlingResult _handleXCResultIssue({required XCResultIssue issue, required Logger logger}) { // Issue summary from xcresult. final StringBuffer issueSummaryBuffer = StringBuffer(); issueSummaryBuffer.write(issue.subType ?? 'Unknown'); @@ -744,16 +708,89 @@ void _handleXCResultIssue({required XCResultIssue issue, required Logger logger} break; } - // Add more custom output for flutter users. - if (issue.message != null && issue.message!.toLowerCase().contains('provisioning profile')) { + final String? message = issue.message; + if (message == null) { + return _XCResultIssueHandlingResult(requiresProvisioningProfile: false, hasProvisioningProfileIssue: false); + } + + // Add more error messages for flutter users for some special errors. + if (message.toLowerCase().contains('requires a provisioning profile.')) { + return _XCResultIssueHandlingResult(requiresProvisioningProfile: true, hasProvisioningProfileIssue: true); + } else if (message.toLowerCase().contains('provisioning profile')) { + return _XCResultIssueHandlingResult(requiresProvisioningProfile: false, hasProvisioningProfileIssue: true); + } + return _XCResultIssueHandlingResult(requiresProvisioningProfile: false, hasProvisioningProfileIssue: false); +} + +// Returns `true` if at least one issue is detected. +bool _handleIssues(XCResult? xcResult, Logger logger, XcodeBuildExecution? xcodeBuildExecution) { + bool requiresProvisioningProfile = false; + bool hasProvisioningProfileIssue = false; + bool issueDetected = false; + + if (xcResult != null && xcResult.parseSuccess) { + for (final XCResultIssue issue in xcResult.issues) { + final _XCResultIssueHandlingResult handlingResult = _handleXCResultIssue(issue: issue, logger: logger); + if (handlingResult.hasProvisioningProfileIssue) { + hasProvisioningProfileIssue = true; + } + if (handlingResult.requiresProvisioningProfile) { + requiresProvisioningProfile = true; + } + issueDetected = true; + } + } else if (xcResult != null) { + globals.printTrace('XCResult parsing error: ${xcResult.parsingErrorMessage}'); + } + + if (requiresProvisioningProfile) { + logger.printError(noProvisioningProfileInstruction, emphasis: true); + } else if (_missingDevelopmentTeam(xcodeBuildExecution)) { + issueDetected = true; + logger.printError(noDevelopmentTeamInstruction, emphasis: true); + } else if (hasProvisioningProfileIssue) { logger.printError(''); logger.printError('It appears that there was a problem signing your application prior to installation on the device.'); logger.printError(''); logger.printError('Verify that the Bundle Identifier in your project is your signing id in Xcode'); logger.printError(' open ios/Runner.xcworkspace'); logger.printError(''); - logger.printError("Also try selecting 'Product > Build' to fix the problem:"); + logger.printError("Also try selecting 'Product > Build' to fix the problem."); } + return issueDetected; +} + +// Return 'true' a missing development team issue is detected. +bool _missingDevelopmentTeam(XcodeBuildExecution? xcodeBuildExecution) { + // Make sure the user has specified one of: + // * DEVELOPMENT_TEAM (automatic signing) + // * PROVISIONING_PROFILE (manual signing) + return xcodeBuildExecution != null && xcodeBuildExecution.environmentType == EnvironmentType.physical && + !['DEVELOPMENT_TEAM', 'PROVISIONING_PROFILE'].any( + xcodeBuildExecution.buildSettings.containsKey); +} +// Detects and handles errors from stdout. +// +// As detecting issues in stdout is not usually accurate, this should be used as a fallback when other issue detecting methods failed. +void _parseIssueInStdout(XcodeBuildExecution xcodeBuildExecution, Logger logger, XcodeBuildResult result) { + if (xcodeBuildExecution.environmentType == EnvironmentType.physical + // May need updating if Xcode changes its outputs. + && (result.stdout?.contains('requires a provisioning profile. Select a provisioning profile in the Signing & Capabilities editor') ?? false)) { + logger.printError(noProvisioningProfileInstruction, emphasis: true); + return; + } +} + +// The result of [_handleXCResultIssue]. +class _XCResultIssueHandlingResult { + + _XCResultIssueHandlingResult({required this.requiresProvisioningProfile, required this.hasProvisioningProfileIssue}); + + // An issue indicates that user didn't provide the provisioning profile. + final bool requiresProvisioningProfile; + + // An issue indicates that there is a provisioning profile issue. + final bool hasProvisioningProfileIssue; } const String _kResultBundlePath = 'temporary_xcresult_bundle'; diff --git a/packages/flutter_tools/test/commands.shard/hermetic/build_ios_test.dart b/packages/flutter_tools/test/commands.shard/hermetic/build_ios_test.dart index befdcf22913..0a85e9717e5 100644 --- a/packages/flutter_tools/test/commands.shard/hermetic/build_ios_test.dart +++ b/packages/flutter_tools/test/commands.shard/hermetic/build_ios_test.dart @@ -8,9 +8,11 @@ import 'package:args/command_runner.dart'; import 'package:file/memory.dart'; import 'package:flutter_tools/src/base/file_system.dart'; import 'package:flutter_tools/src/base/platform.dart'; +import 'package:flutter_tools/src/build_info.dart'; import 'package:flutter_tools/src/cache.dart'; import 'package:flutter_tools/src/commands/build.dart'; import 'package:flutter_tools/src/commands/build_ios.dart'; +import 'package:flutter_tools/src/ios/code_signing.dart'; import 'package:flutter_tools/src/ios/xcodeproj.dart'; import 'package:flutter_tools/src/reporting/reporting.dart'; @@ -20,6 +22,9 @@ import '../../src/context.dart'; import '../../src/test_flutter_command_runner.dart'; class FakeXcodeProjectInterpreterWithBuildSettings extends FakeXcodeProjectInterpreter { + + FakeXcodeProjectInterpreterWithBuildSettings({this.productBundleIdentifier, this.developmentTeam = 'abc'}); + @override Future> getBuildSettings( String projectPath, { @@ -27,12 +32,17 @@ class FakeXcodeProjectInterpreterWithBuildSettings extends FakeXcodeProjectInter Duration timeout = const Duration(minutes: 1), }) async { return { - 'PRODUCT_BUNDLE_IDENTIFIER': 'io.flutter.someProject', - 'DEVELOPMENT_TEAM': 'abc', + 'PRODUCT_BUNDLE_IDENTIFIER': productBundleIdentifier ?? 'io.flutter.someProject', 'TARGET_BUILD_DIR': 'build/ios/Release-iphoneos', 'WRAPPER_NAME': 'Runner.app', + if (developmentTeam != null) 'DEVELOPMENT_TEAM': developmentTeam, }; } + + /// The value of 'PRODUCT_BUNDLE_IDENTIFIER'. + final String productBundleIdentifier; + + final String developmentTeam; } final Platform macosPlatform = FakePlatform( @@ -117,6 +127,7 @@ void main() { bool simulator = false, String deviceId, int exitCode = 0, + String stdout, void Function() onRun, }) { return FakeCommand( @@ -159,6 +170,7 @@ void main() { stdout: ''' TARGET_BUILD_DIR=build/ios/Release-iphoneos WRAPPER_NAME=Runner.app + $stdout ''', exitCode: exitCode, onRun: onRun, @@ -439,7 +451,7 @@ void main() { XcodeProjectInterpreter: () => FakeXcodeProjectInterpreterWithBuildSettings(), }); - testUsingContext('Extra error message for provision profile issue in xcresulb bundle.', () async { + testUsingContext('Extra error message for provision profile issue in xcresult bundle.', () async { final BuildCommand command = BuildCommand(); _createMinimalMockProjectFiles(); @@ -453,7 +465,7 @@ void main() { expect(testLogger.errorText, contains('It appears that there was a problem signing your application prior to installation on the device.')); expect(testLogger.errorText, contains('Verify that the Bundle Identifier in your project is your signing id in Xcode')); expect(testLogger.errorText, contains('open ios/Runner.xcworkspace')); - expect(testLogger.errorText, contains("Also try selecting 'Product > Build' to fix the problem:")); + expect(testLogger.errorText, contains("Also try selecting 'Product > Build' to fix the problem.")); }, overrides: { FileSystem: () => fileSystem, ProcessManager: () => FakeProcessManager.list([ @@ -467,6 +479,241 @@ void main() { Platform: () => macosPlatform, XcodeProjectInterpreter: () => FakeXcodeProjectInterpreterWithBuildSettings(), }); + + testUsingContext('Display xcresult issues with default bundle identifier.', () async { + final BuildCommand command = BuildCommand(); + + _createMinimalMockProjectFiles(); + + await expectLater( + createTestCommandRunner(command).run(const ['build', 'ios', '--no-pub']), + throwsToolExit(), + ); + + expect(testLogger.errorText, contains("Use of undeclared identifier 'asdas'")); + expect(testLogger.errorText, contains('/Users/m/Projects/test_create/ios/Runner/AppDelegate.m:7:56')); + expect(testLogger.errorText, contains('It appears that your application still contains the default signing identifier.')); + }, overrides: { + FileSystem: () => fileSystem, + ProcessManager: () => FakeProcessManager.list([ + xattrCommand, + _setUpFakeXcodeBuildHandler(exitCode: 1, onRun: () { + fileSystem.systemTempDirectory.childDirectory(_xcBundleFilePath).createSync(); + }), + _setUpXCResultCommand(stdout: kSampleResultJsonWithIssues), + _setUpRsyncCommand(), + ]), + Platform: () => macosPlatform, + EnvironmentType: () => EnvironmentType.physical, + XcodeProjectInterpreter: () => FakeXcodeProjectInterpreterWithBuildSettings(productBundleIdentifier: 'com.example'), + }); + + testUsingContext('Display xcresult issues with no provisioning profile.', () async { + final BuildCommand command = BuildCommand(); + + _createMinimalMockProjectFiles(); + + await expectLater( + createTestCommandRunner(command).run(const ['build', 'ios', '--no-pub']), + throwsToolExit(), + ); + + expect(testLogger.errorText, contains('Runner requires a provisioning profile. Select a provisioning profile in the Signing & Capabilities editor')); + expect(testLogger.errorText, contains(noProvisioningProfileInstruction)); + }, overrides: { + FileSystem: () => fileSystem, + ProcessManager: () => FakeProcessManager.list([ + xattrCommand, + _setUpFakeXcodeBuildHandler( + exitCode: 1, + onRun: () { + fileSystem.systemTempDirectory.childDirectory(_xcBundleFilePath).createSync(); + } + ), + _setUpXCResultCommand(stdout: kSampleResultJsonWithNoProvisioningProfileIssue), + _setUpRsyncCommand(), + ]), + Platform: () => macosPlatform, + XcodeProjectInterpreter: () => FakeXcodeProjectInterpreterWithBuildSettings(), + }); + + testUsingContext('Failed to parse xcresult but display missing provisioning profile issue from stdout.', () async { + final BuildCommand command = BuildCommand(); + + _createMinimalMockProjectFiles(); + + await expectLater( + createTestCommandRunner(command).run(const ['build', 'ios', '--no-pub']), + throwsToolExit(), + ); + + expect(testLogger.errorText, contains(noProvisioningProfileInstruction)); + }, overrides: { + FileSystem: () => fileSystem, + ProcessManager: () => FakeProcessManager.list([ + xattrCommand, + _setUpFakeXcodeBuildHandler( + exitCode: 1, + stdout: ''' +Runner requires a provisioning profile. Select a provisioning profile in the Signing & Capabilities editor +''', + onRun: () { + fileSystem.systemTempDirectory.childDirectory(_xcBundleFilePath).createSync(); + } + ), + _setUpXCResultCommand(stdout: kSampleResultJsonInvalidIssuesMap), + _setUpRsyncCommand(), + ]), + Platform: () => macosPlatform, + XcodeProjectInterpreter: () => FakeXcodeProjectInterpreterWithBuildSettings(), + }); + + testUsingContext('Failed to parse xcresult but detected no development team issue.', () async { + final BuildCommand command = BuildCommand(); + + _createMinimalMockProjectFiles(); + + await expectLater( + createTestCommandRunner(command).run(const ['build', 'ios', '--no-pub']), + throwsToolExit(), + ); + + expect(testLogger.errorText, contains(noDevelopmentTeamInstruction)); + }, overrides: { + FileSystem: () => fileSystem, + ProcessManager: () => FakeProcessManager.list([ + xattrCommand, + _setUpFakeXcodeBuildHandler( + exitCode: 1, + onRun: () { + fileSystem.systemTempDirectory.childDirectory(_xcBundleFilePath).createSync(); + } + ), + _setUpXCResultCommand(stdout: kSampleResultJsonInvalidIssuesMap), + _setUpRsyncCommand(), + ]), + Platform: () => macosPlatform, + XcodeProjectInterpreter: () => FakeXcodeProjectInterpreterWithBuildSettings(developmentTeam: null), + }); + + + testUsingContext('xcresult did not detect issue but detected by stdout.', () async { + final BuildCommand command = BuildCommand(); + + _createMinimalMockProjectFiles(); + + await expectLater( + createTestCommandRunner(command).run(const ['build', 'ios', '--no-pub']), + throwsToolExit(), + ); + + expect(testLogger.errorText, contains(noProvisioningProfileInstruction)); + }, overrides: { + FileSystem: () => fileSystem, + ProcessManager: () => FakeProcessManager.list([ + xattrCommand, + _setUpFakeXcodeBuildHandler( + exitCode: 1, + stdout: ''' +Runner requires a provisioning profile. Select a provisioning profile in the Signing & Capabilities editor +''', + onRun: () { + fileSystem.systemTempDirectory.childDirectory(_xcBundleFilePath).createSync(); + } + ), + _setUpXCResultCommand(stdout: kSampleResultJsonNoIssues), + _setUpRsyncCommand(), + ]), + EnvironmentType: () => EnvironmentType.physical, + Platform: () => macosPlatform, + XcodeProjectInterpreter: () => FakeXcodeProjectInterpreterWithBuildSettings(), + }); + + testUsingContext('xcresult did not detect issue, no development team is detected from build setting.', () async { + final BuildCommand command = BuildCommand(); + + _createMinimalMockProjectFiles(); + + await expectLater( + createTestCommandRunner(command).run(const ['build', 'ios', '--no-pub']), + throwsToolExit(), + ); + + expect(testLogger.errorText, contains(noDevelopmentTeamInstruction)); + }, overrides: { + FileSystem: () => fileSystem, + ProcessManager: () => FakeProcessManager.list([ + xattrCommand, + _setUpFakeXcodeBuildHandler( + exitCode: 1, + onRun: () { + fileSystem.systemTempDirectory.childDirectory(_xcBundleFilePath).createSync(); + } + ), + _setUpXCResultCommand(stdout: kSampleResultJsonInvalidIssuesMap), + _setUpRsyncCommand(), + ]), + Platform: () => macosPlatform, + XcodeProjectInterpreter: () => FakeXcodeProjectInterpreterWithBuildSettings(developmentTeam: null), + }); + + testUsingContext('No development team issue error message is not displayed if no provisioning profile issue is detected from xcresult first.', () async { + final BuildCommand command = BuildCommand(); + + _createMinimalMockProjectFiles(); + + await expectLater( + createTestCommandRunner(command).run(const ['build', 'ios', '--no-pub']), + throwsToolExit(), + ); + + expect(testLogger.errorText, contains(noProvisioningProfileInstruction)); + expect(testLogger.errorText, isNot(contains(noDevelopmentTeamInstruction))); + }, overrides: { + FileSystem: () => fileSystem, + ProcessManager: () => FakeProcessManager.list([ + xattrCommand, + _setUpFakeXcodeBuildHandler( + exitCode: 1, + onRun: () { + fileSystem.systemTempDirectory.childDirectory(_xcBundleFilePath).createSync(); + } + ), + _setUpXCResultCommand(stdout: kSampleResultJsonWithNoProvisioningProfileIssue), + _setUpRsyncCommand(), + ]), + Platform: () => macosPlatform, + XcodeProjectInterpreter: () => FakeXcodeProjectInterpreterWithBuildSettings(developmentTeam: null), + }); + + testUsingContext('General provisioning profile issue error message is not displayed if no development team issue is detected first.', () async { + final BuildCommand command = BuildCommand(); + + _createMinimalMockProjectFiles(); + + await expectLater( + createTestCommandRunner(command).run(const ['build', 'ios', '--no-pub']), + throwsToolExit(), + ); + + expect(testLogger.errorText, contains(noDevelopmentTeamInstruction)); + expect(testLogger.errorText, isNot(contains('It appears that there was a problem signing your application prior to installation on the device.'))); + }, overrides: { + FileSystem: () => fileSystem, + ProcessManager: () => FakeProcessManager.list([ + xattrCommand, + _setUpFakeXcodeBuildHandler( + exitCode: 1, + onRun: () { + fileSystem.systemTempDirectory.childDirectory(_xcBundleFilePath).createSync(); + } + ), + _setUpXCResultCommand(stdout: kSampleResultJsonWithProvisionIssue), + _setUpRsyncCommand(), + ]), + Platform: () => macosPlatform, + XcodeProjectInterpreter: () => FakeXcodeProjectInterpreterWithBuildSettings(developmentTeam: null), + }); }); group('xcresults simulator', () { diff --git a/packages/flutter_tools/test/commands.shard/hermetic/build_ipa_test.dart b/packages/flutter_tools/test/commands.shard/hermetic/build_ipa_test.dart index 6d45b425f87..cd940589bdb 100644 --- a/packages/flutter_tools/test/commands.shard/hermetic/build_ipa_test.dart +++ b/packages/flutter_tools/test/commands.shard/hermetic/build_ipa_test.dart @@ -721,7 +721,7 @@ void main() { expect(testLogger.errorText, contains('It appears that there was a problem signing your application prior to installation on the device.')); expect(testLogger.errorText, contains('Verify that the Bundle Identifier in your project is your signing id in Xcode')); expect(testLogger.errorText, contains('open ios/Runner.xcworkspace')); - expect(testLogger.errorText, contains("Also try selecting 'Product > Build' to fix the problem:")); + expect(testLogger.errorText, contains("Also try selecting 'Product > Build' to fix the problem.")); expect(fakeProcessManager, hasNoRemainingExpectations); }, overrides: { FileSystem: () => fileSystem, diff --git a/packages/flutter_tools/test/general.shard/ios/mac_test.dart b/packages/flutter_tools/test/general.shard/ios/mac_test.dart index f641e655a48..44845eae805 100644 --- a/packages/flutter_tools/test/general.shard/ios/mac_test.dart +++ b/packages/flutter_tools/test/general.shard/ios/mac_test.dart @@ -10,6 +10,7 @@ import 'package:flutter_tools/src/base/logger.dart'; import 'package:flutter_tools/src/base/process.dart'; import 'package:flutter_tools/src/build_info.dart'; import 'package:flutter_tools/src/cache.dart'; +import 'package:flutter_tools/src/ios/code_signing.dart'; import 'package:flutter_tools/src/ios/iproxy.dart'; import 'package:flutter_tools/src/ios/mac.dart'; import 'package:flutter_tools/src/project.dart'; @@ -166,7 +167,11 @@ void main() { )); }); - testWithoutContext('No provisioning profile shows message', () async { + testWithoutContext('fallback to stdout: No provisioning profile shows message', () async { + final Map buildSettingsWithDevTeam = { + 'PRODUCT_BUNDLE_IDENTIFIER': 'test.app', + 'DEVELOPMENT_TEAM': 'a team', + }; final XcodeBuildResult buildResult = XcodeBuildResult( success: false, stdout: ''' @@ -194,7 +199,7 @@ Xcode's output: === CLEAN TARGET Runner OF PROJECT Runner WITH CONFIGURATION Release === Check dependencies - [BCEROR]No profiles for 'com.example.test' were found: Xcode couldn't find a provisioning profile matching 'com.example.test'. + [BCEROR]"Runner" requires a provisioning profile. Select a provisioning profile in the Signing & Capabilities editor. [BCEROR]Code signing is required for product type 'Application' in SDK 'iOS 10.3' [BCEROR]Code signing is required for product type 'Application' in SDK 'iOS 10.3' [BCEROR]Code signing is required for product type 'Application' in SDK 'iOS 10.3' @@ -228,14 +233,14 @@ Error launching application on iPhone.''', buildCommands: ['xcrun', 'xcodebuild', 'blah'], appDirectory: '/blah/blah', environmentType: EnvironmentType.physical, - buildSettings: buildSettings, + buildSettings: buildSettingsWithDevTeam, ), ); await diagnoseXcodeBuildFailure(buildResult, testUsage, logger); expect( logger.errorText, - contains("No Provisioning Profile was found for your project's Bundle Identifier or your \ndevice."), + contains(noProvisioningProfileInstruction), ); }); @@ -319,80 +324,6 @@ Could not build the precompiled application for the device.''', contains('Building a deployable iOS app requires a selected Development Team with a \nProvisioning Profile.'), ); }); - - testWithoutContext('embedded and linked framework iOS mismatch shows message', () async { - final XcodeBuildResult buildResult = XcodeBuildResult( - success: false, - stdout: ''' -Launching lib/main.dart on iPhone in debug mode... -Automatically signing iOS for device deployment using specified development team in Xcode project: blah -Xcode build done. 5.7s -Failed to build iOS app -Error output from Xcode build: -↳ -** BUILD FAILED ** -Xcode's output: -↳ -note: Using new build system -note: Building targets in parallel -note: Planning build -note: Constructing build description -error: Building for iOS Simulator, but the linked and embedded framework 'App.framework' was built for iOS. (in target 'Runner' from project 'Runner') -Could not build the precompiled application for the device. - -Error launching application on iPhone. -Exited (sigterm)''', - xcodeBuildExecution: XcodeBuildExecution( - buildCommands: ['xcrun', 'xcodebuild', 'blah'], - appDirectory: '/blah/blah', - environmentType: EnvironmentType.physical, - buildSettings: buildSettings, - ), - ); - - await diagnoseXcodeBuildFailure(buildResult, testUsage, logger); - expect( - logger.errorText, - contains('Your Xcode project requires migration.'), - ); - }); - - testWithoutContext('embedded and linked framework iOS simulator mismatch shows message', () async { - final XcodeBuildResult buildResult = XcodeBuildResult( - success: false, - stdout: ''' -Launching lib/main.dart on iPhone in debug mode... -Automatically signing iOS for device deployment using specified development team in Xcode project: blah -Xcode build done. 5.7s -Failed to build iOS app -Error output from Xcode build: -↳ -** BUILD FAILED ** -Xcode's output: -↳ -note: Using new build system -note: Building targets in parallel -note: Planning build -note: Constructing build description -error: Building for iOS, but the linked and embedded framework 'App.framework' was built for iOS Simulator. (in target 'Runner' from project 'Runner') -Could not build the precompiled application for the device. - -Error launching application on iPhone. -Exited (sigterm)''', - xcodeBuildExecution: XcodeBuildExecution( - buildCommands: ['xcrun', 'xcodebuild', 'blah'], - appDirectory: '/blah/blah', - environmentType: EnvironmentType.physical, - buildSettings: buildSettings, - ), - ); - - await diagnoseXcodeBuildFailure(buildResult, testUsage, logger); - expect( - logger.errorText, - contains('Your Xcode project requires migration.'), - ); - }); }); group('Upgrades project.pbxproj for old asset usage', () { diff --git a/packages/flutter_tools/test/general.shard/ios/xcresult_test_data.dart b/packages/flutter_tools/test/general.shard/ios/xcresult_test_data.dart index a638e041f25..645afd1e876 100644 --- a/packages/flutter_tools/test/general.shard/ios/xcresult_test_data.dart +++ b/packages/flutter_tools/test/general.shard/ios/xcresult_test_data.dart @@ -181,6 +181,82 @@ const String kSampleResultJsonWithIssues = r''' } '''; +/// An example xcresult bundle json that contains some warning and some errors. +const String kSampleResultJsonWithNoProvisioningProfileIssue = r''' +{ + "issues" : { + "_type" : { + "_name" : "ResultIssueSummaries" + }, + "errorSummaries" : { + "_type" : { + "_name" : "Array" + }, + "_values" : [ + { + "_type" : { + "_name" : "IssueSummary" + }, + "documentLocationInCreatingWorkspace" : { + "_type" : { + "_name" : "DocumentLocation" + }, + "concreteTypeName" : { + "_type" : { + "_name" : "String" + }, + "_value" : "DVTTextDocumentLocation" + }, + "url" : { + "_type" : { + "_name" : "String" + }, + "_value" : "file:\/\/\/Users\/m\/Projects\/test_create\/ios\/Runner\/AppDelegate.m#CharacterRangeLen=0&CharacterRangeLoc=263&EndingColumnNumber=56&EndingLineNumber=7&LocationEncoding=1&StartingColumnNumber=56&StartingLineNumber=7" + } + }, + "issueType" : { + "_type" : { + "_name" : "String" + }, + "_value" : "Error" + }, + "message" : { + "_type" : { + "_name" : "String" + }, + "_value" : "Runner requires a provisioning profile. Select a provisioning profile in the Signing & Capabilities editor" + } + } + ] + }, + "warningSummaries" : { + "_type" : { + "_name" : "Array" + }, + "_values" : [ + { + "_type" : { + "_name" : "IssueSummary" + }, + "issueType" : { + "_type" : { + "_name" : "String" + }, + "_value" : "Warning" + }, + "message" : { + "_type" : { + "_name" : "String" + }, + "_value" : "The iOS deployment target 'IPHONEOS_DEPLOYMENT_TARGET' is set to 8.0, but the range of supported deployment target versions is 9.0 to 14.0.99." + } + } + ] + } + } +} +'''; + /// An example xcresult bundle json that contains some warning and some errors. const String kSampleResultJsonWithIssuesAndInvalidUrl = r''' {