make the ios development path less mandatory
diff --git a/packages/flutter_tools/lib/src/ios/device_ios.dart b/packages/flutter_tools/lib/src/ios/device_ios.dart
index f705fd0..908cb3e 100644
--- a/packages/flutter_tools/lib/src/ios/device_ios.dart
+++ b/packages/flutter_tools/lib/src/ios/device_ios.dart
@@ -86,6 +86,9 @@
bool get supportsStartPaused => false;
static List<IOSDevice> getAttachedDevices([IOSDevice mockIOS]) {
+ if (!doctor.iosWorkflow.hasIdeviceId)
+ return <IOSDevice>[];
+
List<IOSDevice> devices = [];
for (String id in _getAttachedDeviceIDs(mockIOS)) {
String name = _getDeviceName(id, mockIOS);
@@ -176,7 +179,7 @@
// Step 1: Install the precompiled application if necessary
bool buildResult = await _buildIOSXcodeProject(app, buildForDevice: true);
if (!buildResult) {
- printError('Could not build the precompiled application for the device');
+ printError('Could not build the precompiled application for the device.');
return false;
}
@@ -184,7 +187,7 @@
Directory bundle = new Directory(path.join(app.localPath, 'build', 'Release-iphoneos', 'Runner.app'));
bool bundleExists = bundle.existsSync();
if (!bundleExists) {
- printError('Could not find the built application bundle at ${bundle.path}');
+ printError('Could not find the built application bundle at ${bundle.path}.');
return false;
}
@@ -202,7 +205,7 @@
]);
if (installationResult != 0) {
- printError('Could not install ${bundle.path} on $id');
+ printError('Could not install ${bundle.path} on $id.');
return false;
}
@@ -246,6 +249,9 @@
IOSSimulator(String id, { this.name }) : super(id);
static List<IOSSimulator> getAttachedDevices() {
+ if (!xcode.isInstalled)
+ return <IOSSimulator>[];
+
return SimControl.getConnectedDevices().map((SimDevice device) {
return new IOSSimulator(device.udid, name: device.name);
}).toList();
@@ -317,7 +323,7 @@
// Step 1: Build the Xcode project
bool buildResult = await _buildIOSXcodeProject(app, buildForDevice: false);
if (!buildResult) {
- printError('Could not build the application for the simulator');
+ printError('Could not build the application for the simulator.');
return false;
}
@@ -325,7 +331,7 @@
Directory bundle = new Directory(path.join(app.localPath, 'build', 'Release-iphonesimulator', 'Runner.app'));
bool bundleExists = await bundle.exists();
if (!bundleExists) {
- printError('Could not find the built application bundle at ${bundle.path}');
+ printError('Could not find the built application bundle at ${bundle.path}.');
return false;
}
@@ -476,7 +482,8 @@
String category = match.group(1);
String content = match.group(2);
if (category == 'Game Center' || category == 'itunesstored' || category == 'nanoregistrylaunchd' ||
- category == 'mstreamd' || category == 'syncdefaultsd' || category == 'companionappd' || category == 'searchd')
+ category == 'mstreamd' || category == 'syncdefaultsd' || category == 'companionappd' ||
+ category == 'searchd')
return null;
_lastWasFiltered = false;
diff --git a/packages/flutter_tools/lib/src/ios/ios_workflow.dart b/packages/flutter_tools/lib/src/ios/ios_workflow.dart
new file mode 100644
index 0000000..8dfc94f
--- /dev/null
+++ b/packages/flutter_tools/lib/src/ios/ios_workflow.dart
@@ -0,0 +1,82 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import 'dart:io';
+
+import '../base/globals.dart';
+import '../base/process.dart';
+import '../doctor.dart';
+
+class IOSWorkflow extends Workflow {
+ IOSWorkflow() : super('iOS');
+
+ bool get appliesToHostPlatform => Platform.isMacOS;
+
+ // We need xcode (+simctl) to list simulator devices, and idevice_id to list real devices.
+ bool get canListDevices => xcode.isInstalled;
+
+ // We need xcode to launch simulator devices, and ideviceinstaller and ios-deploy
+ // for real devices.
+ bool get canLaunchDevices => xcode.isInstalled;
+
+ void diagnose() {
+ Validator iosValidator = new Validator('Develop for iOS devices');
+
+ Function _xcodeExists = () {
+ return xcode.isInstalled ? ValidationType.installed : ValidationType.missing;
+ };
+
+ Function _brewExists = () {
+ return exitsHappy(<String>['brew', '-v'])
+ ? ValidationType.installed : ValidationType.missing;
+ };
+
+ Function _ideviceinstallerExists = () {
+ return exitsHappy(<String>['ideviceinstaller', '-h'])
+ ? ValidationType.installed : ValidationType.missing;
+ };
+
+ Function _iosdeployExists = () {
+ return hasIdeviceId ? ValidationType.installed : ValidationType.missing;
+ };
+
+ iosValidator.addValidator(new Validator(
+ 'XCode',
+ description: 'enable development for iOS devices',
+ resolution: 'Download at https://developer.apple.com/xcode/download/',
+ validatorFunction: _xcodeExists
+ ));
+
+ iosValidator.addValidator(new Validator(
+ 'brew',
+ description: 'install additional development packages',
+ resolution: 'Download at http://brew.sh/',
+ validatorFunction: _brewExists
+ ));
+
+ iosValidator.addValidator(new Validator(
+ 'ideviceinstaller',
+ description: 'discover connected iOS devices',
+ resolution: "Install via 'brew install ideviceinstaller'",
+ validatorFunction: _ideviceinstallerExists
+ ));
+
+ iosValidator.addValidator(new Validator(
+ 'ios-deploy',
+ description: 'deploy to connected iOS devices',
+ resolution: "Install via 'brew install ios-deploy'",
+ validatorFunction: _iosdeployExists
+ ));
+
+ iosValidator.validate().print();
+ }
+
+ bool get hasIdeviceId => exitsHappy(<String>['idevice_id', '-h']);
+
+ /// Return whether the tooling to list and deploy to real iOS devices (not the
+ /// simulator) is installed on the user's machine.
+ bool get canWorkWithIOSDevices {
+ return exitsHappy(<String>['ideviceinstaller', '-h']) && hasIdeviceId;
+ }
+}
diff --git a/packages/flutter_tools/lib/src/ios/mac.dart b/packages/flutter_tools/lib/src/ios/mac.dart
new file mode 100644
index 0000000..47f5e79
--- /dev/null
+++ b/packages/flutter_tools/lib/src/ios/mac.dart
@@ -0,0 +1,14 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import '../base/context.dart';
+import '../base/process.dart';
+
+class XCode {
+ static void initGlobal() {
+ context[XCode] = new XCode();
+ }
+
+ bool get isInstalled => exitsHappy(<String>['xcode-select', '--print-path']);
+}