Skip to content

Commit

Permalink
Merge pull request #1759 from flexn-io/fix/tvOS-launch
Browse files Browse the repository at this point in the history
fix(tvOS): Replace ios-deploy with xcrun commands in @react-native-community/cli-platfom-ios
  • Loading branch information
pauliusguzas authored Nov 8, 2024
2 parents 67514f1 + 8433440 commit 72bada7
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 43 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,11 @@
"{\n isAvailable: device.available,": "{\n modelName:device.modelName, // <= PATCHED BY RENATIVE\n isAvailable: device.available,"
},
"build/commands/runIOS/index.js": {
"_cliTools().logger.error(`Could not find a device named: \"${_chalk().default.bold(String(deviceName))}\". ${printFoundDevices(devices)}`);": "_cliTools().logger.error(`Could not find a device: \"${_chalk().default.bold(String(deviceName))}\". ${printFoundDevices(devices)}`);\n throw 'Could not find device'; // <= PATCHED BY RENATIVE"
"_cliTools().logger.error(`Could not find a device named: \"${_chalk().default.bold(String(deviceName))}\". ${printFoundDevices(devices)}`);": "_cliTools().logger.error(`Could not find a device: \"${_chalk().default.bold(String(deviceName))}\". ${printFoundDevices(devices)}`);\n throw 'Could not find device'; // <= PATCHED BY RENATIVE",
"throw new (_cliTools().CLIError)(`Failed to install the app on the device because we couldn't execute the \"ios-deploy\" command. Please install it by running \"${_chalk().default.bold('brew install ios-deploy')}\" and try again.`);": "// <= PATCHED BY RENATIVE, remove ios-deploy check",
"const iosDeployInstallArgs = ['--bundle', appPath, '--id', selectedDevice.udid, '--justlaunch'];": " if(!selectedDevice.modelName.includes('Apple TV')) {\n const iosDeployInstallArgs = ['--bundle', appPath, '--id', selectedDevice.udid, '--justlaunch'];",
"if (iosDeployOutput.error) {\n throw new (_cliTools().CLIError)(`Failed to install the app on the device. We've encountered an error in \"ios-deploy\" command: ${iosDeployOutput.error.message}`);\n }": "if (iosDeployOutput.error) {\n throw new (_cliTools().CLIError)(`Failed to install the app on the device. We've encountered an error in \"ios-deploy\" command: ${iosDeployOutput.error.message}`);\n }} else {\n _cliTools().logger.info(`Installing your app on ${selectedDevice.name}`);\n const iosInstallArgs = ['devicectl', 'device', 'install', 'app', '--device', selectedDevice.udid, appPath];\n _cliTools().logger.info(`xcrun ${iosInstallArgs.join(' ')}`);\n const iosInstallOutput = _child_process().default.spawnSync('xcrun', iosInstallArgs, {\n stdio: 'pipe',\n encoding: 'utf8',\n });\n const res = JSON.stringify(iosInstallOutput);\n const installationUrl = res.substring(\n res.indexOf('file:') || 0,\n (res.indexOf('.app/') || 0) + '.app/'.length\n );\n _cliTools().logger.info(`Launching your app on ${selectedDevice.name}`);\n const iosLaunchArgs = ['devicectl', 'device', 'process', 'launch', '--device', selectedDevice.udid, installationUrl];\n _cliTools().logger.info(`xcrun ${iosLaunchArgs.join(' ')}`);\n _child_process().default.spawnSync('xcrun', iosLaunchArgs, {\n stdio: 'inherit'\n });\n if (iosInstallOutput.stderr) {\n throw new (_cliTools().CLIError)(`Failed to install the app on the device. We've encountered an error: ${iosInstallOutput.stderr}`);\n }\n }"
}
}
}

44 changes: 2 additions & 42 deletions packages/sdk-apple/src/runner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ import {
import { registerDevice } from './fastlane';
import { Context, getContext } from './getContext';
import { parsePrivacyManifest } from './privacyManifestParser';
import { getAppId } from '@rnv/sdk-utils';

export const packageBundleForXcode = () => {
return packageReactNativeIOS();
Expand Down Expand Up @@ -275,48 +274,10 @@ export const runXcodeProject = async (runDeviceArguments?: string) => {
const bundleAssets = getConfigProp('bundleAssets') === true;

if (runDeviceArguments) {
// await launchAppleSimulator(c, c.runtime.target); @TODO - do we still need this? RN CLI does it as well
//const allowProvisioningUpdates = getConfigProp('allowProvisioningUpdates', true);
//if (allowProvisioningUpdates) p = `${p} --allowProvisioningUpdates`;
if (bundleAssets) {
await packageReactNativeIOS(bundleIsDev);
}
if (c.platform === 'tvos' && !runDeviceArguments.includes('--simulator')) {
try {
await executeAsync(`ios-deploy -c`);
} catch (error) {
if (typeof error === 'string' && error.includes('Command failed with exit code 253')) {
logError(
`Ios-deploy couldn't find a connected device. For a more reliable connection, use a USB cable instead of wireless.`
);
const { confirm } = await inquirerPrompt({
type: 'confirm',
name: 'confirm',
message: 'Would you like to use an Xcode script to build and launch the app?',
});
if (confirm) {
try {
await buildXcodeProject();
} catch (e) {
await _handleMissingTeam(c, e);
}
const udid = runDeviceArguments.split(' ')[1];

await executeAsync(
`xcrun devicectl device install app -d ${udid} ${path.join(
appPath,
`build/RNVApp/Build/Products/${runScheme}-appletvos/RNVApp-tvOS.app`
)}`
);

return executeAsync(
`xcrun devicectl device process launch --device ${udid} --activate ${getAppId()?.toLowerCase()}`
);
}
return;
}
}
}

return _checkLockAndExec(c, appPath, schemeTarget, runScheme, runDeviceArguments);
}

Expand All @@ -335,7 +296,6 @@ export const runXcodeProject = async (runDeviceArguments?: string) => {
`open ${path.join(appPath, `build/RNVApp/Build/Products/${runScheme}-maccatalyst/RNVApp.app`)}`
);
}
// return Promise.reject('Missing options for react-native command!');
};

const _checkLockAndExec = async (
Expand Down Expand Up @@ -369,7 +329,7 @@ const _checkLockAndExec = async (
logWarning(
`${c.platform} DEVICE: ${chalk().bold.white(c.runtime.target)} with UDID: ${chalk().bold.white(
c.runtime.targetUDID
)} is not included in your provisionong profile in TEAM: ${chalk().bold.white(
)} is not included in your provisioning profile in TEAM: ${chalk().bold.white(
getConfigProp('teamID')
)}`
);
Expand Down
15 changes: 15 additions & 0 deletions packages/sdk-react-native/src/iosRunner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,14 @@ import {
inquirerPrompt,
RnvEnvContext,
isOfflineMode,
logWarning,
} from '@rnv/core';
import { EnvVars } from './env';
import shellQuote from 'shell-quote';
import path from 'path';
import crypto from 'crypto';
import { ObjectEncodingOptions } from 'fs';
import child_process, { ExecFileOptions } from 'child_process';

export const packageReactNativeIOS = (isDev = false) => {
const c = getContext();
Expand Down Expand Up @@ -93,6 +96,18 @@ export const runReactNativeIOS = async (
};

try {
// Check if it's an older XCode and show a warning as xcrun commands used
// to install and launch were introduced in xcode 15
const opts: ObjectEncodingOptions & ExecFileOptions = { encoding: 'utf8' };
const child = child_process.spawnSync('xcodebuild', ['-version'], opts);
const xcodeVersion =
JSON.stringify(child.stdout).substring(
JSON.stringify(child.stdout).indexOf('Xcode ') + 6,
JSON.stringify(child.stdout).indexOf('Build') - 2
) || '0';
if (Number(xcodeVersion) < 15)
logWarning('Installing application and launching it with an Xcode older than 15 may not work');

// Inherit full logs
// return executeAsync(c, cmd, { stdio: 'inherit', silent: true });
return executeAsync(cmd, {
Expand Down

0 comments on commit 72bada7

Please sign in to comment.