xref: /expo/packages/@expo/cli/src/run/ios/launchApp.ts (revision bb5069cd)
1import chalk from 'chalk';
2import path from 'path';
3
4import { AppleDeviceManager } from '../../start/platforms/ios/AppleDeviceManager';
5import { SimulatorLogStreamer } from '../../start/platforms/ios/simctlLogging';
6import { DevServerManager } from '../../start/server/DevServerManager';
7import { parsePlistAsync } from '../../utils/plist';
8import { profile } from '../../utils/profile';
9import * as XcodeBuild from './XcodeBuild';
10import { BuildProps } from './XcodeBuild.types';
11import { getAppDeltaDirectory, installOnDeviceAsync } from './appleDevice/installOnDeviceAsync';
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