Add more instructions and handling for first time iOS run (#10521)

* Before tests

* Add the part to trust the cert on the device

* flip the error checks since some are more specific and are more actionable

* add tests

* review
diff --git a/packages/flutter_tools/lib/src/commands/build_ios.dart b/packages/flutter_tools/lib/src/commands/build_ios.dart
index 93792ec..eb72d4a 100644
--- a/packages/flutter_tools/lib/src/commands/build_ios.dart
+++ b/packages/flutter_tools/lib/src/commands/build_ios.dart
@@ -45,7 +45,7 @@
     if (getCurrentHostPlatform() != HostPlatform.darwin_x64)
       throwToolExit('Building for iOS is only supported on the Mac.');
 
-    final IOSApp app = applicationPackages.getPackageForPlatform(TargetPlatform.ios);
+    final BuildableIOSApp app = applicationPackages.getPackageForPlatform(TargetPlatform.ios);
 
     if (app == null)
       throwToolExit('Application not configured for iOS');
@@ -73,7 +73,7 @@
     );
 
     if (!result.success) {
-      await diagnoseXcodeBuildFailure(result);
+      await diagnoseXcodeBuildFailure(result, app);
       throwToolExit('Encountered error while building for $logTarget.');
     }
 
diff --git a/packages/flutter_tools/lib/src/ios/code_signing.dart b/packages/flutter_tools/lib/src/ios/code_signing.dart
index 5a917db..169332d 100644
--- a/packages/flutter_tools/lib/src/ios/code_signing.dart
+++ b/packages/flutter_tools/lib/src/ios/code_signing.dart
@@ -14,34 +14,60 @@
 import '../base/terminal.dart';
 import '../globals.dart';
 
+/// User message when no development certificates are found in the keychain.
+///
+/// The user likely never did any iOS development.
 const String noCertificatesInstruction = '''
 ═══════════════════════════════════════════════════════════════════════════════════
 No valid code signing certificates were found
-Please ensure that you have a valid Development Team with valid iOS Development Certificates
-associated with your Apple ID by:
-  1- Opening the Xcode application
-  2- Go to Xcode->Preferences->Accounts
-  3- Make sure that you're signed in with your Apple ID via the '+' button on the bottom left
-  4- Make sure that you have development certificates available by signing up to Apple
-     Developer Program and/or downloading available profiles as needed.
+You can connect to your Apple Developer account by signing in with your Apple ID in Xcode
+and create an iOS Development Certificate as well as a Provisioning Profile for your project by:
+$fixWithDevelopmentTeamInstruction
+  5- Trust your newly created Development Certificate on your iOS device
+     via Settings > General > Device Management > [your new certificate] > Trust
+
 For more information, please visit:
   https://developer.apple.com/library/content/documentation/IDEs/Conceptual/AppDistributionGuide/MaintainingCertificates/MaintainingCertificates.html
 
 Or run on an iOS simulator without code signing
 ═══════════════════════════════════════════════════════════════════════════════════''';
+/// User message when there are no provisioning profile for the current app bundle identifier.
+///
+/// The user did iOS development but never on this project and/or device.
+const String noProvisioningProfileInstruction = '''
+═══════════════════════════════════════════════════════════════════════════════════
+No Provisioning Profile was found for your project's Bundle Identifier or your device.
+You can create a new Provisioning Profile for your project in Xcode for your
+team by:
+$fixWithDevelopmentTeamInstruction
+
+For more information, please visit:
+  https://flutter.io/setup/#deploy-to-ios-devices
+
+Or run on an iOS simulator without code signing
+═══════════════════════════════════════════════════════════════════════════════════''';
+/// Fallback error message for signing issues.
+///
+/// Couldn't auto sign the app but can likely solved by retracing the signing flow in Xcode.
 const String noDevelopmentTeamInstruction = '''
 ═══════════════════════════════════════════════════════════════════════════════════
 Building a deployable iOS app requires a selected Development Team with a Provisioning Profile
 Please ensure that a Development Team is selected by:
-  1- Opening the Flutter project's Xcode target with
+$fixWithDevelopmentTeamInstruction
+
+For more information, please visit:
+  https://flutter.io/setup/#deploy-to-ios-devices
+
+Or run on an iOS simulator without code signing
+═══════════════════════════════════════════════════════════════════════════════════''';
+const String fixWithDevelopmentTeamInstruction = '''
+  1- Open the Flutter project's Xcode target with
        open ios/Runner.xcworkspace
   2- Select the 'Runner' project in the navigator then the 'Runner' target
      in the project settings
-  3- In the 'General' tab, make sure a 'Development Team' is selected\n
-For more information, please visit:
-  https://flutter.io/setup/#deploy-to-ios-devices\n
-Or run on an iOS simulator
-═══════════════════════════════════════════════════════════════════════════════════''';
+  3- In the 'General' tab, make sure a 'Development Team' is selected. You may need to add
+     your Apple ID first.
+  4- Build or run your project again''';
 
 final RegExp _securityFindIdentityDeveloperIdentityExtractionPattern =
     new RegExp(r'^\s*\d+\).+"(.+Developer.+)"$');
diff --git a/packages/flutter_tools/lib/src/ios/devices.dart b/packages/flutter_tools/lib/src/ios/devices.dart
index 0b4d0be..a1cb175 100644
--- a/packages/flutter_tools/lib/src/ios/devices.dart
+++ b/packages/flutter_tools/lib/src/ios/devices.dart
@@ -208,7 +208,7 @@
       final XcodeBuildResult buildResult = await buildXcodeProject(app: app, mode: mode, target: mainPath, buildForDevice: true);
       if (!buildResult.success) {
         printError('Could not build the precompiled application for the device.');
-        await diagnoseXcodeBuildFailure(buildResult);
+        await diagnoseXcodeBuildFailure(buildResult, app);
         printError('');
         return new LaunchResult.failed();
       }
@@ -242,7 +242,7 @@
       // the port picked and scrape that later.
     }
 
-    if (debuggingOptions.enableSoftwareRendering) 
+    if (debuggingOptions.enableSoftwareRendering)
       launchArguments.add('--enable-software-rendering');
 
     if (platformArgs['trace-startup'] ?? false)
diff --git a/packages/flutter_tools/lib/src/ios/mac.dart b/packages/flutter_tools/lib/src/ios/mac.dart
index 84f6aab..16430aa 100644
--- a/packages/flutter_tools/lib/src/ios/mac.dart
+++ b/packages/flutter_tools/lib/src/ios/mac.dart
@@ -147,7 +147,7 @@
   }
 
   String developmentTeam;
-  if (codesign && mode != BuildMode.release && buildForDevice)
+  if (codesign && buildForDevice)
     developmentTeam = await getCodeSigningIdentityDevelopmentTeam(app);
 
   // Before the build, all service definitions must be updated and the dylibs
@@ -246,51 +246,40 @@
   }
 }
 
-Future<Null> diagnoseXcodeBuildFailure(XcodeBuildResult result) async {
-  final File plistFile = fs.file('ios/Runner/Info.plist');
-  if (plistFile.existsSync()) {
-    final String plistContent = plistFile.readAsStringSync();
-    if (plistContent.contains('com.yourcompany')) {
-      printError('');
-      printError('It appears that your application still contains the default signing identifier.');
-      printError("Try replacing 'com.yourcompany' with your signing id");
-      printError('in ${plistFile.absolute.path}');
-      return;
-    }
+Future<Null> diagnoseXcodeBuildFailure(XcodeBuildResult result, BuildableIOSApp app) async {
+  if (result.xcodeBuildExecution != null &&
+      result.xcodeBuildExecution.buildForPhysicalDevice &&
+      result.stdout?.contains('BCEROR') == true &&
+      // May need updating if Xcode changes its outputs.
+      result.stdout?.contains('Xcode couldn\'t find a provisioning profile matching') == true) {
+    printError(noProvisioningProfileInstruction, emphasis: true);
+    return;
+  }
+  if (result.xcodeBuildExecution != null &&
+      result.xcodeBuildExecution.buildForPhysicalDevice &&
+      // Make sure the user has specified at least the DEVELOPMENT_TEAM (for automatic Xcode 8)
+      // signing or the PROVISIONING_PROFILE (for manual signing or Xcode 7).
+      !(app.buildSettings?.containsKey('DEVELOPMENT_TEAM')) == true || app.buildSettings?.containsKey('PROVISIONING_PROFILE') == true) {
+    printError(noDevelopmentTeamInstruction, emphasis: true);
+    return;
+  }
+  if (app.id?.contains('com.yourcompany') ?? false) {
+    printError('');
+    printError('It appears that your application still contains the default signing identifier.');
+    printError("Try replacing 'com.yourcompany' with your signing id in Xcode:");
+    printError('  open ios/Runner.xcworkspace');
+    return;
   }
   if (result.stdout?.contains('Code Sign error') == true) {
     printError('');
     printError('It appears that there was a problem signing your application prior to installation on the device.');
     printError('');
-    if (plistFile.existsSync()) {
-      printError('Verify that the CFBundleIdentifier in the Info.plist file is your signing id');
-      printError('  ${plistFile.absolute.path}');
-      printError('');
-    }
-    printError("Try launching Xcode and selecting 'Product > Build' to fix the problem:");
-    printError("  open ios/Runner.xcworkspace");
+    printError('Verify that the Bundle Identifier in your project is your signing id in Xcode');
+    printError('  open ios/Runner.xcworkspace');
+    printError('');
+    printError("Also try selecting 'Product > Build' to fix the problem:");
     return;
   }
-  if (result.xcodeBuildExecution != null) {
-    assert(result.xcodeBuildExecution.buildForPhysicalDevice != null);
-    assert(result.xcodeBuildExecution.buildCommands != null);
-    assert(result.xcodeBuildExecution.appDirectory != null);
-    if (result.xcodeBuildExecution.buildForPhysicalDevice &&
-        result.xcodeBuildExecution.buildCommands.contains('build')) {
-      final RunResult checkBuildSettings = await runAsync(
-        result.xcodeBuildExecution.buildCommands..add('-showBuildSettings'),
-        workingDirectory: result.xcodeBuildExecution.appDirectory,
-        allowReentrantFlutter: true
-      );
-      // Make sure the user has specified at least the DEVELOPMENT_TEAM (for automatic Xcode 8)
-      // signing or the PROVISIONING_PROFILE (for manual signing or Xcode 7).
-      if (checkBuildSettings.exitCode == 0 &&
-          !checkBuildSettings.stdout?.contains(new RegExp(r'\bDEVELOPMENT_TEAM\b')) == true &&
-          !checkBuildSettings.stdout?.contains(new RegExp(r'\bPROVISIONING_PROFILE\b')) == true) {
-        printError(noDevelopmentTeamInstruction, emphasis: true);
-      }
-    }
-  }
 }
 
 class XcodeBuildResult {