Xcode 10 使用的心塞之路
說心塞之路,一點也不為過,這兩天體會到了類似服務端開發的壓力。以下為事件的始末。
自從蘋果 9 月釋出會之後,Xcode 10 陸續開始了推送,為了一瞻蘋果暗黑模式,我在 十一 期間也更新了最新系統,安裝了Xcode 10,而且使用沒有明顯的bug,暗黑模式也是挺裝逼的。
十一 之後,開始了我們 app 3.5.7 版本的提交稽核,準確來說是 10.9 。但是直到兩週也沒有稽核,一直維持著正在等待稽核的狀態。期間,我們又進行了新功能的研發,想著反正還是要釋出一個版本,索性 3.5.7 就不再管了。
當 10.23 提交了 3.5.8 之後,第二天就稽核通過了,頓時覺得很開心。接下來使用者也沒有反饋出什麼問題。由於 app 在 AppStore 更新資料不及時,可能有些人還沒有安裝最新版。但是,晚上已經陸續有人開始反應會有閃退了,而且系統主要集中在 iOS 9。當時覺得可能是某個地方不相容,所以就花費了2個小時下載了 iOS 9 的模擬器執行測試,也不會出現問題。接下來會有偶爾的使用者反饋 iOS 11 、iOS 12 也會崩潰。關鍵這些閃退,大部分是 app 啟動就閃退。在下載模擬器的同時我還查看了友盟、itunes 上的崩潰日誌,發現沒有關於這種的日誌。然後就沒轍了,只能等到明天繼續打這場硬仗了。
第二天,也就是 10.25 ,一大早就收到好多客服反饋說好多人閃退(其實最後拉到一個群組裡面也就 28 個人左右),大部分還是啟動就閃退,很少使用者是點選個人中心清除快取閃退。由於系統版本的分散,所以也不是系統相容的問題,檢視友盟、itunes 仍然沒有相應的崩潰日誌。
10.25 中午,在群裡看到有個使用者還在說問題,這個時候,突然想到 讓使用者新增我,獲取他們裝置上的崩潰日誌,進行分析檢視。這個過程大概持續了三個小時,獲取到了他們裝置的資訊,通過命令列解析了崩潰日誌如下:
Exception Type: EXC_BAD_ACCESS (SIGSEGV) Exception Subtype: KERN_INVALID_ADDRESS at 0x000000010004cad0 Triggered by Thread: 0 Filtered syslog: None found Global Trace Buffer (reverse chronological seconds): 6148914687.014364 CFNetwork 0x0000000182e69928 TCP Conn 0x15fa75d50 starting SSL negotiation 6148914687.014932 CFNetwork 0x0000000182f0ba30 TCP Conn 0x15fa75d50 complete. fd: 9, err: 0 6148914687.016414 CFNetwork 0x0000000182f0cf5c TCP Conn 0x15fa75d50 event 1. err: 0 6148914687.075758 CFNetwork 0x0000000182f0d034 TCP Conn 0x15fa75d50 started 6148914689.682108 CFNetwork 0x0000000182e69a18 TCP Conn 0x15e7a27e0 SSL Handshake DONE 6148914689.687297 CFNetwork 0x0000000182f0ba30 TCP Conn 0x15f897720 complete. fd: 9, err: 0 6148914689.687758 CFNetwork 0x0000000182f0cf5c TCP Conn 0x15f897720 event 1. err: 0 6148914689.716092 CFNetwork 0x0000000182f0d034 TCP Conn 0x15f897720 started 6148914689.728427 CFNetwork 0x0000000182f0ba30 TCP Conn 0x15fa62e00 complete. fd: 21, err: 0 6148914689.728559 CFNetwork 0x0000000182f0cf5c TCP Conn 0x15fa62e00 event 1. err: 0 6148914689.741988 CFNetwork 0x0000000182e69a18 TCP Conn 0x15e7bc4b0 SSL Handshake DONE 6148914689.745552 CFNetwork 0x0000000182f0ba30 TCP Conn 0x15f897720 complete. fd: 35, err: 0 6148914689.745862 CFNetwork 0x0000000182f0cf5c TCP Conn 0x15f897720 event 1. err: 0 6148914689.749554 CFNetwork 0x0000000182f0ba30 TCP Conn 0x15e7d66e0 complete. fd: 34, err: 0 6148914689.749744 CFNetwork 0x0000000182f0cf5c TCP Conn 0x15e7d66e0 event 1. err: 0 6148914689.751110 CFNetwork 0x0000000182f0ba30 TCP Conn 0x15f8b60b0 complete. fd: 15, err: 0 6148914689.751278 CFNetwork 0x0000000182f0cf5c TCP Conn 0x15f8b60b0 event 1. err: 0 6148914689.754748 CFNetwork 0x0000000182f0d034 TCP Conn 0x15fa62e00 started 6148914689.773936 CFNetwork 0x0000000182f0d034 TCP Conn 0x15f897720 started 6148914689.773936 CFNetwork 0x0000000182f0d034 TCP Conn 0x15f8b60b0 started 6148914689.783995 CFNetwork 0x0000000182e69a18 TCP Conn 0x15f942ef0 SSL Handshake DONE 6148914689.786436 CFNetwork 0x0000000182e69928 TCP Conn 0x15e7a27e0 starting SSL negotiation 6148914689.786681 CFNetwork 0x0000000182f0ba30 TCP Conn 0x15e7a27e0 complete. fd: 13, err: 0 6148914689.786936 CFNetwork 0x0000000182f0cf5c TCP Conn 0x15e7a27e0 event 1. err: 0 6148914689.794683 CFNetwork 0x0000000182e69a18 TCP Conn 0x15fa41c60 SSL Handshake DONE 6148914689.805450 CFNetwork 0x0000000182f0ba30 TCP Conn 0x15fa265b0 complete. fd: 39, err: 0 6148914689.805680 CFNetwork 0x0000000182f0cf5c TCP Conn 0x15fa265b0 event 1. err: 0 6148914689.805878 CFNetwork 0x0000000182f0ba30 TCP Conn 0x15fa53ec0 complete. fd: 21, err: 0 6148914689.807784 CFNetwork 0x0000000182f0cf5c TCP Conn 0x15fa53ec0 event 1. err: 0
但是,主執行緒的日誌不規律,有的是啟動初始化 tab 報錯,有的是重新整理控制元件報錯,有的是個人中心報錯。但是前面部分的錯誤都是這樣的:
Exception Type: EXC_BAD_ACCESS (SIGSEGV)
Exception Subtype: KERN_INVALID_ADDRESS at 0x000000010004cad0
Triggered by Thread: 0
這樣子也解決不了問題呀。
剛好有使用者新增我好友,我便在 AppDelegate 中添加了捕獲異常的程式碼,並將異常資訊通過開啟郵箱傳送給我,以便排查問題。當我將包通過蒲公英發送給他的時候,沒有任何問題,也不會開啟郵件 app 。這個情況讓我很費解,隨即把捕獲異常的程式碼去掉,重新打包給他,還是沒有問題。然後立馬想到了可能是打包方式的問題。因為上傳 AppStore 使用的是 fastlane 打包的。之後把測試包全部下發給加我的三個使用者,全部正常了,然後讓客服找了幾個人測試了一下也是正常的。所以就斷定了是打包方式的問題。接下來,就是使用 Xcode 10 打包上傳,並申請加急,期待稽核成功。
上傳之後,差不多也到了下班時間了,但是,為了確定到底問題出在了哪裡,我就把 AppStore 線上包下載下來,重簽名發給使用者安裝,測試也是沒有問題的。所以我就確定了是上傳包後蘋果簽名的問題。也就是打包工具不一樣導致的。剩下的只有等著明天稽核通過,app 正常使用了。
其實,在回家的路上,自己心裡還是很虛的,如果真的是我上傳包工具不一樣,那所有使用 fastlane 的開發者不都會出現這個問題嗎?但是,這個就是唯一的答案,只能自己相信自己了。
10.26 一早,app 稽核通過了,還沒有發到市場上。我就先查看了一下 fastlane 使用什麼命令上傳包的,官方文件上說也是使用的官方工具 iTMSTransporter ,而且不論Organizer還是App Loader,都是通過iTMSTransporter來上傳檔案的。看到這裡,我心裡就虛了,也就是說上傳過程不會有問題,真有問題,就是上傳之後蘋果簽名的問題,如果簽名有問題,所有 app 都會出現這個問題。這顯然是不現實。接著,由於客服又開始催我上架 app ,就只能硬著頭皮上架了。果然,閃退的使用者更新完 app 還是閃退,而且有的使用者安裝後不閃退,但是 app 搜尋彈出的鍵盤好多字母重合一塊,而其他 app 彈出的鍵盤顯示正常。怎麼辦呢?徹底沒轍了。但是,辦法總是想出來的。我又使用最新的專案打出一個測試包,讓使用者安裝測試,還是沒有任何問題。所以,結論就是渠道包的問題,打出的 AppStore 渠道的包就會有問題,而打出的 Adhoc 渠道包不會有問題。那又怎麼樣呢?把這個情況跟技術總監說了一下,技術總監說是不是專案中渠道配置問題,但是通常不會有這種配置問題,只有 Release Debug 之分。然後,想到前幾天自己手動修改了一些配置,git 合併的時候也修改了一些配置,不確定是否有影響,只能通過 git 檢視日誌了。可是,git 裡面有兩個版本,到底是從 3.5.7 還是 3.5.8 開始的呢,又是一個問題?這麼大的工作量也是不好找呀,無奈,只能中午吃飯去了。
吃完飯之後,想了一下,為了找到從哪個版本出現的問題,只能通過 TestFlight 安裝測試了。所以繼續找使用者通過 TestFlight 安裝測試,這時,發現 TestFlight 新添加了一個生成共有連結的功能。不需要 AppleId 即可安裝,所以就通過這種方式給使用者生成一個 3.5.6 先臨時使用。接著,找到加我的使用者,詢問郵箱,邀請、截圖、點選、一步步操作,中間過程非常複雜,還是沒有成功。沒辦法,只能兵行險招,給他們開通許可權,這樣就可以測試之前多個版本了。找到一個使用者,給了許可權,安裝各個版本測試一下,發現從 3.5.7 版本就崩潰了。找到了問題,就只能去 git 翻看日誌了。同時回想了一下,發現從 3.5.7 開始使用的 Xcode 10 釋出的應用,所以,可能也跟 Xcode 版本有關。在找 log 的同時,重新下載 Xcode 9.4.1,同時詢問以前公司的 iOS 開發目前使用的 Xcode 版本也是 10。心中又有了疑惑,難道是我 Xcode 壞了。沒關係,不是有使用者可以測試嘛。我重新打出包讓以前同事上傳上去了。同時,我查到一個日誌,關於 release 下簽名的配置改動,重新恢復成原來的,繼續打包上傳了。而此時,我的 Xcode 9.4.1 也下載好了,開啟專案進行編譯打包,同時聯絡使用者幫我測試,發現這個使用者暫時沒有時間,只能找另一個使用者重新新增許可權測試了。他首先測試了前兩個包,還是會出現閃退,接著測試第三個包,就一切正常了。哎喲,終於找到了問題了,還真的是 Xcode 版本的問題。當然,這次為了求穩,還是期待多個人同時測試的。目前來說,只能等第一個給許可權的使用者了。5 點左右的時候,這個人有時間了,並測試一波也是好了。現在穩了,可以提交版本了。
提交了新版本 3.6.0 ,並加急後,我決定明天即使通過(因為明天就是週六),也不上架,先通過 TestFlight 讓使用者測試,真的沒有問題,再進行上架(說實話,自己真蠢,為什麼之前沒有想到呢)。
10.27 ,3.6.0 成功稽核通過,過了一會,TestFlight 也可以測試這個版本了,就分發給使用者進行了測試,這次真的是穩了,沒有什麼問題。參與測試的使用者達到了 107 個,但是為了求穩,還是想讓沒閃退的使用者參與測試一下,奈何無人測試呀。
以上就是整個查詢 bug 的過程,真的是心酸。雖然歷時比較久,我不覺得有哪裡耽誤了時間。當然,如果有個這樣的手機在身邊,估計 2 個小時就搞定。
雖然說這個 bug 的解決過程沒有可優化處,但是其他方面還是有待提高。比如找到了問題解決之後,如果要發包,可以去看看崩潰日誌,順道把已有的 bug 一起解決掉。
ps: 在使用者測試 3.6.0 版本的時候,聽到產品經理說同行多個 app 最近也是頻繁更新,估計也是這個問題。
當然,還是會有總結的:
- 使用者的時間不是固定的,自己的時間是固定的,所以,不要把雞蛋放到同一個籃子裡,多找幾個使用者並行進行。
- 方向很重要,先找問題的方向,然後再去具體找。假設當時直接去看日誌,那不是翻死了,最後還是找不到問題,所以,通過使用者測試找到從 3.5.7 開始的崩潰,進而聯想到 Xcode 的問題。
- 多考慮後續操作。因為最終還是要確定 App Store 包在使用者手機上執行正常,所以必須要通過 TestFlight,所以在引導使用者使用 TestFlight 的操作不是浪費時間,而是必要時間損耗。而且,通過 TestFlight 找到了整個方向。
- 逆向思考。從崩潰日誌解決不了問題,從結果來看,排除所有的不可能,剩下的唯一一個就是可能。
- 平時多積累,日後必有用。如果不是之前使用過 TestFlight,也不會想到這個測試工具。同樣,如果知道 fastlane 使用的上傳包工具也是系統的,就不會再多浪費一個版本的釋出。
到此,基本確定了就是 Xcode 10 上傳 App Store 渠道包的問題了。