iOS 测试 Golang 版 libimobiledevice

雷系泡泡 · April 14, 2021 · Last by 少女 replied at April 19, 2021 · 2627 hits

⭐ 「抄作业系列 - 2」⭐

交作业了 electricbubble/gidevice

Pythontidevice 翻译成了 Golang

基本上功能都已经实现啦

  • 设备基础信息查询
  • 设备配对
  • 开发者镜像挂载
  • 获取截图
  • 定位修改
  • 启动 App
  • XCTest

这个版本是纯 Go Module,不含 tideviceCLI 部分
CLI 的版本也有计划做,但可能会晚些。。🤖

后面要先补充一下这过于简陋的 README。。。


加几个例子

Devices 查看设备列表

package main

import (
    giDevice "github.com/electricbubble/gidevice"
    "log"
)

func main() {
    usbmux, err := giDevice.NewUsbmux()
    if err != nil {
        log.Fatalln(err)
    }

    devices, err := usbmux.Devices()
    if err != nil {
        log.Fatal(err)
    }

    for _, dev := range devices {
        log.Println(dev.Properties().SerialNumber, dev.Properties().ProductID, dev.Properties().DeviceID)
    }
}

DeveloperDiskImage 开发者镜像

package main

import (
    "encoding/base64"
    giDevice "github.com/electricbubble/gidevice"
    "log"
)

func main() {
    usbmux, err := giDevice.NewUsbmux()
    if err != nil {
        log.Fatal(err)
    }

    devices, err := usbmux.Devices()
    if err != nil {
        log.Fatal(err)
    }

    if len(devices) == 0 {
        log.Fatal("No Device")
    }

    d := devices[0]

    imageSignatures, err := d.Images()
    if err != nil {
        log.Fatalln(err)
    }

    for i, imgSign := range imageSignatures {
        log.Printf("[%d] %s\n", i+1, base64.StdEncoding.EncodeToString(imgSign))
    }

    dmgPath := "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/DeviceSupport/14.4/DeveloperDiskImage.dmg"
    signaturePath := "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/DeviceSupport/14.4/DeveloperDiskImage.dmg.signature"

    err = d.MountDeveloperDiskImage(dmgPath, signaturePath)
    if err != nil {
        log.Fatalln(err)
    }
}

App 启/停 App

package main

import (
    giDevice "github.com/electricbubble/gidevice"
    "log"
    "path/filepath"
)

func main() {
    usbmux, err := giDevice.NewUsbmux()
    if err != nil {
        log.Fatalln(err)
    }

    devices, err := usbmux.Devices()
    if err != nil {
        log.Fatalln(err)
    }

    if len(devices) == 0 {
        log.Fatalln("No Device")
    }

    d := devices[0]

    bundleID := "com.apple.Preferences"
    pid, err := d.AppLaunch(bundleID)
    if err != nil {
        log.Fatalln(err)
    }

    err = d.AppKill(pid)
    if err != nil {
        log.Fatalln(err)
    }

    runningProcesses, err := d.AppRunningProcesses()
    if err != nil {
        log.Fatalln(err)
    }

    for _, process := range runningProcesses {
        if process.IsApplication {
            log.Printf("%4d\t%-24s\t%-36s\t%s\n", process.Pid, process.Name, filepath.Base(process.RealAppName), process.StartDate)
        }
    }
}

Screenshot 获取截图

package main

import (
    giDevice "github.com/electricbubble/gidevice"
    "image"
    "image/jpeg"
    "image/png"
    "log"
    "os"
)

func main() {
    usbmux, err := giDevice.NewUsbmux()
    if err != nil {
        log.Fatalln(err)
    }

    devices, err := usbmux.Devices()
    if err != nil {
        log.Fatalln(err)
    }

    if len(devices) == 0 {
        log.Fatalln("No Device")
    }

    d := devices[0]

    raw, err := d.Screenshot()
    if err != nil {
        log.Fatalln(err)
    }

    img, format, err := image.Decode(raw)
    if err != nil {
        log.Fatalln(err)
    }
    userHomeDir, _ := os.UserHomeDir()
    file, err := os.Create(userHomeDir + "/Desktop/s1." + format)
    if err != nil {
        log.Fatalln(err)
    }
    defer func() { _ = file.Close() }()
    switch format {
    case "png":
        err = png.Encode(file, img)
    case "jpeg":
        err = jpeg.Encode(file, img, nil)
    }
    if err != nil {
        log.Fatalln(err)
    }
    log.Println(file.Name())
}

SimulateLocation 定位修改/还原

package main

import (
    giDevice "github.com/electricbubble/gidevice"
    "log"
)

func main() {
    usbmux, err := giDevice.NewUsbmux()
    if err != nil {
        log.Fatalln(err)
    }

    devices, err := usbmux.Devices()
    if err != nil {
        log.Fatalln(err)
    }

    if len(devices) == 0 {
        log.Fatalln("No Device")
    }

    d := devices[0]

    // https://api.map.baidu.com/lbsapi/getpoint/index.html
    if err = d.SimulateLocationUpdate(116.024067, 40.362639, giDevice.CoordinateSystemBD09); err != nil {
        log.Fatalln(err)
    }

    // https://developer.amap.com/tools/picker
    // https://lbs.qq.com/tool/getpoint/index.html
    // if err = d.SimulateLocationUpdate(120.116979, 30.252876, giDevice.CoordinateSystemGCJ02); err != nil {
    //  log.Fatalln(err)
    // }

    // if err = d.SimulateLocationUpdate(121.499763, 31.239580,giDevice.CoordinateSystemWGS84); err != nil {
    // if err = d.SimulateLocationUpdate(121.499763, 31.239580); err != nil {
    //  log.Fatalln(err)
    // }

    // err = d.SimulateLocationRecover()
    // if err != nil {
    //  log.Fatalln(err)
    // }
}

XCTest 启动 WDA

package main

import (
    "fmt"
    giDevice "github.com/electricbubble/gidevice"
    "log"
    "os"
    "os/signal"
)

func main() {
    usbmux, err := giDevice.NewUsbmux()
    if err != nil {
        log.Fatal(err)
    }

    devices, err := usbmux.Devices()
    if err != nil {
        log.Fatal(err)
    }

    if len(devices) == 0 {
        log.Fatal("No Device")
    }

    d := devices[0]

    out, cancel, err := d.XCTest("com.leixipaopao.WebDriverAgentRunner.xctrunner")
    if err != nil {
        log.Fatal(err)
    }

    done := make(chan os.Signal, 1)
    signal.Notify(done, os.Interrupt)

    go func() {
        for s := range out {
            fmt.Print(s)
        }
    }()

    <-done
    cancel()
    fmt.Println()
    log.Println("DONE")
}

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
共收到 6 条回复 时间 点赞

大佬 有 JVM 版的嘛

恒温 回复

看了。可好了。

陈子昂 回复

😂 还是有几个 TODO 没完成...
不过完全不影响现有的全部功能

Yu 回复

Java 版本?

😨 没计划....

目前只打算用 Golang 造点小轮子....

Java 版本期待哪位大神翻译一下😁

需要 Sign In 后方可回复, 如果你还没有账号请点击这里 Sign Up