Permalink
Browse files

Add the scheme configuration option to the run-ios command

Summary:
With the current `run-ios` script it is not possible to create/run iOS release builds or any other kind of scheme configuration from the terminal (we need to use `Xcode`). The reason for this is that the `run-ios` script does not expose the scheme configuration option for the `xcodebuild` command. This PR exposes that property and allows the developers to directly create/run release builds from the terminal.

This PR also closes [this](https://productpains.com/post/react-native/create-ios-release-builds-from-terminal) request at `productpains`.

And answers to [this](http://stackoverflow.com/questions/40303229/run-a-react-native-ios-release-build-from-terminal) question at the `stackoverflow`.

**Test plan (required)**

To generate a release build just run:

``` sh
react-native run-ios --configuration Release
```

The output

``` sh
Found Xcode project App.xcodeproj
Launching iPhone 6 (iOS 9.3)...
Building using "xcodebuild -project App.xcodeproj -scheme App -destination id=B0738993-CE4A-4D
Closes #10637

Differential Revision: D4151793

Pulled By: cpojer

fbshipit-source-id: 5a0fcdd59589977f3e251ec9bb3ba85e8919cffc
  • Loading branch information...
1 parent 4785a60 commit ca7cbdee858e84c4a74a2d9c7be151f5cfdcfbfe @SandroMachado SandroMachado committed with Facebook Github Bot Nov 10, 2016
Showing with 26 additions and 17 deletions.
  1. +4 −0 docs/RunningOnDevice.md
  2. +22 −17 local-cli/runIOS/runIOS.js
@@ -206,6 +206,10 @@ Building an app for distribution in the App Store requires using the `Release` s
Apps built for `Release` will automatically disable the in-app Developer menu, which will prevent your users from inadvertently accessing the menu in production. It will also load the JavaScript locally, so you can put the app on a device and test whilst not connected to the computer.
+> Hint
+>
+> You can also use the `React Native CLI` to perform this operation using the option `--configuration` with the value `Release` (e.g. `react-native run-ios --configuration Release`).
+
Once built for release, you'll be able to distribute the app to beta testers and submit the app to the App Store.
### App Transport Security
@@ -14,6 +14,9 @@ const path = require('path');
const findXcodeProject = require('./findXcodeProject');
const parseIOSDevicesList = require('./parseIOSDevicesList');
const findMatchingSimulator = require('./findMatchingSimulator');
+const getBuildPath = function(configuration = 'Debug', appName, isDevice) {
+ return `build/Build/Products/${configuration}-${isDevice ? 'iphoneos' : 'iphonesimulator'}/${appName}.app`;
+};
function runIOS(argv, config, args) {
process.chdir(args.projectPath);
@@ -31,7 +34,7 @@ function runIOS(argv, config, args) {
if (args.device) {
const selectedDevice = matchingDevice(devices, args.device);
if (selectedDevice){
- return runOnDevice(selectedDevice, scheme, xcodeProject);
+ return runOnDevice(selectedDevice, scheme, xcodeProject, args.configuration);
} else {
if (devices){
console.log('Could not find device with the name: "' + args.device + '".');
@@ -42,19 +45,19 @@ function runIOS(argv, config, args) {
}
}
} else if (args.udid) {
- return runOnDeviceByUdid(args.udid, scheme, xcodeProject, devices);
+ return runOnDeviceByUdid(args, scheme, xcodeProject, devices);
} else {
return runOnSimulator(xcodeProject, args, inferredSchemeName, scheme);
}
}
-function runOnDeviceByUdid(udid, scheme, xcodeProject, devices) {
- const selectedDevice = matchingDeviceByUdid(devices, udid);
+function runOnDeviceByUdid(args, scheme, xcodeProject, devices) {
+ const selectedDevice = matchingDeviceByUdid(devices, args.udid);
if (selectedDevice){
- return runOnDevice(selectedDevice, scheme, xcodeProject);
+ return runOnDevice(selectedDevice, scheme, xcodeProject, args.configuration);
} else {
if (devices){
- console.log('Could not find device with the udid: "' + udid + '".');
+ console.log('Could not find device with the udid: "' + args.udid + '".');
console.log('Choose one of the following:');
printFoundDevices(devices);
} else {
@@ -88,12 +91,12 @@ function runOnSimulator(xcodeProject, args, inferredSchemeName, scheme){
}
resolve(selectedSimulator.udid)
})
- .then((udid) => buildProject(xcodeProject, udid, scheme))
+ .then((udid) => buildProject(xcodeProject, udid, scheme, args.configuration))
.then((appName) => {
if (!appName) {
appName = inferredSchemeName;
}
- const appPath = `build/Build/Products/Debug-iphonesimulator/${appName}.app`;
+ let appPath = getBuildPath(args.configuration, appName);
console.log(`Installing ${appPath}`);
child_process.spawnSync('xcrun', ['simctl', 'install', 'booted', appPath], {stdio: 'inherit'});
@@ -108,14 +111,14 @@ function runOnSimulator(xcodeProject, args, inferredSchemeName, scheme){
})
}
-function runOnDevice(selectedDevice, scheme, xcodeProject){
- return buildProject(xcodeProject, selectedDevice.udid, scheme)
+function runOnDevice(selectedDevice, scheme, xcodeProject, configuration){
+ return buildProject(xcodeProject, selectedDevice.udid, scheme, configuration)
.then((appName) => {
if (!appName) {
appName = scheme;
}
const iosDeployInstallArgs = [
- '--bundle', 'build/Build/Products/Debug-iphoneos/' + appName + '.app',
+ '--bundle', getBuildPath(configuration, appName, true),
'--id' , selectedDevice.udid,
'--justlaunch'
];
@@ -132,11 +135,12 @@ function runOnDevice(selectedDevice, scheme, xcodeProject){
});
}
-function buildProject(xcodeProject, udid, scheme) {
+function buildProject(xcodeProject, udid, scheme, configuration = 'Debug') {
return new Promise((resolve,reject) =>
{
- const xcodebuildArgs = [
+ var xcodebuildArgs = [
xcodeProject.isWorkspace ? '-workspace' : '-project', xcodeProject.name,
+ '-configuration', configuration,
'-scheme', scheme,
'-destination', `id=${udid}`,
'-derivedDataPath', 'build',
@@ -162,21 +166,19 @@ function buildProject(xcodeProject, udid, scheme) {
});
}
-
function matchingDevice(devices, deviceName) {
if (deviceName === true && devices.length === 1)
{
console.log(`Using first available device ${devices[0].name} due to lack of name supplied.`)
return devices[0];
- }
+ }
for (let i = devices.length - 1; i >= 0; i--) {
if (devices[i].name === deviceName || formattedDeviceName(devices[i]) === deviceName) {
return devices[i];
}
}
}
-
function matchingDeviceByUdid(devices, udid) {
for (let i = devices.length - 1; i >= 0; i--) {
if (devices[i].udid === udid) {
@@ -217,7 +219,10 @@ module.exports = {
command: '--simulator [string]',
description: 'Explicitly set simulator to use',
default: 'iPhone 6',
- }, {
+ } , {
+ command: '--configuration [string]',
+ description: 'Explicitly set the scheme configuration to use',
+ } , {
command: '--scheme [string]',
description: 'Explicitly set Xcode scheme to use',
}, {

0 comments on commit ca7cbde

Please sign in to comment.