# All files / src/platformTools/apple deviceManager.js

19.78% Statements 18/91
0% Branches 0/55
0% Functions 0/10
20% Lines 14/70

Press n or j to go to the next uncovered block, b, p or k for the previous block.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    1232x
    2x
    2x
    2x

    2x

    2x

    2x

    2x

    2x

    2x

    2x

    2x

    2x

    2x
     import inquirer from 'inquirer';
    import chalk from 'chalk';
    import child_process from 'child_process';
    import {
        getAppFolder,
        isPlatformActive,
    } from '../../common';
    import { logToSummary, logTask,
        logError,
        logWarning, logDebug } from '../../systemTools/logger';
    import { IOS, TVOS } from '../../constants';

    export const getAppleDevices = (c, platform, ignoreDevices, ignoreSimulators) => {
        logTask(`getAppleDevices:${platform},ignoreDevices:${ignoreDevices},ignoreSimulators${ignoreSimulators}`);
        const devices = child_process.execFileSync('xcrun', ['instruments', '-s'], {
            encoding: 'utf8',
        });

        const devicesArr = _parseIOSDevicesList(devices, platform, ignoreDevices, ignoreSimulators);
        return devicesArr;
    };

    const _parseIOSDevicesList = (text, platform, ignoreDevices = false, ignoreSimulators = false) => {
        const devices = [];
        text.split('\n').forEach((line) => {
            const s1 = line.match(/\[.*?\]/);
            const s2 = line.match(/\(.*?\)/g);
            const s3 = line.substring(0, line.indexOf('(') - 1);
            const s4 = line.substring(0, line.indexOf('[') - 1);
            let isSim = false;
            if (s2 && s1) {
                if (s2[s2.length - 1] === '(Simulator)') {
                    isSim = true;
                    s2.pop();
                }
                const version = s2.pop();
                let name = `${s4.substring(0, s4.lastIndexOf('(') - 1)}`;
                name = name || 'undefined';
                const udid = s1[0].replace(/\[|\]/g, '');
                const isDevice = !isSim;

                if ((isDevice && !ignoreDevices) || (!isDevice && !ignoreSimulators)) {
                    switch (platform) {
                    case IOS:
                        if (name.includes('iPhone') || name.includes('iPad') || name.includes('iPod') || isDevice) {
                            let icon = 'Phone 📱';
                            if (name.includes('iPad')) icon = 'Tablet 💊';
                            devices.push({ udid, name, version, isDevice, icon });
                        }
                        break;
                    case TVOS:
                        if ((name.includes('Apple TV') || isDevice) && !name.includes('iPhone') && !name.includes('iPad')) {
                            devices.push({ udid, name, version, isDevice, icon: 'TV 📺' });
                        }
                        break;
                    default:
                        devices.push({ udid, name, version, isDevice });
                        break;
                    }
                }
            }
        });

        return devices;
    };

    export const launchAppleSimulator = async (c, platform, target) => {
        logTask(`launchAppleSimulator:${platform}:${target}`);

        const devicesArr = getAppleDevices(c, platform, true);
        let selectedDevice;
        for (let i = 0; i < devicesArr.length; i++) {
            if (devicesArr[i].name === target) {
                selectedDevice = devicesArr[i];
            }
        }
        if (selectedDevice) {
            _launchSimulator(selectedDevice);
            return selectedDevice.name;
        }

        logWarning(`Your specified simulator target ${chalk.white(target)} doesn't exists`);
        const devices = devicesArr.map(v => ({ name: `${v.name} | ${v.icon} | v: ${chalk.green(v.version)} | udid: ${chalk.grey(v.udid)}${v.isDevice ? chalk.red(' (device)') : ''}`, value: v }));

        const { sim } = await inquirer.prompt({
            name: 'sim',
            message: 'Select the simulator you want to launch',
            type: 'list',
            choices: devices
        });

        if (sim) {
            _launchSimulator(sim);
            return sim.name;
        }
        return Promise.reject('Action canceled!');
    };

    const _launchSimulator = (selectedDevice) => {
        try {
            child_process.spawnSync('xcrun', ['instruments', '-w', selectedDevice.udid]);
        } catch (e) {
            // instruments always fail with 255 because it expects more arguments,
            // but we want it to only launch the simulator
        }
    };

    export const listAppleDevices = (c, platform) => new Promise((resolve) => {
        logTask(`listAppleDevices:${platform}`);

        const devicesArr = getAppleDevices(c, platform);
        let devicesString = '';
        devicesArr.forEach((v, i) => {
            devicesString += ` [${i + 1}]> ${chalk.bold(v.name)} | ${v.icon} | v: ${chalk.green(v.version)} | udid: ${chalk.grey(v.udid)}${
                v.isDevice ? chalk.red(' (device)') : ''
            }\n`;
        });

        logToSummary(`${platform} Targets:\n\n${devicesString}`);

        resolve();
    });