@@ -574,37 +574,14 @@ Future<void> diagnoseXcodeBuildFailure(XcodeBuildResult result, Usage flutterUsa
574574 ).send ();
575575 }
576576
577- // Building for iOS Simulator, but the linked and embedded framework 'App.framework' was built for iOS.
578- // or
579- // Building for iOS, but the linked and embedded framework 'App.framework' was built for iOS Simulator.
580- if ((result.stdout? .contains ('Building for iOS' ) ?? false )
581- && (result.stdout? .contains ('but the linked and embedded framework' ) ?? false )
582- && (result.stdout? .contains ('was built for iOS' ) ?? false )) {
583- logger.printError ('' );
584- logger.printError ('Your Xcode project requires migration. See https://flutter.dev/docs/development/ios-project-migration for details.' );
585- logger.printError ('' );
586- logger.printError ('You can temporarily work around this issue by running:' );
587- logger.printError (' flutter clean' );
588- return ;
589- }
590- if (xcodeBuildExecution != null
591- && xcodeBuildExecution.environmentType == EnvironmentType .physical
592- && (result.stdout? .contains ('BCEROR' ) ?? false )
593- // May need updating if Xcode changes its outputs.
594- && (result.stdout? .contains ("Xcode couldn't find a provisioning profile matching" ) ?? false )) {
595- logger.printError (noProvisioningProfileInstruction, emphasis: true );
596- return ;
597- }
598- // Make sure the user has specified one of:
599- // * DEVELOPMENT_TEAM (automatic signing)
600- // * PROVISIONING_PROFILE (manual signing)
601- if (xcodeBuildExecution != null &&
602- xcodeBuildExecution.environmentType == EnvironmentType .physical &&
603- ! < String > ['DEVELOPMENT_TEAM' , 'PROVISIONING_PROFILE' ].any (
604- xcodeBuildExecution.buildSettings.containsKey)) {
605- logger.printError (noDevelopmentTeamInstruction, emphasis: true );
606- return ;
577+ // Handle errors.
578+ final bool issueDetected = _handleIssues (result.xcResult, logger, xcodeBuildExecution);
579+
580+ if (! issueDetected && xcodeBuildExecution != null ) {
581+ // Fallback to use stdout to detect and print issues.
582+ _parseIssueInStdout (xcodeBuildExecution, logger, result);
607583 }
584+
608585 if (xcodeBuildExecution != null
609586 && xcodeBuildExecution.environmentType == EnvironmentType .physical
610587 && (xcodeBuildExecution.buildSettings['PRODUCT_BUNDLE_IDENTIFIER' ]? .contains ('com.example' ) ?? false )) {
@@ -614,19 +591,6 @@ Future<void> diagnoseXcodeBuildFailure(XcodeBuildResult result, Usage flutterUsa
614591 logger.printError (' open ios/Runner.xcworkspace' );
615592 return ;
616593 }
617-
618- // Handle xcresult errors.
619- final XCResult ? xcResult = result.xcResult;
620- if (xcResult == null ) {
621- return ;
622- }
623- if (! xcResult.parseSuccess) {
624- globals.printTrace ('XCResult parsing error: ${xcResult .parsingErrorMessage }' );
625- return ;
626- }
627- for (final XCResultIssue issue in xcResult.issues) {
628- _handleXCResultIssue (issue: issue, logger: logger);
629- }
630594}
631595
632596/// xcodebuild <buildaction> parameter (see man xcodebuild for details).
@@ -724,7 +688,7 @@ bool upgradePbxProjWithFlutterAssets(IosProject project, Logger logger) {
724688 return true ;
725689}
726690
727- void _handleXCResultIssue ({required XCResultIssue issue, required Logger logger}) {
691+ _XCResultIssueHandlingResult _handleXCResultIssue ({required XCResultIssue issue, required Logger logger}) {
728692 // Issue summary from xcresult.
729693 final StringBuffer issueSummaryBuffer = StringBuffer ();
730694 issueSummaryBuffer.write (issue.subType ?? 'Unknown' );
@@ -744,16 +708,89 @@ void _handleXCResultIssue({required XCResultIssue issue, required Logger logger}
744708 break ;
745709 }
746710
747- // Add more custom output for flutter users.
748- if (issue.message != null && issue.message! .toLowerCase ().contains ('provisioning profile' )) {
711+ final String ? message = issue.message;
712+ if (message == null ) {
713+ return _XCResultIssueHandlingResult (requiresProvisioningProfile: false , hasProvisioningProfileIssue: false );
714+ }
715+
716+ // Add more error messages for flutter users for some special errors.
717+ if (message.toLowerCase ().contains ('requires a provisioning profile.' )) {
718+ return _XCResultIssueHandlingResult (requiresProvisioningProfile: true , hasProvisioningProfileIssue: true );
719+ } else if (message.toLowerCase ().contains ('provisioning profile' )) {
720+ return _XCResultIssueHandlingResult (requiresProvisioningProfile: false , hasProvisioningProfileIssue: true );
721+ }
722+ return _XCResultIssueHandlingResult (requiresProvisioningProfile: false , hasProvisioningProfileIssue: false );
723+ }
724+
725+ // Returns `true` if at least one issue is detected.
726+ bool _handleIssues (XCResult ? xcResult, Logger logger, XcodeBuildExecution ? xcodeBuildExecution) {
727+ bool requiresProvisioningProfile = false ;
728+ bool hasProvisioningProfileIssue = false ;
729+ bool issueDetected = false ;
730+
731+ if (xcResult != null && xcResult.parseSuccess) {
732+ for (final XCResultIssue issue in xcResult.issues) {
733+ final _XCResultIssueHandlingResult handlingResult = _handleXCResultIssue (issue: issue, logger: logger);
734+ if (handlingResult.hasProvisioningProfileIssue) {
735+ hasProvisioningProfileIssue = true ;
736+ }
737+ if (handlingResult.requiresProvisioningProfile) {
738+ requiresProvisioningProfile = true ;
739+ }
740+ issueDetected = true ;
741+ }
742+ } else if (xcResult != null ) {
743+ globals.printTrace ('XCResult parsing error: ${xcResult .parsingErrorMessage }' );
744+ }
745+
746+ if (requiresProvisioningProfile) {
747+ logger.printError (noProvisioningProfileInstruction, emphasis: true );
748+ } else if (_missingDevelopmentTeam (xcodeBuildExecution)) {
749+ issueDetected = true ;
750+ logger.printError (noDevelopmentTeamInstruction, emphasis: true );
751+ } else if (hasProvisioningProfileIssue) {
749752 logger.printError ('' );
750753 logger.printError ('It appears that there was a problem signing your application prior to installation on the device.' );
751754 logger.printError ('' );
752755 logger.printError ('Verify that the Bundle Identifier in your project is your signing id in Xcode' );
753756 logger.printError (' open ios/Runner.xcworkspace' );
754757 logger.printError ('' );
755- logger.printError ("Also try selecting 'Product > Build' to fix the problem: " );
758+ logger.printError ("Also try selecting 'Product > Build' to fix the problem. " );
756759 }
760+ return issueDetected;
761+ }
762+
763+ // Return 'true' a missing development team issue is detected.
764+ bool _missingDevelopmentTeam (XcodeBuildExecution ? xcodeBuildExecution) {
765+ // Make sure the user has specified one of:
766+ // * DEVELOPMENT_TEAM (automatic signing)
767+ // * PROVISIONING_PROFILE (manual signing)
768+ return xcodeBuildExecution != null && xcodeBuildExecution.environmentType == EnvironmentType .physical &&
769+ ! < String > ['DEVELOPMENT_TEAM' , 'PROVISIONING_PROFILE' ].any (
770+ xcodeBuildExecution.buildSettings.containsKey);
771+ }
772+ // Detects and handles errors from stdout.
773+ //
774+ // As detecting issues in stdout is not usually accurate, this should be used as a fallback when other issue detecting methods failed.
775+ void _parseIssueInStdout (XcodeBuildExecution xcodeBuildExecution, Logger logger, XcodeBuildResult result) {
776+ if (xcodeBuildExecution.environmentType == EnvironmentType .physical
777+ // May need updating if Xcode changes its outputs.
778+ && (result.stdout? .contains ('requires a provisioning profile. Select a provisioning profile in the Signing & Capabilities editor' ) ?? false )) {
779+ logger.printError (noProvisioningProfileInstruction, emphasis: true );
780+ return ;
781+ }
782+ }
783+
784+ // The result of [_handleXCResultIssue].
785+ class _XCResultIssueHandlingResult {
786+
787+ _XCResultIssueHandlingResult ({required this .requiresProvisioningProfile, required this .hasProvisioningProfileIssue});
788+
789+ // An issue indicates that user didn't provide the provisioning profile.
790+ final bool requiresProvisioningProfile;
791+
792+ // An issue indicates that there is a provisioning profile issue.
793+ final bool hasProvisioningProfileIssue;
757794}
758795
759796const String _kResultBundlePath = 'temporary_xcresult_bundle' ;
0 commit comments