Skip to content

Commit

Permalink
fix: make run-ios-device script (#18845)
Browse files Browse the repository at this point in the history
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
  • Loading branch information
siddarthkay authored Feb 20, 2024
1 parent 50f6c1e commit 5a7bfc6
Show file tree
Hide file tree
Showing 7 changed files with 81 additions and 28 deletions.
10 changes: 2 additions & 8 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -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
7 changes: 2 additions & 5 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
18 changes: 18 additions & 0 deletions logs/README.md
Original file line number Diff line number Diff line change
@@ -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`.
2 changes: 1 addition & 1 deletion nix/mobile/ios/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
12 changes: 0 additions & 12 deletions nix/overlay.nix
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
55 changes: 55 additions & 0 deletions scripts/run-ios-device.sh
Original file line number Diff line number Diff line change
@@ -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

5 changes: 3 additions & 2 deletions scripts/run-ios.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand All @@ -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}

Expand All @@ -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."
Expand Down

0 comments on commit 5a7bfc6

Please sign in to comment.