diff --git a/packages/config-templates/pluginTemplates/@react-native-community/cli-platform-ios/overrides@12.3.6.json b/packages/config-templates/pluginTemplates/@react-native-community/cli-platform-ios/overrides@12.3.6.json index 71f088ab8..ec35e3543 100644 --- a/packages/config-templates/pluginTemplates/@react-native-community/cli-platform-ios/overrides@12.3.6.json +++ b/packages/config-templates/pluginTemplates/@react-native-community/cli-platform-ios/overrides@12.3.6.json @@ -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 }" } } } + \ No newline at end of file diff --git a/packages/sdk-apple/src/runner.ts b/packages/sdk-apple/src/runner.ts index 9788fa626..b44c15a01 100644 --- a/packages/sdk-apple/src/runner.ts +++ b/packages/sdk-apple/src/runner.ts @@ -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(); @@ -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); } @@ -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 ( @@ -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') )}` ); diff --git a/packages/sdk-react-native/src/iosRunner.ts b/packages/sdk-react-native/src/iosRunner.ts index 09104ce79..e7ee3d951 100644 --- a/packages/sdk-react-native/src/iosRunner.ts +++ b/packages/sdk-react-native/src/iosRunner.ts @@ -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(); @@ -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, {