Xcode 9 supports running multiple simulators

Summary:
Since Xcode 9 you can run multiple simultaneously. And since I believe React Native advocates using the latest version of Xcode, we can safely remove this constraint.

Updated the unit tests. Furthermore it can be found in the [Xcode release notes](https://developer.apple.com/library/content/documentation/DeveloperTools/Conceptual/WhatsNewXcode/xcode_9/xcode_9.html#//apple_ref/doc/uid/TP40004626-CH8-SW12) that multiple simulators are now supported.

This can be tested with the CLI by running `react-native run-ios` twice, but with a different `--simulator` flag, e.g.;

    react-native run-ios --simulator "iPhone SE"
    react-native run-ios --simulator "iPhone X"

[IOS] [ENHANCEMENT] [local-cli/runIOS/findMatchingSimulator.js] - Allow running multiple simulators
Closes https://github.com/facebook/react-native/pull/17284

Differential Revision: D7102790

Pulled By: hramos

fbshipit-source-id: 750e7039201e28a1feda2bec1e78144fd9deff98
This commit is contained in:
Koen Punt 2018-02-27 14:03:50 -08:00 committed by Facebook Github Bot
parent 2dc559d1fb
commit 2ad34075f1
3 changed files with 38 additions and 24 deletions

View File

@ -55,6 +55,7 @@ describe('findMatchingSimulator', () => {
)).toEqual({ )).toEqual({
udid: 'BA0D93BD-07E6-4182-9B0A-F60A2474139C', udid: 'BA0D93BD-07E6-4182-9B0A-F60A2474139C',
name: 'iPhone 6', name: 'iPhone 6',
booted: false,
version: 'iOS 9.2' version: 'iOS 9.2'
}); });
}); });
@ -145,6 +146,7 @@ describe('findMatchingSimulator', () => {
)).toEqual({ )).toEqual({
udid: '1CCBBF8B-5773-4EA6-BD6F-C308C87A1ADB', udid: '1CCBBF8B-5773-4EA6-BD6F-C308C87A1ADB',
name: 'iPhone 5', name: 'iPhone 5',
booted: false,
version: 'iOS 9.2' version: 'iOS 9.2'
}); });
}); });
@ -216,6 +218,7 @@ describe('findMatchingSimulator', () => {
)).toEqual({ )).toEqual({
udid: '1CCBBF8B-5773-4EA6-BD6F-C308C87A1ADB', udid: '1CCBBF8B-5773-4EA6-BD6F-C308C87A1ADB',
name: 'iPhone 5', name: 'iPhone 5',
booted: false,
version: 'iOS 9.2' version: 'iOS 9.2'
}); });
}); });
@ -261,11 +264,12 @@ describe('findMatchingSimulator', () => {
)).toEqual({ )).toEqual({
udid: 'D0F29BE7-CC3C-4976-888D-C739B4F50508', udid: 'D0F29BE7-CC3C-4976-888D-C739B4F50508',
name: 'iPhone 6s', name: 'iPhone 6s',
booted: true,
version: 'iOS 9.2' version: 'iOS 9.2'
}); });
}); });
it('should return the booted simulator in list even if another device is defined', () => { it('should return the defined simulator in list even if another device is booted', () => {
expect(findMatchingSimulator({ expect(findMatchingSimulator({
'devices': { 'devices': {
'iOS 9.2': [ 'iOS 9.2': [
@ -304,8 +308,9 @@ describe('findMatchingSimulator', () => {
}, },
'iPhone 6' 'iPhone 6'
)).toEqual({ )).toEqual({
udid: 'D0F29BE7-CC3C-4976-888D-C739B4F50508', udid: 'BA0D93BD-07E6-4182-9B0A-F60A2474139C',
name: 'iPhone 6s', name: 'iPhone 6',
booted: false,
version: 'iOS 9.2' version: 'iOS 9.2'
}); });
}); });
@ -377,11 +382,12 @@ describe('findMatchingSimulator', () => {
)).toEqual({ )).toEqual({
udid: '3A409DC5-5188-42A6-8598-3AA6F34607A5', udid: '3A409DC5-5188-42A6-8598-3AA6F34607A5',
name: 'iPhone 7', name: 'iPhone 7',
booted: true,
version: 'iOS 10.0' version: 'iOS 10.0'
}); });
}); });
it('should return the booted simulator in list even if another device is defined (multi ios versions)', () => { it('should return the defined simulator in list even if another device is booted (multi ios versions)', () => {
expect(findMatchingSimulator({ expect(findMatchingSimulator({
'devices': { 'devices': {
'iOS 9.2': [ 'iOS 9.2': [
@ -446,9 +452,10 @@ describe('findMatchingSimulator', () => {
}, },
'iPhone 6s' 'iPhone 6s'
)).toEqual({ )).toEqual({
udid: '3A409DC5-5188-42A6-8598-3AA6F34607A5', udid: 'D0F29BE7-CC3C-4976-888D-C739B4F50508',
name: 'iPhone 7', name: 'iPhone 6s',
version: 'iOS 10.0' booted: false,
version: 'iOS 9.2'
}); });
}); });
@ -481,6 +488,7 @@ describe('findMatchingSimulator', () => {
)).toEqual({ )).toEqual({
udid: '816C30EA-38EA-41AC-BFDA-96FB632D522E', udid: '816C30EA-38EA-41AC-BFDA-96FB632D522E',
name: 'Apple TV', name: 'Apple TV',
booted: true,
version: 'tvOS 11.2' version: 'tvOS 11.2'
}); });
}); });

View File

@ -34,14 +34,12 @@ function findMatchingSimulator(simulators, simulatorName) {
if (simulator.availability !== '(available)') { if (simulator.availability !== '(available)') {
continue; continue;
} }
// If there is a booted simulator, we'll use that as instruments will not boot a second simulator let booted = simulator.state === 'Booted';
if (simulator.state === 'Booted') { if (booted && simulatorName === null) {
if (simulatorName !== null) {
console.warn("We couldn't boot your defined simulator due to an already booted simulator. We are limited to one simulator launched at a time.");
}
return { return {
udid: simulator.udid, udid: simulator.udid,
name: simulator.name, name: simulator.name,
booted,
version version
}; };
} }
@ -49,6 +47,7 @@ function findMatchingSimulator(simulators, simulatorName) {
match = { match = {
udid: simulator.udid, udid: simulator.udid,
name: simulator.name, name: simulator.name,
booted,
version version
}; };
} }
@ -57,6 +56,7 @@ function findMatchingSimulator(simulators, simulatorName) {
match = { match = {
udid: simulator.udid, udid: simulator.udid,
name: simulator.name, name: simulator.name,
booted,
version version
}; };
} }

View File

@ -113,24 +113,30 @@ function runOnSimulator(xcodeProject, args, scheme) {
throw new Error(`Could not find ${args.simulator} simulator`); throw new Error(`Could not find ${args.simulator} simulator`);
} }
const simulatorFullName = formattedDeviceName(selectedSimulator); if (!selectedSimulator.booted) {
console.log(`Launching ${simulatorFullName}...`); const simulatorFullName = formattedDeviceName(selectedSimulator);
try { console.log(`Booting ${simulatorFullName}...`);
child_process.spawnSync('xcrun', ['instruments', '-w', selectedSimulator.udid]); try {
} catch (e) { child_process.execFileSync('xcrun', ['simctl', 'boot', selectedSimulator.udid]);
// instruments always fail with 255 because it expects more arguments, } catch (e) {
// but we want it to only launch the simulator throw new Error(
`Could not boot ${args.simulator} simulator. Is there already a simulator running?
Running multiple simulators is only supported from Xcode 9 and up.
Try closing the simulator or run the command again without specifying a simulator.`
);
}
} }
resolve(selectedSimulator.udid);
buildProject(xcodeProject, selectedSimulator.udid, scheme, args.configuration, args.packager, args.verbose)
.then((appName) => resolve(selectedSimulator.udid, appName));
}) })
.then((udid) => buildProject(xcodeProject, udid, scheme, args.configuration, args.packager, args.verbose, args.port)) .then((udid, appName) => {
.then((appName) => {
if (!appName) { if (!appName) {
appName = scheme; appName = scheme;
} }
let appPath = getBuildPath(args.configuration, appName); let appPath = getBuildPath(args.configuration, appName);
console.log(`Installing ${appPath}`); console.log(`Installing ${appPath}`);
child_process.spawnSync('xcrun', ['simctl', 'install', 'booted', appPath], {stdio: 'inherit'}); child_process.spawnSync('xcrun', ['simctl', 'install', udid, appPath], {stdio: 'inherit'});
const bundleID = child_process.execFileSync( const bundleID = child_process.execFileSync(
'/usr/libexec/PlistBuddy', '/usr/libexec/PlistBuddy',
@ -139,7 +145,7 @@ function runOnSimulator(xcodeProject, args, scheme) {
).trim(); ).trim();
console.log(`Launching ${bundleID}`); console.log(`Launching ${bundleID}`);
child_process.spawnSync('xcrun', ['simctl', 'launch', 'booted', bundleID], {stdio: 'inherit'}); child_process.spawnSync('xcrun', ['simctl', 'launch', udid, bundleID], {stdio: 'inherit'});
}); });
} }