From 5a7bfc61cc4c00ff0d5baece826c0ecf503eada7 Mon Sep 17 00:00:00 2001 From: Siddarth Kumar Date: Tue, 20 Feb 2024 10:54:09 +0530 Subject: [PATCH] fix: make run-ios-device script (#18845) fixes #16310 We used to reply on `react-native cli` and would pass a `--device` flag to deploy the debug variant of `iOS` app on connected `iPhone`. `react-native cli` under the hood uses `ios-deploy` library to achieve this functionality. This showed many weird issues, specifically in locating connected devices and failures at build step with ambiguous error messages. This commit fixes it by using our custom script `run-ios-devices.sh` which does not rely on `ios-deploy`. We use `libimobiledevice` to identify `UDID` of a connected `iPhone`. We use `xcrun devicectl device install app` and `xcrun devicectl device process launch` to install and launch the app. This works well with `Xcode 15` and `iOS 17.x`. We can now remove `ios-deploy` from `iOS` shell and `nix` overlay. We also set up a logs folder and add a Readme. ## Review notes - connect your iPhone to your Laptop via a cable - `make run-clojure` - `make run-ios-device` (note: no need to pass device name now) ## Platforms - iOS --- .gitignore | 10 ++----- Makefile | 7 ++--- logs/README.md | 18 +++++++++++++ nix/mobile/ios/default.nix | 2 +- nix/overlay.nix | 12 --------- scripts/run-ios-device.sh | 55 ++++++++++++++++++++++++++++++++++++++ scripts/run-ios.sh | 5 ++-- 7 files changed, 81 insertions(+), 28 deletions(-) create mode 100644 logs/README.md create mode 100755 scripts/run-ios-device.sh diff --git a/.gitignore b/.gitignore index 666e844742..ca93eceb4c 100644 --- a/.gitignore +++ b/.gitignore @@ -195,11 +195,5 @@ test/appium/tests/users.py ## git hooks lefthook.yml -## metro server logs -metro-server-logs.log - -## debug build time logs -logs/ - -## available iOS simulators -ios_simulators_list.json +## build time logs +/logs/*.log diff --git a/Makefile b/Makefile index c1fc6ca074..18ca317c78 100644 --- a/Makefile +++ b/Makefile @@ -296,11 +296,8 @@ show-ios-devices: ##@other shows connected ios device and its name # TODO: fix IOS_STATUS_GO_TARGETS to be either amd64 or arm64 when RN is upgraded run-ios-device: export TARGET := ios run-ios-device: export IOS_STATUS_GO_TARGETS := ios/arm64;iossimulator/amd64 -run-ios-device: ##@run iOS app and start it on a connected device by its name -ifndef DEVICE_NAME - $(error Usage: make run-ios-device DEVICE_NAME=your-device-name) -endif - react-native run-ios --device "$(DEVICE_NAME)" +run-ios-device: ##@run iOS app and start it on the first connected iPhone + @scripts/run-ios-device.sh #-------------- # Tests diff --git a/logs/README.md b/logs/README.md new file mode 100644 index 0000000000..eaea0d52ed --- /dev/null +++ b/logs/README.md @@ -0,0 +1,18 @@ +# Description + +This directory is the destination of logs created during build time of debug builds. + +# Logs + +* `xcrun_device_install.log` - Output from `status-mobile/scripts/run-ios-device.sh`. + - Created by redirecting output of `xcrun simctl install "$UDID" "$APP_PATH"`. +* `xcrun_device_process_launch.log` - Output from `status-mobile/scripts/run-ios-device.sh`. + - Created by specifying `--json-output` flag for `xcrun devicectl device process launch --no-activate --verbose --device "${DEVICE_UUID}" "${INSTALLATION_URL}"`. +* `xcrun_device_process_resume.log` - Output from `status-mobile/scripts/run-ios-device.sh`. + - Created by redirecting output of `xcrun devicectl device process resume --device "${DEVICE_UUID}" --pid "${STATUS_PID}"`. +* `adb_install.log` - Output from `scripts/run-android.sh`. + - Created by redirecting output of `adb install -r ./result/app-debug.apk`. +* `adb_shell_monkey.log` - Output from `status-mobile/scripts/run-android.sh`. + - Created by redirecting output of `adb shell monkey -p im.status.ethereum.debug 1 >`. +* `ios_simulators_list.log` - Output from `status-mobile/scripts/run-ios.sh`. + - Created by redirecting output of `xcrun simctl list devices -j`. diff --git a/nix/mobile/ios/default.nix b/nix/mobile/ios/default.nix index affb530363..ca423f50f1 100644 --- a/nix/mobile/ios/default.nix +++ b/nix/mobile/ios/default.nix @@ -20,8 +20,8 @@ in { buildInputs = with pkgs; [ xcodeWrapper watchman procps flock # used in nix/scripts/node_modules.sh - ios-deploy # used in 'make run-ios-device' xcbeautify # used in 'make run-ios' + libimobiledevice # used in `make run-ios-device` ]; # WARNING: Executes shellHook in reverse order. diff --git a/nix/overlay.nix b/nix/overlay.nix index 63875026fd..b0029f92f7 100644 --- a/nix/overlay.nix +++ b/nix/overlay.nix @@ -26,18 +26,6 @@ in { react-native = callPackage ./deps/react-native { }; }; - # Fix for missing libarclite_macosx.a in Xcode 14.3. - # https://github.com/ios-control/ios-deploy/issues/580 - ios-deploy = super.darwin.ios-deploy.overrideAttrs (old: rec { - version = "1.12.2"; - src = super.fetchFromGitHub { - owner = "ios-control"; - repo = "ios-deploy"; - rev = version; - sha256 = "sha256-TVGC+f+1ow3b93CK3PhIL70le5SZxxb2ug5OkIg8XCA"; - }; - }); - # Clojure's linter receives frequent upgrades, and we want to take advantage # of the latest available rules. clj-kondo = super.clj-kondo.override rec { diff --git a/scripts/run-ios-device.sh b/scripts/run-ios-device.sh new file mode 100755 index 0000000000..11cbd5f2dd --- /dev/null +++ b/scripts/run-ios-device.sh @@ -0,0 +1,55 @@ +#!/usr/bin/env bash +set -euo pipefail +set -m # needed to access jobs + +GIT_ROOT=$(cd "${BASH_SOURCE%/*}" && git rev-parse --show-toplevel) +XCRUN_DEVICE_INSTALL_LOG_DIR="${GIT_ROOT}/logs/xcrun_device_install.log" +XCRUN_DEVICE_PROCESS_LAUNCH_LOG_DIR="${GIT_ROOT}/logs/xcrun_device_process_launch.log" +XCRUN_DEVICE_PROCESS_RESUME_LOG_DIR="${GIT_ROOT}/logs/xcrun_device_process_resume.log" + +# Install on the connected device +installAndLaunchApp() { + xcrun devicectl device install app --device "${DEVICE_UUID}" "${APP_PATH}" --json-output "${XCRUN_DEVICE_INSTALL_LOG_DIR}" 2>&1 + + # Extract installationURL + INSTALLATION_URL=$(jq -r '.result.installedApplications[0].installationURL' "${XCRUN_DEVICE_INSTALL_LOG_DIR}") + + # launch the app and put it in background + xcrun devicectl device process launch --no-activate --verbose --device "${DEVICE_UUID}" "${INSTALLATION_URL}" --json-output "${XCRUN_DEVICE_PROCESS_LAUNCH_LOG_DIR}" + + # Extract background PID of status app + STATUS_PID=$(jq -r '.result.process.processIdentifier' "${XCRUN_DEVICE_PROCESS_LAUNCH_LOG_DIR}") + "${GIT_ROOT}/scripts/wait-for-metro-port.sh" 2>&1 + + # now that metro is ready, resume the app from background + xcrun devicectl device process resume --device "${DEVICE_UUID}" --pid "${STATUS_PID}" > "${XCRUN_DEVICE_PROCESS_RESUME_LOG_DIR}" 2>&1 +} + +showXcrunLogs() { + cat "${XCRUN_DEVICE_INSTALL_LOG_DIR}" >&2; + cat "${XCRUN_DEVICE_PROCESS_LAUNCH_LOG_DIR}" >&2; + cat "${XCRUN_DEVICE_PROCESS_RESUME_LOG_DIR}" >&2; +} + +# find the first connected iPhone's UUID +DEVICE_UUID=$(idevice_id -l) + +# Check if any device is connected +if [ -z "${DEVICE_UUID}" ]; then + echo "No connected iPhone device detected." + exit 1 +else + echo "Connected iPhone UDID: ${DEVICE_UUID}" +fi + +BUILD_DIR="${GIT_ROOT}/build" + +#iOS build of debug scheme +xcodebuild -workspace "ios/StatusIm.xcworkspace" -configuration Debug -scheme StatusIm -destination id="${DEVICE_UUID}" -derivedDataPath "${BUILD_DIR}" -verbose | xcbeautify + +APP_PATH="${BUILD_DIR}/Build/Products/Debug-iphoneos/StatusIm.app" + +trap showXcrunLogs EXIT ERR INT QUIT +installAndLaunchApp & +exec "${GIT_ROOT}/scripts/run-metro.sh" 2>&1 + diff --git a/scripts/run-ios.sh b/scripts/run-ios.sh index affcbd2d09..49a3ae45fc 100755 --- a/scripts/run-ios.sh +++ b/scripts/run-ios.sh @@ -5,6 +5,7 @@ set -m # needed to access jobs GIT_ROOT=$(cd "${BASH_SOURCE%/*}" && git rev-parse --show-toplevel) XCRUN_INSTALL_LOG_FILE="${GIT_ROOT}/logs/xcrun_install.log" XCRUN_LAUNCH_LOG_FILE="${GIT_ROOT}/logs/xcrun_launch.log" +XCRUN_SIMULATOR_JSON_FILE="${GIT_ROOT}/logs/ios_simulators_list.log" # Install on the simulator installAndLaunchApp() { @@ -26,7 +27,7 @@ if [ -z "${1-}" ]; then fi # fetch available iOS Simulators -xcrun simctl list devices -j > ios_simulators_list.json +xcrun simctl list devices -j > "${XCRUN_SIMULATOR_JSON_FILE}" SIMULATOR=${1} @@ -36,7 +37,7 @@ read -r UDID SIMULATOR_STATE IS_AVAILABLE < <(jq --raw-output --arg simulator "$ map(select(.isAvailable)) + map(select(.isAvailable | not)) | first | "\(.udid) \(.state) \(.isAvailable)" -' ios_simulators_list.json) +' "${XCRUN_SIMULATOR_JSON_FILE}") if [ "${IS_AVAILABLE}" == false ] || [ "${UDID}" == null ]; then echo "Error: Simulator ${SIMULATOR} is not available, Please find and install them."