cli run-ios on device
Summary: At the moment the run-ios command from the react-native cli does only work for simulators. The pull request adds a new option to the existing command: **"--device 'device-name'" which installs and launches an iOS application on a connected device.** This makes it easier to build a test environment using react-native for connected devices. I've tested my code with the following commands: react-native run-ios --device "Not existing device" react-native run-ios --device react-native run-ios --device "name-of-a-simulator" react-native run-ios --device "name-of-connected-device" Output of the first three commands: ![example_error_output](https://cloud.githubusercontent.com/assets/9102810/17669443/f53d5948-630d-11e6-9a80-7df2f352c6a3.png) Additional to the manual command tests i've added a test file 'parseIOSDevicesList-test.js'. I used **ios-deploy** In order to launch and install the .app-bundle on a connected device. ios-deploy on github: Closes https://github.com/facebook/react-native/pull/9414 Differential Revision: D3821638 Pulled By: javache fbshipit-source-id: c07b7bf25283a966e45613a22ed3184bb1aac714
This commit is contained in:
parent
128b698a03
commit
48ab5eb436
|
@ -0,0 +1,196 @@
|
|||
/**
|
||||
/**
|
||||
* 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';
|
||||
|
||||
jest.dontMock('../findMatchingSimulator');
|
||||
|
||||
const findMatchingSimulator = require('../findMatchingSimulator');
|
||||
|
||||
describe('findMatchingSimulator', () => {
|
||||
it('should find simulator', () => {
|
||||
expect(findMatchingSimulator({
|
||||
"devices": {
|
||||
"iOS 9.2": [
|
||||
{
|
||||
"state": "Shutdown",
|
||||
"availability": "(available)",
|
||||
"name": "iPhone 4s",
|
||||
"udid": "B9B5E161-416B-43C4-A78F-729CB96CC8C6"
|
||||
},
|
||||
{
|
||||
"state": "Shutdown",
|
||||
"availability": "(available)",
|
||||
"name": "iPhone 5",
|
||||
"udid": "1CCBBF8B-5773-4EA6-BD6F-C308C87A1ADB"
|
||||
},
|
||||
{
|
||||
"state": "Shutdown",
|
||||
"availability": "(available)",
|
||||
"name": "iPhone 6",
|
||||
"udid": "BA0D93BD-07E6-4182-9B0A-F60A2474139C"
|
||||
},
|
||||
{
|
||||
"state": "Shutdown",
|
||||
"availability": "(available)",
|
||||
"name": "iPhone 6 (Plus)",
|
||||
"udid": "9564ABEE-9EC2-4B4A-B443-D3710929A45A"
|
||||
},
|
||||
{
|
||||
"state": "Shutdown",
|
||||
"availability": "(available)",
|
||||
"name": "iPhone 6s",
|
||||
"udid": "D0F29BE7-CC3C-4976-888D-C739B4F50508"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
'iPhone 6'
|
||||
)).toEqual({
|
||||
udid: 'BA0D93BD-07E6-4182-9B0A-F60A2474139C',
|
||||
name: 'iPhone 6',
|
||||
version: 'iOS 9.2'
|
||||
});
|
||||
});
|
||||
|
||||
it('should return null if no simulators available', () => {
|
||||
expect(findMatchingSimulator({
|
||||
"devices": {
|
||||
"iOS 9.2": [
|
||||
{
|
||||
"state": "Shutdown",
|
||||
"availability": "(unavailable, runtime profile not found)",
|
||||
"name": "iPhone 4s",
|
||||
"udid": "B9B5E161-416B-43C4-A78F-729CB96CC8C6"
|
||||
},
|
||||
{
|
||||
"state": "Shutdown",
|
||||
"availability": "(unavailable, runtime profile not found)",
|
||||
"name": "iPhone 5",
|
||||
"udid": "1CCBBF8B-5773-4EA6-BD6F-C308C87A1ADB"
|
||||
},
|
||||
{
|
||||
"state": "Shutdown",
|
||||
"availability": "(unavailable, runtime profile not found)",
|
||||
"name": "iPhone 6",
|
||||
"udid": "BA0D93BD-07E6-4182-9B0A-F60A2474139C"
|
||||
},
|
||||
{
|
||||
"state": "Shutdown",
|
||||
"availability": "(unavailable, runtime profile not found)",
|
||||
"name": "iPhone 6 (Plus)",
|
||||
"udid": "9564ABEE-9EC2-4B4A-B443-D3710929A45A"
|
||||
},
|
||||
{
|
||||
"state": "Shutdown",
|
||||
"availability": "(unavailable, runtime profile not found)",
|
||||
"name": "iPhone 6s",
|
||||
"udid": "D0F29BE7-CC3C-4976-888D-C739B4F50508"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
'iPhone 6'
|
||||
)).toEqual(null);
|
||||
});
|
||||
|
||||
it('should return null if an odd input', () => {
|
||||
expect(findMatchingSimulator('random string input', 'iPhone 6')).toEqual(null);
|
||||
});
|
||||
|
||||
it('should return the first simulator in list if none is defined', () => {
|
||||
expect(findMatchingSimulator({
|
||||
"devices": {
|
||||
"iOS 9.2": [
|
||||
{
|
||||
"state": "Shutdown",
|
||||
"availability": "(unavailable, runtime profile not found)",
|
||||
"name": "iPhone 4s",
|
||||
"udid": "B9B5E161-416B-43C4-A78F-729CB96CC8C6"
|
||||
},
|
||||
{
|
||||
"state": "Shutdown",
|
||||
"availability": "(available)",
|
||||
"name": "iPhone 5",
|
||||
"udid": "1CCBBF8B-5773-4EA6-BD6F-C308C87A1ADB"
|
||||
},
|
||||
{
|
||||
"state": "Shutdown",
|
||||
"availability": "(available)",
|
||||
"name": "iPhone 6",
|
||||
"udid": "BA0D93BD-07E6-4182-9B0A-F60A2474139C"
|
||||
},
|
||||
{
|
||||
"state": "Shutdown",
|
||||
"availability": "(available)",
|
||||
"name": "iPhone 6 (Plus)",
|
||||
"udid": "9564ABEE-9EC2-4B4A-B443-D3710929A45A"
|
||||
},
|
||||
{
|
||||
"state": "Shutdown",
|
||||
"availability": "(unavailable, runtime profile not found)",
|
||||
"name": "iPhone 6s",
|
||||
"udid": "D0F29BE7-CC3C-4976-888D-C739B4F50508"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
null
|
||||
)).toEqual({
|
||||
udid: '1CCBBF8B-5773-4EA6-BD6F-C308C87A1ADB',
|
||||
name: 'iPhone 5',
|
||||
version: 'iOS 9.2'
|
||||
});
|
||||
});
|
||||
|
||||
it('should return the botted simulator in list if none is defined', () => {
|
||||
expect(findMatchingSimulator({
|
||||
"devices": {
|
||||
"iOS 9.2": [
|
||||
{
|
||||
"state": "Shutdown",
|
||||
"availability": "(unavailable, runtime profile not found)",
|
||||
"name": "iPhone 4s",
|
||||
"udid": "B9B5E161-416B-43C4-A78F-729CB96CC8C6"
|
||||
},
|
||||
{
|
||||
"state": "Shutdown",
|
||||
"availability": "(available)",
|
||||
"name": "iPhone 5",
|
||||
"udid": "1CCBBF8B-5773-4EA6-BD6F-C308C87A1ADB"
|
||||
},
|
||||
{
|
||||
"state": "Shutdown",
|
||||
"availability": "(available)",
|
||||
"name": "iPhone 6",
|
||||
"udid": "BA0D93BD-07E6-4182-9B0A-F60A2474139C"
|
||||
},
|
||||
{
|
||||
"state": "Shutdown",
|
||||
"availability": "(available)",
|
||||
"name": "iPhone 6 (Plus)",
|
||||
"udid": "9564ABEE-9EC2-4B4A-B443-D3710929A45A"
|
||||
},
|
||||
{
|
||||
"state": "Booted",
|
||||
"availability": "(available)",
|
||||
"name": "iPhone 6s",
|
||||
"udid": "D0F29BE7-CC3C-4976-888D-C739B4F50508"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
null
|
||||
)).toEqual({
|
||||
udid: 'D0F29BE7-CC3C-4976-888D-C739B4F50508',
|
||||
name: 'iPhone 6s',
|
||||
version: 'iOS 9.2'
|
||||
});
|
||||
});
|
||||
});
|
|
@ -0,0 +1,39 @@
|
|||
/**
|
||||
* 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';
|
||||
|
||||
jest.dontMock('../parseIOSDevicesList');
|
||||
var parseIOSDevicesList = require('../parseIOSDevicesList');
|
||||
|
||||
describe('parseIOSDevicesList', () => {
|
||||
it('parses typical output', () => {
|
||||
var devices = parseIOSDevicesList([
|
||||
'Known Devices:',
|
||||
'Maxs MacBook Pro [11111111-1111-1111-1111-111111111111]',
|
||||
"Max's iPhone (9.2) [11111111111111111111aaaaaaaaaaaaaaaaaaaa]",
|
||||
'iPad 2 (9.3) [07538CE4-675B-4EDA-90F2-3DD3CD93309D] (Simulator)',
|
||||
'iPad Air (9.3) [0745F6D1-6DC5-4427-B9A6-6FBA327ED65A] (Simulator)',
|
||||
'iPhone 6s (9.3) [3DBE4ECF-9A86-469E-921B-EE0F9C9AB8F4] (Simulator)',
|
||||
'Known Templates:',
|
||||
'Activity Monitor',
|
||||
'Blank',
|
||||
'System Usage',
|
||||
'Zombies'
|
||||
].join('\n'));
|
||||
|
||||
expect(devices).toEqual([
|
||||
{name: "Max's iPhone", udid: '11111111111111111111aaaaaaaaaaaaaaaaaaaa', version: '9.2'},
|
||||
]);
|
||||
});
|
||||
|
||||
it('ignores garbage', () => {
|
||||
expect(parseIOSDevicesList('Something went terribly wrong (-42)')).toEqual([]);
|
||||
});
|
||||
});
|
|
@ -1,53 +0,0 @@
|
|||
/**
|
||||
* 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';
|
||||
|
||||
jest.dontMock('../parseIOSSimulatorsList');
|
||||
var parseIOSSimulatorsList = require('../parseIOSSimulatorsList');
|
||||
|
||||
describe('parseIOSSimulatorsList', () => {
|
||||
it('parses typical output', () => {
|
||||
var simulators = parseIOSSimulatorsList([
|
||||
'== Devices ==',
|
||||
'-- iOS 8.1 --',
|
||||
' iPhone 4s (4FE43B33-EF13-49A5-B6A6-658D32F20988) (Shutdown)',
|
||||
'-- iOS 8.4 --',
|
||||
' iPhone 4s (EAB622C7-8ADE-4FAE-A911-94C0CA4709BB) (Shutdown)',
|
||||
' iPhone 5 (AE1CD3D0-A85B-4A73-B320-9CA7BA4FAEB0) (Shutdown)',
|
||||
].join('\n'));
|
||||
|
||||
expect(simulators).toEqual([
|
||||
{name: 'iPhone 4s', udid: '4FE43B33-EF13-49A5-B6A6-658D32F20988', version: '8.1'},
|
||||
{name: 'iPhone 4s', udid: 'EAB622C7-8ADE-4FAE-A911-94C0CA4709BB', version: '8.4'},
|
||||
{name: 'iPhone 5', udid: 'AE1CD3D0-A85B-4A73-B320-9CA7BA4FAEB0', version: '8.4'},
|
||||
]);
|
||||
});
|
||||
|
||||
it('ignores unavailable simulators', () => {
|
||||
var simulators = parseIOSSimulatorsList([
|
||||
'== Devices ==',
|
||||
'-- iOS 8.1 --',
|
||||
' iPhone 4s (4FE43B33-EF13-49A5-B6A6-658D32F20988) (Shutdown)',
|
||||
'-- Unavailable: com.apple.CoreSimulator.SimRuntime.iOS-8-3 --',
|
||||
' iPhone 5s (EAB622C7-8ADE-4FAE-A911-94C0CA4709BB) (Shutdown)',
|
||||
].join('\n'));
|
||||
|
||||
expect(simulators).toEqual([{
|
||||
name: 'iPhone 4s',
|
||||
udid: '4FE43B33-EF13-49A5-B6A6-658D32F20988',
|
||||
version: '8.1',
|
||||
}]);
|
||||
|
||||
});
|
||||
|
||||
it('ignores garbage', () => {
|
||||
expect(parseIOSSimulatorsList('Something went terribly wrong (-42)')).toEqual([]);
|
||||
});
|
||||
});
|
|
@ -0,0 +1,73 @@
|
|||
/**
|
||||
* 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';
|
||||
|
||||
/**
|
||||
* Takes in a parsed simulator list and a desired name, and returns an object with the matching simulator.
|
||||
*
|
||||
* If the simulatorName argument is null, we'll go into default mode and return the currently booted simulator, or if
|
||||
* none is booted, it will be the first in the list.
|
||||
*
|
||||
* @param Object simulators a parsed list from `xcrun simctl list --json devices` command
|
||||
* @param String|null simulatorName the string with the name of desired simulator. If null, it will use the currently
|
||||
* booted simulator, or if none are booted, the first in the list.
|
||||
* @returns {Object} {udid, name, version}
|
||||
*/
|
||||
function findMatchingSimulator(simulators, simulatorName) {
|
||||
if (!simulators.devices) {
|
||||
return null;
|
||||
}
|
||||
const devices = simulators.devices;
|
||||
var match;
|
||||
for (let version in devices) {
|
||||
// Making sure the version of the simulator is an iOS (Removes Apple Watch, etc)
|
||||
if (version.indexOf('iOS') !== 0) {
|
||||
continue;
|
||||
}
|
||||
for (let i in devices[version]) {
|
||||
let simulator = devices[version][i];
|
||||
// Skipping non-available simulator
|
||||
if (simulator.availability !== '(available)') {
|
||||
continue;
|
||||
}
|
||||
// If there is a booted simulator, we'll use that as instruments will not boot a second simulator
|
||||
if (simulator.state === 'Booted') {
|
||||
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 {
|
||||
udid: simulator.udid,
|
||||
name: simulator.name,
|
||||
version
|
||||
};
|
||||
}
|
||||
if (simulator.name === simulatorName) {
|
||||
return {
|
||||
udid: simulator.udid,
|
||||
name: simulator.name,
|
||||
version
|
||||
};
|
||||
}
|
||||
// Keeps track of the first available simulator for use if we can't find one above.
|
||||
if (simulatorName === null && !match) {
|
||||
match = {
|
||||
udid: simulator.udid,
|
||||
name: simulator.name,
|
||||
version
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
if (match) {
|
||||
return match;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
module.exports = findMatchingSimulator;
|
|
@ -10,7 +10,7 @@
|
|||
*/
|
||||
'use strict';
|
||||
|
||||
type IOSSimulatorInfo = {
|
||||
type IOSDeviceInfo = {
|
||||
name: string;
|
||||
udid: string;
|
||||
version: string;
|
||||
|
@ -19,31 +19,20 @@ type IOSSimulatorInfo = {
|
|||
/**
|
||||
* Parses the output of `xcrun simctl list devices` command
|
||||
*/
|
||||
function parseIOSSimulatorsList(text: string): Array<IOSSimulatorInfo> {
|
||||
function parseIOSDevicesList(text: string): Array<IOSDeviceInfo> {
|
||||
const devices = [];
|
||||
var currentOS = null;
|
||||
|
||||
text.split('\n').forEach((line) => {
|
||||
var section = line.match(/^-- (.+) --$/);
|
||||
if (section) {
|
||||
var header = section[1].match(/^iOS (.+)$/);
|
||||
if (header) {
|
||||
currentOS = header[1];
|
||||
} else {
|
||||
currentOS = null;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
const device = line.match(/^[ ]*([^()]+) \(([^()]+)\)/);
|
||||
if (device && currentOS) {
|
||||
const device = line.match(/(.*?) \((.*?)\) \[(.*?)\]/);
|
||||
const noSimulator = line.match(/(.*?) \((.*?)\) \[(.*?)\] \((.*?)\)/);
|
||||
if (device != null && noSimulator == null){
|
||||
var name = device[1];
|
||||
var udid = device[2];
|
||||
devices.push({udid, name, version: currentOS});
|
||||
var version = device[2];
|
||||
var udid = device[3];
|
||||
devices.push({udid, name, version});
|
||||
}
|
||||
});
|
||||
|
||||
return devices;
|
||||
}
|
||||
|
||||
module.exports = parseIOSSimulatorsList;
|
||||
module.exports = parseIOSDevicesList;
|
|
@ -1,18 +1,19 @@
|
|||
/**
|
||||
* 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.
|
||||
*/
|
||||
* 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');
|
||||
const parseIOSDevicesList = require('./parseIOSDevicesList');
|
||||
const findMatchingSimulator = require('./findMatchingSimulator');
|
||||
|
||||
function runIOS(argv, config, args) {
|
||||
process.chdir(args.projectPath);
|
||||
|
@ -24,32 +25,68 @@ function runIOS(argv, config, args) {
|
|||
const inferredSchemeName = path.basename(xcodeProject.name, path.extname(xcodeProject.name));
|
||||
const scheme = args.scheme || inferredSchemeName;
|
||||
console.log(`Found Xcode ${xcodeProject.isWorkspace ? 'workspace' : 'project'} ${xcodeProject.name}`);
|
||||
|
||||
const simulators = parseIOSSimulatorsList(
|
||||
child_process.execFileSync('xcrun', ['simctl', 'list', 'devices'], {encoding: 'utf8'})
|
||||
const devices = parseIOSDevicesList(
|
||||
child_process.execFileSync('xcrun', ['instruments', '-s'], {encoding: 'utf8'})
|
||||
);
|
||||
const selectedSimulator = matchingSimulator(simulators, args.simulator);
|
||||
if (args.device) {
|
||||
const selectedDevice = matchingDevice(devices, args.device);
|
||||
if (selectedDevice){
|
||||
runOnDevice(selectedDevice, scheme, xcodeProject);
|
||||
} else {
|
||||
if (devices){
|
||||
console.log('Could not find device with the name: "' + args.device + '".');
|
||||
console.log('Choose one of the following:');
|
||||
printFoundDevices(devices);
|
||||
} else {
|
||||
console.log('No iOS devices connected.');
|
||||
}
|
||||
}
|
||||
} else if (args.udid) {
|
||||
runOnDeviceByUdid(args.udid, scheme, xcodeProject, devices);
|
||||
} else {
|
||||
runOnSimulator(xcodeProject, args, inferredSchemeName, scheme);
|
||||
}
|
||||
}
|
||||
|
||||
function runOnDeviceByUdid(udid, scheme, xcodeProject, devices) {
|
||||
const selectedDevice = matchingDeviceByUdid(devices, udid);
|
||||
if (selectedDevice){
|
||||
runOnDevice(selectedDevice, scheme, xcodeProject);
|
||||
} else {
|
||||
if (devices){
|
||||
console.log('Could not find device with the udid: "' + udid + '".');
|
||||
console.log('Choose one of the following:');
|
||||
printFoundDevices(devices);
|
||||
} else {
|
||||
console.log('No iOS devices connected.');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function runOnSimulator(xcodeProject, args, inferredSchemeName, scheme){
|
||||
try {
|
||||
var simulators = JSON.parse(
|
||||
child_process.execFileSync('xcrun', ['simctl', 'list', '--json', 'devices'], {encoding: 'utf8'})
|
||||
);
|
||||
} catch (e) {
|
||||
throw new Error('Could not parse the simulator list output');
|
||||
}
|
||||
|
||||
const selectedSimulator = findMatchingSimulator(simulators, args.simulator);
|
||||
if (!selectedSimulator) {
|
||||
throw new Error(`Cound't find ${args.simulator} simulator`);
|
||||
}
|
||||
|
||||
const simulatorFullName = formattedSimulatorName(selectedSimulator);
|
||||
const simulatorFullName = formattedDeviceName(selectedSimulator);
|
||||
console.log(`Launching ${simulatorFullName}...`);
|
||||
try {
|
||||
child_process.spawnSync('xcrun', ['instruments', '-w', simulatorFullName]);
|
||||
child_process.spawnSync('xcrun', ['instruments', '-w', selectedSimulator.udid]);
|
||||
} catch (e) {
|
||||
// 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,
|
||||
'-scheme', scheme,
|
||||
'-destination', `id=${selectedSimulator.udid}`,
|
||||
'-derivedDataPath', 'build',
|
||||
];
|
||||
console.log(`Building using "xcodebuild ${xcodebuildArgs.join(' ')}"`);
|
||||
child_process.spawnSync('xcodebuild', xcodebuildArgs, {stdio: 'inherit'});
|
||||
buildProject(xcodeProject, selectedSimulator.udid, scheme);
|
||||
|
||||
const appPath = `build/Build/Products/Debug-iphonesimulator/${inferredSchemeName}.app`;
|
||||
console.log(`Installing ${appPath}`);
|
||||
|
@ -65,31 +102,79 @@ function runIOS(argv, config, args) {
|
|||
child_process.spawnSync('xcrun', ['simctl', 'launch', 'booted', bundleID], {stdio: 'inherit'});
|
||||
}
|
||||
|
||||
function matchingSimulator(simulators, simulatorName) {
|
||||
for (let i = simulators.length - 1; i >= 0; i--) {
|
||||
if (simulators[i].name === simulatorName || formattedSimulatorName(simulators[i]) === simulatorName) {
|
||||
return simulators[i];
|
||||
function runOnDevice(selectedDevice, scheme, xcodeProject){
|
||||
buildProject(xcodeProject, selectedDevice.udid, scheme);
|
||||
const iosDeployInstallArgs = [
|
||||
'--bundle', 'build/Build/Products/Debug-iphoneos/' + scheme + '.app',
|
||||
'--id' , selectedDevice.udid,
|
||||
'--justlaunch'
|
||||
];
|
||||
console.log(`installing and launching your app on ${selectedDevice.name}...`);
|
||||
var iosDeployOutput = child_process.spawnSync('ios-deploy', iosDeployInstallArgs, {encoding: 'utf8'});
|
||||
if (iosDeployOutput.error) {
|
||||
console.log('');
|
||||
console.log('** INSTALLATION FAILED **');
|
||||
console.log('Make sure you have ios-deploy installed globally.');
|
||||
console.log('(e.g "npm install -g ios-deploy")');
|
||||
} else {
|
||||
console.log('** INSTALLATION SUCCEEDED **');
|
||||
}
|
||||
}
|
||||
|
||||
function buildProject(xcodeProject, udid, scheme) {
|
||||
const xcodebuildArgs = [
|
||||
xcodeProject.isWorkspace ? '-workspace' : '-project', xcodeProject.name,
|
||||
'-scheme', scheme,
|
||||
'-destination', `id=${udid}`,
|
||||
'-derivedDataPath', 'build',
|
||||
];
|
||||
console.log(`Building using "xcodebuild ${xcodebuildArgs.join(' ')}"`);
|
||||
child_process.spawnSync('xcodebuild', xcodebuildArgs, {stdio: 'inherit'});
|
||||
}
|
||||
|
||||
function matchingDevice(devices, deviceName) {
|
||||
for (let i = devices.length - 1; i >= 0; i--) {
|
||||
if (devices[i].name === deviceName || formattedDeviceName(devices[i]) === deviceName) {
|
||||
return devices[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function formattedSimulatorName(simulator) {
|
||||
function matchingDeviceByUdid(devices, udid) {
|
||||
for (let i = devices.length - 1; i >= 0; i--) {
|
||||
if (devices[i].udid === udid) {
|
||||
return devices[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function formattedDeviceName(simulator) {
|
||||
return `${simulator.name} (${simulator.version})`;
|
||||
}
|
||||
|
||||
function printFoundDevices(devices){
|
||||
for (let i = devices.length - 1; i >= 0; i--) {
|
||||
console.log(devices[i].name + ' Udid: ' + devices[i].udid);
|
||||
}
|
||||
}
|
||||
|
||||
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"',
|
||||
},
|
||||
{
|
||||
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"',
|
||||
},
|
||||
{
|
||||
desc: "Run on a connected device, e.g. Max's iPhone",
|
||||
cmd: "react-native run-ios --device 'Max's iPhone'",
|
||||
},
|
||||
],
|
||||
options: [{
|
||||
command: '--simulator [string]',
|
||||
|
@ -101,7 +186,13 @@ module.exports = {
|
|||
}, {
|
||||
command: '--project-path [string]',
|
||||
description: 'Path relative to project root where the Xcode project '
|
||||
+ '(.xcodeproj) lives. The default is \'ios\'.',
|
||||
+ '(.xcodeproj) lives. The default is \'ios\'.',
|
||||
default: 'ios',
|
||||
}, {
|
||||
command: '--device [string]',
|
||||
description: 'Explicitly set device to use by name',
|
||||
},{
|
||||
command: '--udid [string]',
|
||||
description: 'Explicitly set device to use by udid',
|
||||
}]
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue