什么是sonic-ios-bridge
sonic-ios-bridge(以下簡稱sib),用于pc與ios通信的工具,當前版本包含以下基礎功能
1、跨平臺啟動wda
2、app列表、安裝、卸載、啟動
3、設備上下線監(jiān)聽
4、設備詳細信息
5、自動掛載開發(fā)者鏡像
Github地址
使用文檔
只要你的ios有wda包,可以使用sib喚起之后,用appium等框架直接連接對應url,就能實現(xiàn)跨平臺(Linux、Win、Mac)自動化,可以不依賴mac和xcode(當然打wda到ios的時候需要xcode,后續(xù)跑自動化就不需要了)
Sonic為什么考慮替換tidevice
tidevice是一個非常優(yōu)秀的工具,但是這邊如果單因為tidevice讓用戶部署python環(huán)境無疑是巨大的浪費,以往不少用戶部署Agent的時候都是在python環(huán)境踩了坑。而go語言打包的可執(zhí)行二進制文件可以不需要部署額外的環(huán)境運行,并且go語言天生的性能與速度都是非常優(yōu)的。
引用網(wǎng)上一篇文章的話
Go 語言的特點表明它具備輕量級線程實現(xiàn)(Goroutine)、智能標準庫、強大的內(nèi)置安全性,且可使用最簡語法進行編程。
所以,如果你自己是Sonic平臺層面的用戶,那么這個新技術帶來的效果也許是不痛不癢,最明顯收益是部署時不需要py環(huán)境。
如果你是python語言為主做iOS自動化,那么還是推薦繼續(xù)使用tidevice
如果你是java或其他語言為主做iOS自動化,那么可以考慮使用sib,不要搭建py環(huán)境啦~
嘗試自己造輪子
當時查找了大量usbmuxd、lockdown的文章,也有參考了tidevice的代碼。用自己的方式實現(xiàn)了跨平臺與usbmuxd的通信與iOS的lockdown通信,做出了
- 獲取設備詳情
- 監(jiān)聽設備上下線
- 設備端口轉發(fā),類似iproxy
進展還是挺順利,接下來搞啟動wda
發(fā)現(xiàn)寶藏
后面著手進行啟動wda這最難的功能的時候,testmanager等等一系列惡心人的邏輯讓我痛不欲生,啟動wda幾乎圍繞了整個iOS協(xié)議走了一圈,偶爾逛github的時候發(fā)現(xiàn)原來有小伙伴用go實現(xiàn)過ios通信了,叫gidevice,也有伴生了cli版。但是因為沒有自動掛載開發(fā)者鏡像的功能,還不能直接接到sonic里面,加上某些數(shù)據(jù)基礎還是要結合sonic業(yè)務來展開。
于是放棄之前自己做的輪子,直接基于gidevice的基礎上,來做一層sonic的cli與輔助擴展
擴展功能如下幾點:
1. 獲取設備型號的中文名稱,如iPhone14,5 -> iPhone 13
整理的映射表
主要從apple的wiki爬取下來的
2. 自定義輸出json數(shù)據(jù)格式與格式化格式
這個主要用來結合sonic業(yè)務做的
3. 自動掛載開發(fā)者鏡像
這里參考了tidevice的做法,在倉庫下載對應版本號的開發(fā)者鏡像并進行掛載操作
func downloadZip(url, version string) error {
if versionMap[version] != "" {
version = versionMap[version]
}
_, errT := os.Stat(fmt.Sprintf(".sib/%s.zip", version))
if errT != nil {
_, err := os.Stat(".sib")
if err != nil {
os.MkdirAll(".sib", os.ModePerm)
}
client := http.Client{
Timeout: DownLoadTimeOut,
}
res, err := client.Get(fmt.Sprintf("%s/iOSDeviceSupport/raw/master/DeviceSupport/%s.zip", url, version))
if err != nil {
return err
}
defer res.Body.Close()
r := bufio.NewReaderSize(res.Body, 32*1024)
newFile, err := os.Create(fmt.Sprintf(".sib/%s.zip", version))
w := bufio.NewWriter(newFile)
io.Copy(w, r)
abs, _ := filepath.Abs(newFile.Name())
errZip := unzip(abs, ".sib", version)
if errZip != nil {
os.Remove(newFile.Name())
return errZip
}
}
return nil
}
4. 設備離線后填充對應序列號到對應字段
離線后只能拿到deviceID,這個id是連接時候通過自增定義的,并不是設備的序列號,需要自己做處理
5. 監(jiān)聽時展示設備詳細信息
這個屬于擴展功能,搭配sonic業(yè)務使用
6. 獲取app信息,包括中文名與長版本號
本來gidevice提供的applist只有app的英文名稱和短版本號,需要用gidevice另一個InstallationProxyBrowse的方法做,并且篩選用戶的應用
if device.Properties().SerialNumber != "" {
result, errList := device.InstallationProxyBrowse(giDevice.WithApplicationType(giDevice.ApplicationTypeUser))
if errList != nil {
return util.NewErrorPrint(util.ErrSendCommand, "appList", errList)
}
var appList entity.AppList
for _, app := range result {
a := entity.Application{}
mapstructure.Decode(app, &a)
appList.ApplicationList = append(appList.ApplicationList, a)
}
data := util.ResultData(appList)
fmt.Println(util.Format(data, isFormat, isJson))
} else {
fmt.Println("device no found")
os.Exit(0)
}
如何使用
- Sonic平臺用戶可以不用關心,使用起來跟以往無異,Agent層會自動調(diào)用sib,并解決了以往版本我還沒修復的很多bug,理論上更穩(wěn)定。
- 非直接使用平臺的用戶可以前往這里下載對應版本文件
sib run wda -b 你的wda包名
執(zhí)行之后可以瀏覽器打開localhost:9100,有手機畫面代表成功
包名如果沒有.xctrunner會自動補全.xctrunner,默認使用第一臺手機,如果想指定手機,可以
sib run wda -u 序列號 -b 你的wda包名
如果想更改端口號,可以
sib run wda -h 來查看對應參數(shù)
獲取序列號可以通過
sib devices
更多用法可以通過sib -h或者github的文檔查看哦~
結語
這里還是非常感謝gidevice作者雷系泡泡,給我省去了不少造輪子的時間。
sib也將在v1.3.2-beta開始接入sonic,希望大家多多期待