From 5d52c24f225a8278c89c33908a24d79f7c880822 Mon Sep 17 00:00:00 2001 From: danielpaulus Date: Mon, 21 Nov 2022 15:43:48 +0100 Subject: [PATCH] Add --wait to ios launch (#205) adds new --wait switch to keep the command running and display application logs when an app is launched with ios launch [bundleID] --- ios/dtx_codec/connection.go | 12 ++++++++---- ios/instruments/processcontrol.go | 18 ++++++++++++------ main.go | 12 +++++++++--- 3 files changed, 29 insertions(+), 13 deletions(-) diff --git a/ios/dtx_codec/connection.go b/ios/dtx_codec/connection.go index f185a08b..706ac9c9 100644 --- a/ios/dtx_codec/connection.go +++ b/ios/dtx_codec/connection.go @@ -1,13 +1,13 @@ package dtx import ( + "github.com/danielpaulus/go-ios/ios" "io" + "math" "strings" "sync" "time" - "math" - ios "github.com/danielpaulus/go-ios/ios" "github.com/danielpaulus/go-ios/ios/nskeyedarchiver" log "github.com/sirupsen/logrus" ) @@ -73,9 +73,13 @@ func (g GlobalDispatcher) Dispatch(msg Message) { } //TODO: use the dispatchFunctions map if "outputReceived:fromProcess:atTime:" == msg.Payload[0] { - msg, err := nskeyedarchiver.Unarchive(msg.Auxiliary.GetArguments()[0].([]byte)) + logmsg, err := nskeyedarchiver.Unarchive(msg.Auxiliary.GetArguments()[0].([]byte)) if err == nil { - log.Info(msg[0]) + log.WithFields(log.Fields{ + "msg": logmsg[0], + "pid": msg.Auxiliary.GetArguments()[1], + "time": msg.Auxiliary.GetArguments()[2], + }).Info("outputReceived:fromProcess:atTime:") } return } diff --git a/ios/instruments/processcontrol.go b/ios/instruments/processcontrol.go index 13aa0205..1d302d37 100644 --- a/ios/instruments/processcontrol.go +++ b/ios/instruments/processcontrol.go @@ -2,7 +2,6 @@ package instruments import ( "fmt" - "github.com/danielpaulus/go-ios/ios" dtx "github.com/danielpaulus/go-ios/ios/dtx_codec" log "github.com/sirupsen/logrus" @@ -16,13 +15,20 @@ type ProcessControl struct { //LaunchApp launches the app with the given bundleID on the given device.LaunchApp //Use LaunchAppWithArgs for passing arguments and envVars. It returns the PID of the created app process. func (p *ProcessControl) LaunchApp(bundleID string) (uint64, error) { - options := map[string]interface{}{} - options["StartSuspendedKey"] = uint64(0) - return p.StartProcess(bundleID, map[string]interface{}{}, []interface{}{}, options) + opts := map[string]interface{}{ + "StartSuspendedKey": uint64(0), + } + // Xcode sends all these, no idea if we need them for sth. later. + //"CA_ASSERT_MAIN_THREAD_TRANSACTIONS": "0", "CA_DEBUG_TRANSACTIONS": "0", "LLVM_PROFILE_FILE": "/dev/null", "METAL_DEBUG_ERROR_MODE": "0", "METAL_DEVICE_WRAPPER_TYPE": "1", + //"OS_ACTIVITY_DT_MODE": "YES", "SQLITE_ENABLE_THREAD_ASSERTIONS": "1", "__XPC_LLVM_PROFILE_FILE": "/dev/null" + // NSUnbufferedIO seems to make the app send its logs via instruments using the outputReceived:fromProcess:atTime: selector + // We'll supply per default to get logs + env := map[string]interface{}{"NSUnbufferedIO": "YES"} + return p.StartProcess(bundleID, env, []interface{}{}, opts) } -func (p *ProcessControl) Close() { - p.conn.Close() +func (p *ProcessControl) Close() error { + return p.conn.Close() } func NewProcessControl(device ios.DeviceEntry) (*ProcessControl, error) { diff --git a/main.go b/main.go index a84a1ba9..f0a983fe 100644 --- a/main.go +++ b/main.go @@ -93,7 +93,7 @@ Usage: ios install --path= [options] ios uninstall [options] ios apps [--system] [--all] [--list] [options] - ios launch [options] + ios launch [--wait] [options] ios kill ( | --pid= | --process=) [options] ios runtest [options] ios runwda [--bundleid=] [--testrunnerbundleid=] [--xctestconfig=] [--arg=]... [--env=]... [options] @@ -177,7 +177,7 @@ The commands work as following: ios install --path= [options] Specify a .app folder or an installable ipa file that will be installed. ios pcap [options] [--pid=] [--process=] Starts a pcap dump of network traffic, use --pid or --process to filter specific processes. ios apps [--system] [--all] [--list] Retrieves a list of installed applications. --system prints out preinstalled system apps. --all prints all apps, including system, user, and hidden apps. --list only prints bundle ID, bundle name and version number. - ios launch Launch app with the bundleID on the device. Get your bundle ID from the apps command. + ios launch [--wait] Launch app with the bundleID on the device. Get your bundle ID from the apps command. --wait keeps the connection open if you want logs. ios kill ( | --pid= | --process=) [options] Kill app with the specified bundleID, process id, or process name on the device. ios runtest Run a XCUITest. ios runwda [--bundleid=] [--testrunnerbundleid=] [--xctestconfig=] [--arg=]... [--env=]...[options] runs WebDriverAgents @@ -515,6 +515,7 @@ The commands work as following: b, _ = arguments.Bool("launch") if b { + wait, _ := arguments.Bool("--wait") bundleID, _ := arguments.String("") if bundleID == "" { log.Fatal("please provide a bundleID") @@ -524,8 +525,13 @@ The commands work as following: pid, err := pControl.LaunchApp(bundleID) exitIfError("launch app command failed", err) - log.WithFields(log.Fields{"pid": pid}).Info("Process launched") + if wait { + c := make(chan os.Signal, 1) + signal.Notify(c, syscall.SIGINT, syscall.SIGTERM) + <-c + log.WithFields(log.Fields{"pid": pid}).Info("stop listening to logs") + } } b, _ = arguments.Bool("kill")