pickSimulatorDevice function

SimulatorDeviceResolution pickSimulatorDevice(
  1. List<SimulatorDevice> simulators, {
  2. required String? deviceOverride,
  3. required String? sessionDevice,
})

Applies the precedence of resolveSimulatorDevice to an already fetched simulators list, so callers that need the list themselves (for example to decide whether a device ID is a simulator at all) list devices only once.

Implementation

SimulatorDeviceResolution pickSimulatorDevice(
  List<SimulatorDevice> simulators, {
  required String? deviceOverride,
  required String? sessionDevice,
}) {
  if (deviceOverride != null) {
    final sim = findSimulator(simulators, deviceOverride);
    if (sim == null) {
      return (
        udid: null,
        error: 'No iOS simulator with UDID $deviceOverride. List them with: xcrun simctl list devices',
      );
    }
    if (sim.state != 'Booted') {
      return (udid: null, error: 'Simulator ${_describe(sim)} is not booted (state: ${sim.state}).');
    }
    return (udid: sim.udid, error: null);
  }

  final sessionSim = sessionDevice == null ? null : findSimulator(simulators, sessionDevice);
  if (sessionSim != null) {
    if (sessionSim.state != 'Booted') {
      return (
        udid: null,
        error: 'The session simulator ${_describe(sessionSim)} is not booted (state: ${sessionSim.state}). '
            'Boot it, or target another booted simulator with --device <udid>.',
      );
    }
    return (udid: sessionSim.udid, error: null);
  }

  // Only iOS-runtime simulators are auto-pick candidates: a booted watchOS,
  // tvOS or visionOS simulator (e.g. the pair of an iPhone) is not a target.
  final booted = simulators.where((sim) => sim.state == 'Booted' && sim.runtime.contains(_iosRuntimeMarker)).toList();
  if (booted.isEmpty) {
    return (
      udid: null,
      error: 'No booted iOS simulator. Boot one with: xcrun simctl boot <udid>',
    );
  }
  if (booted.length > 1) {
    return (
      udid: null,
      error: 'Multiple booted iOS simulators and no fdb session simulator to choose from. '
          'Pass --device <udid> with one of:\n${booted.map((sim) => '  ${_describe(sim)}').join('\n')}',
    );
  }
  return (udid: booted.single.udid, error: null);
}