package ios import ( "encoding/json" "fmt" "os" "strings" giDevice "github.com/electricbubble/gidevice" "github.com/pkg/errors" "github.com/spf13/cobra" ) func wrapError(err error, msg string) error { if strings.HasSuffix(err.Error(), "InvalidService") { msg += ", check if Developer Disk Image mounted" } return errors.Wrap(err, msg) } type DeviceList []Device type Device struct { d giDevice.Device UDID string `json:"UDID"` Status string `json:"status"` ConnectionType string `json:"connectionType"` ConnectionSpeed int `json:"connectionSpeed"` DeviceDetail *DeviceDetail `json:"deviceDetail,omitempty"` } type DeviceDetail struct { DeviceName string `json:"deviceName,omitempty"` DeviceClass string `json:"deviceClass,omitempty"` ProductVersion string `json:"productVersion,omitempty"` ProductType string `json:"productType,omitempty"` ProductName string `json:"productName,omitempty"` PasswordProtected bool `json:"passwordProtected,omitempty"` ModelNumber string `json:"modelNumber,omitempty"` SerialNumber string `json:"serialNumber,omitempty"` SIMStatus string `json:"simStatus,omitempty"` PhoneNumber string `json:"phoneNumber,omitempty"` CPUArchitecture string `json:"cpuArchitecture,omitempty"` ProtocolVersion string `json:"protocolVersion,omitempty"` RegionInfo string `json:"regionInfo,omitempty"` TimeZone string `json:"timeZone,omitempty"` UniqueDeviceID string `json:"uniqueDeviceID,omitempty"` WiFiAddress string `json:"wifiAddress,omitempty"` BuildVersion string `json:"buildVersion,omitempty"` } func (device *Device) GetDetail() (*DeviceDetail, error) { value, err := device.d.GetValue("", "") if err != nil { return nil, errors.Wrap(err, "get device detail failed") } detailByte, _ := json.Marshal(value) detail := &DeviceDetail{} json.Unmarshal(detailByte, detail) return detail, nil } func (device *Device) GetStatus() string { if device.ConnectionType != "" { return "online" } else { return "offline" } } func (device *Device) ToFormat() string { result, _ := json.MarshalIndent(device, "", "\t") return string(result) } var listIOSDevicesCmd = &cobra.Command{ Use: "devices", Short: "List all iOS devices", RunE: func(cmd *cobra.Command, args []string) error { usbmux, err := giDevice.NewUsbmux() if err != nil { return wrapError(err, "create usbmux failed") } devices, err := usbmux.Devices() if err != nil { return wrapError(err, "list ios devices failed") } var deviceList []giDevice.Device // filter by udid for _, d := range devices { if udid != "" && udid != d.Properties().SerialNumber { continue } deviceList = append(deviceList, d) } if udid != "" && len(deviceList) == 0 { fmt.Printf("no device found for udid: %s\n", udid) os.Exit(1) } for _, d := range deviceList { deviceByte, _ := json.Marshal(d.Properties()) device := &Device{ d: d, } json.Unmarshal(deviceByte, device) device.Status = device.GetStatus() if isDetail { device.DeviceDetail, err = device.GetDetail() if err != nil { return err } fmt.Println(device.ToFormat()) } else { fmt.Println(device.UDID, device.ConnectionType, device.Status) } } return nil }, } var ( udid string isDetail bool ) func init() { listIOSDevicesCmd.Flags().StringVarP(&udid, "udid", "u", "", "filter by device's udid") listIOSDevicesCmd.Flags().BoolVarP(&isDetail, "detail", "d", false, "print device's detail") iosRootCmd.AddCommand(listIOSDevicesCmd) }