📱 Auto-deciding simulator vs device script for iOS React Native

Filed under:

It involves combining the instruments, xcrun Xcode CLI tools to see if an USB device is attached, otherwise run it via the Simulator

# Get a list of available USB attached devices, provide --simulator to also output available sims
function list_ios_devices() {
  echo -e "\033[0;32mAvailable devices (USB):\033[0m"
  instruments -s devices | grep -v Simulator | grep -v Mac | grep -v "Known Devices:"

  if [ "$1" == "--simulators" ]; then
    echo ""
    echo -e "\033[0;32mAvailable simulators:\033[0m"
    xcrun simctl list | grep iPhone | sed 's/Phone://' | sed 's/(.*)//' | sort -u | awk '{$1=$1};1' | uniq -u
  fi
}

# Requires ios-deploy from npm and xcrun from Xcode dev toolchain. Can dynamically decide which scheme to use. Will automatically grab the connected USB device from `instruments`
function run_ios() {
  if ! command -v ios-deploy > /dev/null; then
    echo "ios-deploy is required but was not found."
    echo "Please follow the instructions to install ios-deploy:"
    echo "  → https://github.com/ios-control/ios-deploy#readme"
    exit 1
  fi

  if ! command -v xcrun > /dev/null; then
    echo "xcrun is required but was not found.";
    echo "Please make sure latest Xcode is installed and you have the xcode CLI tools by running:"
    echo "  $ xcode-select --install"
    exit 1
  fi

  local scheme
  local device
  device=$(list_ios_devices "$@" | tail -1)

  case "$1" in
    debug)
      scheme="(Dev)"
      ;;
    client)
      scheme="(Client)"
      ;;
    rc)
      scheme="(Release)"
      ;;
    release)
      scheme="(AppStore)"
      ;;
    *)
      scheme="(Dev)"
      ;;
  esac

  if echo "$device" | grep -q "Available devices"; then
    echo -e "\033[0;32mExecuting (Simulator): react-native run-ios --scheme \"$scheme\"\033[0m"
    react-native run-ios --scheme "$scheme"
  else
    device=$(echo "$device" | sed 's/(.*]//;s/^ *//;s/ *$//;s/  */ /;')
    echo -e "\033[0;32mExecuting (USB Device): react-native run-ios --scheme \"$scheme\" --device \"$device\"\033[0m"
    react-native run-ios --scheme "$scheme" --device "$device"
  fi
}

Via npm run-task:

{
  "scripts": {
    "ios:debug": "./run-ios.sh debug",
    "ios:client": "./run-ios.sh client",
    "ios:rc": "./run-ios.sh rc",
    "ios:release": "./run-ios.sh release",
  }
}