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