2016-01-06 01:11:53 +00:00
|
|
|
/**
|
|
|
|
* Copyright (c) 2015-present, Facebook, Inc.
|
|
|
|
* All rights reserved.
|
|
|
|
*
|
|
|
|
* This source code is licensed under the BSD-style license found in the
|
|
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
|
|
|
|
const child_process = require('child_process');
|
|
|
|
const fs = require('fs');
|
|
|
|
const path = require('path');
|
|
|
|
const findXcodeProject = require('./findXcodeProject');
|
|
|
|
const parseIOSSimulatorsList = require('./parseIOSSimulatorsList');
|
|
|
|
|
2016-07-30 15:59:16 +00:00
|
|
|
function runIOS(argv, config, args) {
|
|
|
|
process.chdir(args.projectPath);
|
2016-01-06 01:11:53 +00:00
|
|
|
const xcodeProject = findXcodeProject(fs.readdirSync('.'));
|
|
|
|
if (!xcodeProject) {
|
2016-07-30 15:59:16 +00:00
|
|
|
throw new Error('Could not find Xcode project files in ios folder');
|
2016-01-06 01:11:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
const inferredSchemeName = path.basename(xcodeProject.name, path.extname(xcodeProject.name));
|
2016-04-01 15:02:40 +00:00
|
|
|
const scheme = args.scheme || inferredSchemeName;
|
2016-01-06 01:11:53 +00:00
|
|
|
console.log(`Found Xcode ${xcodeProject.isWorkspace ? 'workspace' : 'project'} ${xcodeProject.name}`);
|
|
|
|
|
|
|
|
const simulators = parseIOSSimulatorsList(
|
|
|
|
child_process.execFileSync('xcrun', ['simctl', 'list', 'devices'], {encoding: 'utf8'})
|
|
|
|
);
|
|
|
|
const selectedSimulator = matchingSimulator(simulators, args.simulator);
|
|
|
|
if (!selectedSimulator) {
|
2016-07-30 15:59:16 +00:00
|
|
|
throw new Error(`Cound't find ${args.simulator} simulator`);
|
2016-01-06 01:11:53 +00:00
|
|
|
}
|
|
|
|
|
2016-07-30 15:59:16 +00:00
|
|
|
const simulatorFullName = formattedSimulatorName(selectedSimulator);
|
2016-01-06 01:11:53 +00:00
|
|
|
console.log(`Launching ${simulatorFullName}...`);
|
|
|
|
try {
|
|
|
|
child_process.spawnSync('xcrun', ['instruments', '-w', simulatorFullName]);
|
2016-07-30 15:59:16 +00:00
|
|
|
} catch (e) {
|
2016-01-06 01:11:53 +00:00
|
|
|
// instruments always fail with 255 because it expects more arguments,
|
|
|
|
// but we want it to only launch the simulator
|
|
|
|
}
|
|
|
|
|
|
|
|
const xcodebuildArgs = [
|
|
|
|
xcodeProject.isWorkspace ? '-workspace' : '-project', xcodeProject.name,
|
2016-03-07 22:25:27 +00:00
|
|
|
'-scheme', scheme,
|
2016-01-06 01:11:53 +00:00
|
|
|
'-destination', `id=${selectedSimulator.udid}`,
|
|
|
|
'-derivedDataPath', 'build',
|
|
|
|
];
|
|
|
|
console.log(`Building using "xcodebuild ${xcodebuildArgs.join(' ')}"`);
|
2016-07-30 15:59:16 +00:00
|
|
|
child_process.spawnSync('xcodebuild', xcodebuildArgs, {stdio: 'inherit'});
|
2016-01-06 01:11:53 +00:00
|
|
|
|
2016-07-30 15:59:16 +00:00
|
|
|
const appPath = `build/Build/Products/Debug-iphonesimulator/${inferredSchemeName}.app`;
|
|
|
|
console.log(`Installing ${appPath}`);
|
|
|
|
child_process.spawnSync('xcrun', ['simctl', 'install', 'booted', appPath], {stdio: 'inherit'});
|
2016-06-22 10:30:30 +00:00
|
|
|
|
2016-07-30 15:59:16 +00:00
|
|
|
const bundleID = child_process.execFileSync(
|
|
|
|
'/usr/libexec/PlistBuddy',
|
|
|
|
['-c', 'Print:CFBundleIdentifier', path.join(appPath, 'Info.plist')],
|
|
|
|
{encoding: 'utf8'}
|
|
|
|
).trim();
|
2016-01-06 01:11:53 +00:00
|
|
|
|
2016-07-30 15:59:16 +00:00
|
|
|
console.log(`Launching ${bundleID}`);
|
|
|
|
child_process.spawnSync('xcrun', ['simctl', 'launch', 'booted', bundleID], {stdio: 'inherit'});
|
2016-01-06 01:11:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
function matchingSimulator(simulators, simulatorName) {
|
|
|
|
for (let i = simulators.length - 1; i >= 0; i--) {
|
2016-07-05 16:46:22 +00:00
|
|
|
if (simulators[i].name === simulatorName || formattedSimulatorName(simulators[i]) === simulatorName) {
|
2016-01-06 01:11:53 +00:00
|
|
|
return simulators[i];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-07-05 16:46:22 +00:00
|
|
|
function formattedSimulatorName(simulator) {
|
|
|
|
return `${simulator.name} (${simulator.version})`;
|
|
|
|
}
|
|
|
|
|
2016-07-30 15:59:16 +00:00
|
|
|
module.exports = {
|
|
|
|
name: 'run-ios',
|
|
|
|
description: 'builds your app and starts it on iOS simulator',
|
|
|
|
func: runIOS,
|
|
|
|
examples: [
|
|
|
|
{
|
|
|
|
desc: 'Run on a different simulator, e.g. iPhone 5',
|
|
|
|
cmd: 'react-native run-ios --simulator "iPhone 5"',
|
|
|
|
},
|
|
|
|
{
|
|
|
|
desc: 'Pass a non-standard location of iOS directory',
|
|
|
|
cmd: 'react-native run-ios --project-path "./app/ios"',
|
|
|
|
},
|
|
|
|
],
|
|
|
|
options: [{
|
|
|
|
command: '--simulator [string]',
|
|
|
|
description: 'Explicitly set simulator to use',
|
|
|
|
default: 'iPhone 6',
|
|
|
|
}, {
|
|
|
|
command: '--scheme [string]',
|
|
|
|
description: 'Explicitly set Xcode scheme to use',
|
|
|
|
}, {
|
|
|
|
command: '--project-path [string]',
|
|
|
|
description: 'Path relative to project root where the Xcode project '
|
|
|
|
+ '(.xcodeproj) lives. The default is \'ios\'.',
|
|
|
|
default: 'ios',
|
|
|
|
}]
|
|
|
|
};
|