diff --git a/src/dispatcher/iOSDevice.js b/src/dispatcher/iOSDevice.js index a3dc5c0e2..1942e73f6 100644 --- a/src/dispatcher/iOSDevice.js +++ b/src/dispatcher/iOSDevice.js @@ -9,7 +9,10 @@ import type {ChildProcess} from 'child_process'; import type {Store} from '../reducers/index.js'; import type Logger from '../fb-stubs/Logger.js'; +import {promisify} from 'util'; import child_process from 'child_process'; +const exec = promisify(child_process.exec); +const execFile = promisify(child_process.execFile); import IOSDevice from '../devices/IOSDevice'; type iOSSimulatorDevice = {| @@ -22,33 +25,57 @@ type iOSSimulatorDevice = {| type IOSDeviceMap = {[id: string]: Array}; // start port forwarding server for real device connections -const portForwarder: ChildProcess = child_process.exec( +const portForwarder: ChildProcess = exec( 'PortForwardingMacApp.app/Contents/MacOS/PortForwardingMacApp -portForward=8088 -multiplexChannelPort=8078', ); window.addEventListener('beforeunload', () => { portForwarder.kill(); }); -function querySimulatorDevices(): Promise { - return new Promise((resolve, reject) => { - child_process.execFile( - 'xcrun', - ['simctl', 'list', 'devices', '--json'], - {encoding: 'utf8'}, - (err, stdout) => { - if (err) { - reject(err); - } +function querySimulatorDevices(store: Store): Promise { + const {connections} = store.getState(); - try { - const {devices} = JSON.parse(stdout.toString()); - resolve(devices); - } catch (err) { - reject(err); + return execFile('xcrun', ['simctl', 'list', 'devices', '--json'], { + encoding: 'utf8', + }) + .then(({stdout}) => JSON.parse(stdout).devices) + .then((simulatorDevices: IOSDeviceMap) => { + const simulators: Array = Object.values( + simulatorDevices, + // $FlowFixMe + ).reduce((acc, cv) => acc.concat(cv), []); + + const currentDeviceIDs: Set = new Set( + connections.devices + .filter(device => device instanceof IOSDevice) + .map(device => device.serial), + ); + + const deviceIDsToRemove = new Set(); + simulators.forEach((simulator: iOSSimulatorDevice) => { + const isRunning = + simulator.state === 'Booted' && + simulator.availability === '(available)'; + + if (isRunning && !currentDeviceIDs.has(simulator.udid)) { + // create device + store.dispatch({ + type: 'REGISTER_DEVICE', + payload: new IOSDevice(simulator.udid, 'emulator', simulator.name), + }); + } else if (!isRunning && currentDeviceIDs.has(simulator.udid)) { + deviceIDsToRemove.add(simulator.udid); + // delete device } - }, - ); - }); + }); + + if (deviceIDsToRemove.size > 0) { + store.dispatch({ + type: 'UNREGISTER_DEVICES', + payload: deviceIDsToRemove, + }); + } + }); } export default (store: Store, logger: Logger) => { @@ -56,53 +83,14 @@ export default (store: Store, logger: Logger) => { if (process.platform !== 'darwin') { return; } - const simulatorUpdateInterval = setInterval(() => { - const {connections} = store.getState(); - querySimulatorDevices() - .then((simulatorDevices: IOSDeviceMap) => { - const simulators: Array = Object.values( - simulatorDevices, - // $FlowFixMe - ).reduce((acc, cv) => acc.concat(cv), []); - - const currentDeviceIDs: Set = new Set( - connections.devices - .filter(device => device instanceof IOSDevice) - .map(device => device.serial), - ); - - const deviceIDsToRemove = new Set(); - simulators.forEach((simulator: iOSSimulatorDevice) => { - const isRunning = - simulator.state === 'Booted' && - simulator.availability === '(available)'; - - if (isRunning && !currentDeviceIDs.has(simulator.udid)) { - // create device - store.dispatch({ - type: 'REGISTER_DEVICE', - payload: new IOSDevice( - simulator.udid, - 'emulator', - simulator.name, - ), - }); - } else if (!isRunning && currentDeviceIDs.has(simulator.udid)) { - deviceIDsToRemove.add(simulator.udid); - // delete device - } + querySimulatorDevices(store) + .then(() => { + const simulatorUpdateInterval = setInterval(() => { + querySimulatorDevices(store).catch(err => { + console.error(err); + clearInterval(simulatorUpdateInterval); }); - - if (deviceIDsToRemove.size > 0) { - store.dispatch({ - type: 'UNREGISTER_DEVICES', - payload: deviceIDsToRemove, - }); - } - }) - .catch(err => { - console.error(err); - clearInterval(simulatorUpdateInterval); - }); - }, 3000); + }, 3000); + }) + .catch(console.error); };