iOS比優雞除錯技巧篇(一):reveal檢視除錯

weixin_34124651發表於2016-05-22

前言

深深的喜歡這篇文章《iOS各種除錯技巧》的寫作風格,讀起來就是那麼愉快,文章有內容有價值,而且作者這麼用心為大家寫,推薦大家閱讀這篇文章。寫文章就是用來讀的啊。我們開發者寫產品要有為使用者考慮的態度才能做出好產品;寫文章要有為讀者服務的態度才能讓讀者喜歡;做好工作也要有給同事給領導排憂解難的的公僕態度才對。你可能要問了,人家寫了那麼好的有關除錯的文章,你幹嘛還要寫除錯的文章,多此一舉啊?你要是有這想法啊,我就得說您幼稚了,作者我混跡江湖這麼多年,怎麼這會考慮不到呢,主要是覺得《iOS各種除錯技巧》只能算是一個除錯技巧的籠統介紹,其實裡面的每一種除錯技巧都值得深入講解,而且有些除錯技巧他的文章也沒有提到,比如這篇文章要講的reveal除錯,但我希望能借鑑他這篇文章的寫作風格,希望帶給讀者輕鬆的閱讀體驗。

作為iOS開發者為什麼需要學會使用reveal

1.相比xcode自帶的檢視除錯(下文簡稱XcodeVD),reveal強大的不是一丁點。
比如,XcodeVD會有部分資訊不顯示,還有佈局顯示不精確,而reveal則表現好很多。
XcodeVD下的表現:

1112722-5738a0354757ec14.png

reveal下的表現:

1112722-9968c41345d75e42.png
Paste_Image.png

大家可以注意看看,XcodeVD中顯示的文字被擋住了擋住了耶,這怎麼受得了,如果讀者您眼尖,相信您已經注意到reveal顯示的檢視層次結構提供的資訊更豐富,比如顯示了文字的內容(中文內容資訊),而xcode不僅僅需要您眼尖,還需要您能智慧過人聰明絕頂的去猜測一個UILabel對應模擬器上的哪個Label,蛋疼嗎?不疼只能說明您牛逼。

2.相比xcodeVD只能看看之外,reveal可以修改檢視的屬性,並實時在模擬器(真機)上顯示變化。(當然只是臨時修改的屬性,不會修改工程的實際程式碼,如果真實修改,還是需要修改的工程原始碼的)。

在reveal中修改UILabel的屬性

1112722-bce6b26fc2027310.png
Paste_Image.png

而XcodeVD幾乎什麼也幹不了,只能看看,咳。

3.reveal最強大的一點是可以通過它檢視和分析別倫家的App檢視元素構成和佈局。(牛逼波?這是reveal最有價值的部分,如果您覺得這個資訊有價值,你西不西應該打賞我一下)。
下圖是我特地為了讀者您去偷窺了下攜程這個美妞,(如果讀者您是攜程的,請您留情,不要笑我太瘋癲,我只笑他人看不穿(?))。

1112722-5284ac59643ddacc.png
Paste_Image.png

好了,您如果看到這裡,我相信您已經迫不及待想要去學會如何使用reveal,我知道您不是因為喜歡偷窺而去學的,您只是單純的愛好學習。

如何在Mac上安裝Reveal

1.作為國人我知道您不喜歡輕易付費
reveal破解和安裝:在簡書上看到這篇文章《Reveal 1.6.2最新版 破解教程》,大家照著做就好,如果您笨到搞不定(或者聰明到想利用時間專注做好開發和產品,而不是這些非核心的學習上),您可以付費諮詢我(打賞金額:¥10+)。
2.您是願意的付費的小眾?
直接去官網下載然後購買吧 http://revealapp.com/ 你要是肯花錢買,我真的為您點個贊,您是有錢的主,您順便順個手也給我打賞打賞吧,嗯。
如何在專案中整合Reveal
1.reveal官方有中文整合的教程。介紹了靜態庫、動態庫、cocoapod的安裝方法(這三種建議選這種)自行檢視吧:
http://support.revealapp.com/kb/getting-started/reveal
上面的整合方式多少需要在我們的工程專案中加入一些程式碼,可能有些同事並不想使用這玩意,所以應該在團隊中慎用。
2.下面這個方法不需要在工程中加入任何程式碼就可以使用:
http://support.revealapp.com/kb/getting-started/revealxcodereveal
3.一勞永逸的最佳整合玩法:
http://blog.ittybittyapps.com/blog/2013/11/07/integrating-reveal-without-modifying-your-xcode-project/
第三種整合的高階玩法有點複雜,如果你只想用好reveal而不想浪費時間去學如何整合,或者同樣您可能笨到沒搞定(哈哈,不是侮辱您啊,我也很笨,笨有笨的優點啊,比如學習有耐性和長性,我就研究了兩天才研究明白),同樣可以付費諮詢我:(20元打賞+)。

在自己的專案中使用Reveal

一、基本使用
本文的重點是教大家如何使用Reveal,這部分只能有請我閃亮登場(掌聲響起來),親自出馬搞了,關於Reveal的中文教程真的太少,不信你搜搜看看,基本都是一些重複且看了等於沒看的垃圾文章。像作者我這樣認認真真給老外當搬運工的人都不多見。
1.如果您安裝reveal順利,開啟reveal應該是看到大致如下圖這樣的介面:

1112722-fff63b6dbd9bebb5.png
Paste_Image.png

2.如果您搞定了整合,那你可以在模擬器(真機)上執行您專案程式,然後就可以reveal的左上角選擇該模擬器(真機)了。

1112722-fb3fd85cbaf2ef7b.png

3.重新整理介面
當您在模擬器上操作您的APP,你可能發現reveal沒有及時更新,這個它確實做不到,您可以像2提到的再選擇一次模擬,或者按下Command+R,還可以點選右上角的重新整理圖示:

1112722-e68545487f3a07b5.png

Reveal 介面和功能介紹

Reveal介面主要分為三個部分:


1112722-e9495e58ed14eb75.png

1.左側層級皮膚:介面層級關係區域,用於顯示當前介面元素的結構樹。

1112722-fee15adbfd20429e.png

如果你多檢視幾個APP,就會發現他們的根都是UIScreen,然後是UIWindow,然後還有幾個我們都不瞭解的UIKit封裝類,如:
1)UINavigationTransitionView:導航控制器在這裡發生轉場行為的容器檢視。
2)UIViewControllerWrapperView: 包含view controller 的view屬性的封裝檢視。
總之這些我們不瞭解的檢視我們(biè)管就對了。

2.中央視覺化皮膚:視覺化檢視區域, 用於顯示當前介面的佈局效果(2D/3D)

1112722-4d0d52b8bfa4f40e.gif
3d.gif

在頂部有是三個控制元件。
1)顯示樣式分段控制元件。從左至右可以讓檢視顯示三種狀態:只顯示檢視邊界frame,不顯示內容;只顯示內容不顯示邊界frame;邊界frame和內容都顯示。
2)中間的選擇器控制器可以選擇檢視尺寸大小,它的值是檢視內容和模擬器內容的大小正比值。
3)最右側的開關控制可以選擇顯示3D效果還是2D效果。預設為3D效果。

在3D模式下,點選空白區域然後上下左右拖動,檢視也跟著您的拖動方向三地旋轉和3D展示。

3.右側屬性皮膚:控制元件詳細引數區域,用於當前選中控制元件的引數展示(可以修改並 實時反應到視覺化檢視區域)

1112722-1e09af593160c4bd.png
Paste_Image.png

如圖所示,包含以下5個功能。
1)程式觀察器Application Inspector。主要顯示和程式相關的全域性屬性。
2)物件觀察器Identity Inspector。主要顯示選中物件的先關屬性,如父類資訊,自身類名資訊,記憶體地址資訊等。
3)屬性觀察器Attributes Inspector。我知道您聰明,這些都知道。可是我就是要告訴您一遍:這裡展示和選中物件相關屬性的資訊。您能拿我怎麼著(O(∩_∩)O哈哈)。
4)佈局觀察器Layout Inspector。這裡可以檢視選中物件的frame,bounds,自動佈局特性相關資訊。
5)圖層觀察器Layer Inspector

自動佈局的除錯(這部分的內容是從這裡搬運)

自動佈局(Auto Layout)已經越來越普遍的深入千家萬戶了,隨著iOS裝置解析度的多(sui)樣(pian)化,自動佈局已慢慢成為了標準配置。
你可能經常看到控制檯輸出類似這樣的內容,而不知何處下手:

Unable to simultaneously satisfy constraints.
Probably at least one of the constraints in the following list is one you don't want. Try this: (1) look at each constraint and try to figure out which you don't expect; (2) find the code that added the unwanted constraint or constraints and fix it. (Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints)
(
 "<NSLayoutConstraint:0x7fc82d3e18a0 H:[UIView:0x7fc82aba1210(768)]>",
 "<NSLayoutConstraint:0x7fc82d6369e0 H:[UIView:0x7fc82aba1210]-(0)-|   (Names: '|':UIView:0x7fc82d6b9f80 )>",
 "<NSLayoutConstraint:0x7fc82d636a30 H:|-(0)-[UIView:0x7fc82aba1210]   (Names: '|':UIView:0x7fc82d6b9f80 )>",
 "<NSLayoutConstraint:0x7fc82d3e7fd0 'UIView-Encapsulated-Layout-Width' H:[UIView:0x7fc82d6b9f80(50)]>"
 )

Will attempt to recover by breaking constraint
<NSLayoutConstraint:0x7fc82d3e18a0 H:[UIView:0x7fc82aba1210(768)]>

Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful.

除了我們在編碼時自己繫結到View上的約束條件(Constraints)之外,其實許多UIKit控制元件還會被隱式地地設定上一些約束,而這些可能會帶來一些意外的佈局結果。

也許曾經你需要使用LLDB來一點點除錯Auto Layouts:

(lldb) po 0x7731880
$0 = 124983424 <UIView: 0x7731880; frame = (90 -50; 80 100);
layer = <CALayer: 0x7731450>>

(lldb) po [0x7731880 superview]
$2 = 0x07730fe0 <UIView: 0x7730fe0; frame = (32 128; 259 604);
layer = <CALayer: 0x7731150>>

(lldb) po [[0x7731880 superview] recursiveDescription]
$3 = 0x07117ac0 <UIView: 0x7730fe0; frame = (32 128; 259 604); layer = <CALayer: 0x7731150>>
| <UIView: 0x7731880; frame = (90 -50; 80 100); layer = <CALayer: 0x7731450>>
| <UIView: 0x7731aa0; frame = (90 101; 80 100); layer = <CALayer: 0x7731c60>>

有了Reveal,這就方便多了。Reveal對檢視上的約束條件提供了相當豐富的檢視與實時修改功能,具體看下面這張圖,再自己摸索一下就好了。

1112722-f0ccef29956c1974.png

a顯示/隱藏所有約束條件
b 檢視關聯到此View的所有約束
c 可以直接在Canvas中選中某一約束
d 檢視某一約束的具體資訊,可以實時修改constant屬性,立刻檢查效果
e 跳轉到某一約束的詳細屬性頁面

給大家透露一個我摸索到的十分特別以及及其重要的知識:藍色的約束代表系統給物件新增的約束,紫色的約束是我們開發者給物件新增的約束。恩,這個在您除錯佈局衝突時很重要。不謝,打賞我就對了,我不是雷鋒,我不會武功,我不會飛簷走壁,也不會餓著肚子寫文章。

實時修改View屬性

Reveal不僅僅只是檢視各種屬性的工具,也支援實時的修改一些屬性。如下圖中的大部份屬性,你都可以實時的在模擬器中看到修改後的效果。這省去了過去總是要修改程式碼,重新編譯執行這個漫長的反饋流程。在和設計師一起嘗試各種顯示效果時,這個功能特別高效。

1112722-711df35a9c280409.png

Reveal偷窺正確姿勢

(部分內容搬運,接受鄙視,但是我是讓文章有深度需要的勤快的搬運工,和普通搬運工可以區別開來好嘛,O(∩_∩)O)(您錯過以下內容,我只能呵呵了)
溫馨提示:前方高能,越過難度有點大,如果遇到頭暈腦脹、眼神絕望,請儘快逃離現場。如果您依然十分想要偷窺,又不想費時費力,最好的解決辦法依然是打賞我拉,小的帶您坐纜車,飛速直達目的地。(打賞¥50+)。
1.越獄你的iOS裝置:可以利用盤古、PP助手、太極等三方工具一鍵越獄。這部分內容請自行搜尋。
2.iOS裝置越獄完成後,需要使用Cydia
安裝兩個軟體:**OpenSSH
CydiaSubstrate
**
安裝OpenSSH,開啟越獄後的裝置上的Cydia程式,點選搜尋輸入OpenSSH,然後點選安裝。(下面的配圖是已經安裝成功後搜尋的顯示畫面)

SSH是一種可以保證使用者加密遠端登入到系統的協議,OpenSSH是一個SSH的連線傳輸工具。

安裝Cydia Substrate,開啟越獄後的裝置上的Cydia程式,點選搜尋輸入Cydia Substrate,然後點選安裝。只有安裝了CydiaSubstrate之後才會有MobileSubstrate目錄(此目錄必須存在才可以繼續下面的步驟)。(下面的配圖是已經安裝成功後搜尋的顯示畫面)

MobileSubstrate是一個公共庫,可以用來動態替換記憶體中的程式碼、數 據等。基本上越獄機下比較有用的系統工具都需要這個庫,是Cydia同一個作者 維護的,可以放心裝。

3.將libReveal.dylib上傳到越獄後的裝置的
/Library/MobileSubstrate/DynamicLibraries下檢查工作:測試OpenSSH和CydiaSubstrate是否安裝成功

1)上傳libReveal.dylib檔案必須使用到上面安裝的OpenSSH工具。如果想要使用OpenSSH工具,那麼就必須將Reveal軟體所在的mac裝置與越獄後的iOS裝置置於同一個區域網內
2)首先來測試OpenSSH是否安裝成功。獲取越獄後的裝置的區域網內的IP地址,開啟“設定”->“WLAN”,連上區域網,然後再點選連線上的區域網檢視iOS裝置的IP地址。

3)開啟mac上的終端工具(Terminal),輸入如下命令:ssh root@iOS裝置IP地址。輸入完成後回車,等待連線iOS裝置。


iOS裝置的IP地址指的是越獄後的裝置(iphone、ipad)的IP地址,也就是上個步驟中獲取的IP地址,後面的教程中出現的地址僅僅是代表筆者測試時iOS裝置的IP地址(192.168.2.2),讀者請一定要檢視自己的iOS裝置地址,並進行替換。

4)接下來會提示你輸入root使用者的密碼,iOS裝置root使用者的預設密碼是alpine,在終端中輸入密碼時,終端不會顯示你輸入的字元,所以只需要輸入alpine字元後回車就可以請求連線iOS裝置了。(這一步請保證你的iOS裝置螢幕已經解鎖,不然不會出現輸入密碼的提示!


》如果出現~ root#字元就表示連線成功了。

接下來測試Cydia Substrate 是否安裝成功,上一步已經連線上iOS裝置的終端中輸入以下命令:cd /Library/MobleSubstrate/DinamicLibraries
,回車檢視返回結果。如果出現-sh: cd: /Library/MobileSubstrate/DynamicLibraries: No such file or directory
提示那就說明Cydia Substrate安裝不成功,不成功請重新進入iOS裝置上下載安裝Cydia Substrate軟體。
若果沒出現如何錯誤提示資訊,就說明Cydia Substrate安裝成功!

4.上傳libReveal.dylib。如果上一個步驟的檢查工作全部完成:OpenSSH和Cydia Substrate成功安裝。
重新開啟mac上的終端工具(Terminal),使用如下命令進入Reveal軟體的動態庫所在目錄:cd /Applications/Reveal.app/Contents/SharedSupport/iOS-Libraries


使用如下命令將libReveal.dylib上傳到iOS裝置的/Library/MobileSubstrate/DynamicLibraries目錄下:scp libReveal.dylib root@iOS裝置IP地址:/Library/MobileSubstrate/DynamicLibraries/
,請替換@之後的“iOS裝置的IP地址”為你的iOS裝置的真實地址,回車執行命令後會讓你輸入iOS裝置的root的密碼,預設是alpine,上傳成功後會顯示%100字樣。

5.編寫並上傳一份libReveal.plist
到iOS裝置的/Library/MobileSubstrate/DynamicLibraries
目錄中。這個檔案的作用是:在Reveal中監控指定的App,不上傳這個檔案也是可以的,那麼Reveal就會監控所有的App,只是這樣速度會慢一點點。編寫libReveal.plist檔案,最簡單的方法就是新建一個plist檔案,它的內容是
{ Filter = { Bundles = ( "你要檢視的app的bundle Id1","你要檢視的app的bundle Id2" ); }; }

xcode下開啟這個libReveal.plist檔案可以看到它的結構示例(筆者已經新增了兩個Bundle ID):

關於獲取iOS App應用的Bundle ID:開啟PP助手、iTools、itunes等工具,備份手機上安裝到的程式到電腦上(或直接下載需要檢視程式ipa檔案),將.ipa修改成.zip,解壓後按如下路徑進入info.plist檔案所在目錄,開啟info.plist其中便有我們需要的bundle Id。

6.上傳libReveal.plist
到iOS裝置的/Library/MobileSubstrate/DynamicLibraries
目錄中。開啟終端進入libReveal.plist所在的目錄,使用如下命令上傳:scp libReveal.plist root@iOS裝置的IP地址:/Library/MobileSubstrate/DynamicLibraries/
,請替換@之後的“iOS裝置的IP地址”為你的iOS裝置的真實地址,回車執行命令後會讓你輸入iOS裝置的root的密碼,預設是alpine,上傳成功後會顯示%100字樣。

7.接下來在重啟你的iOS裝置,連上mac電腦所在的區域網,上開啟你需要在Reveal中觀察的程式,此時在mac電腦上的Reveal中選擇你要觀察的程式。


提示:如果此時在mac上的Reveal左上方沒有出現你想要除錯的程式,這裡給出幾個檢查的建議:

  • 1.手機連線的wifi是否與mac處於同一區域網(如果你在執行步驟7時是在正確執行步驟5和6之後,那就忽略這個檢查,這裡是針對手機重啟了或者是切換了手機網路等情況)。
  • 2.檢視你編寫的libReveal.plist檔案中寫的BundleID是否與你在iOS裝置上開啟的應用是否匹配。甚至,請檢查你的pist檔案結構是否正確!
  • 3.iOS裝置上想要觀察的App應用必須處於前臺,進入後臺即使開啟了,在Reveal的左上角“選擇連線的應用”框中也不會顯示。

補充
歡迎收藏的 我的部落格

相關文章