1import chalk from 'chalk'; 2import path from 'path'; 3 4import * as XcodeBuild from './XcodeBuild'; 5import { BuildProps } from './XcodeBuild.types'; 6import { getAppDeltaDirectory, installOnDeviceAsync } from './appleDevice/installOnDeviceAsync'; 7import { AppleDeviceManager } from '../../start/platforms/ios/AppleDeviceManager'; 8import { SimulatorLogStreamer } from '../../start/platforms/ios/simctlLogging'; 9import { DevServerManager } from '../../start/server/DevServerManager'; 10import { parsePlistAsync } from '../../utils/plist'; 11import { profile } from '../../utils/profile'; 12 13/** Install and launch the app binary on a device. */ 14export async function launchAppAsync( 15 binaryPath: string, 16 manager: DevServerManager, 17 props: Pick<BuildProps, 'isSimulator' | 'device' | 'shouldStartBundler'> 18) { 19 const appId = await profile(getBundleIdentifierForBinaryAsync)(binaryPath); 20 21 if (!props.isSimulator) { 22 await profile(installOnDeviceAsync)({ 23 bundleIdentifier: appId, 24 bundle: binaryPath, 25 appDeltaDirectory: getAppDeltaDirectory(appId), 26 udid: props.device.udid, 27 deviceName: props.device.name, 28 }); 29 return; 30 } 31 32 XcodeBuild.logPrettyItem(chalk`{bold Installing} on ${props.device.name}`); 33 34 const device = await AppleDeviceManager.resolveAsync({ device: props.device }); 35 await device.installAppAsync(binaryPath); 36 37 XcodeBuild.logPrettyItem(chalk`{bold Opening} on ${device.name} {dim (${appId})}`); 38 39 if (props.shouldStartBundler) { 40 await SimulatorLogStreamer.getStreamer(device.device, { 41 appId, 42 }).attachAsync(); 43 } 44 45 await manager.getDefaultDevServer().openCustomRuntimeAsync( 46 'simulator', 47 { 48 applicationId: appId, 49 }, 50 { device } 51 ); 52} 53 54async function getBundleIdentifierForBinaryAsync(binaryPath: string): Promise<string> { 55 const builtInfoPlistPath = path.join(binaryPath, 'Info.plist'); 56 const { CFBundleIdentifier } = await parsePlistAsync(builtInfoPlistPath); 57 return CFBundleIdentifier; 58} 59