iOS開發筆記 - 界面調試神器Reveal

http://blog.csdn.net/jackfrued/article/details/50934092ios

 
 

Reveal是iOS開發工具中的神器之一,它可以在應用程序運行過程當中調試應用程序界面。 經過Reveal咱們能夠鏈接到應用程序,並容許開發者編輯各類用戶界面參數,結果會立刻在用戶界面上呈現。就像Web開發人員用瀏覽器提供的開發人員工具調試頁面同樣,Reveal容許開發者在不修改代碼、不從新構建項目、不從新部署應用程序的狀況下就可以調試iOS應用的用戶界面。objective-c

安裝Reveal

Reveal 下載地址:http://revealapp.com/download/swift

集成指南

集成Reveal無需添加任何代碼,無需引入任何頭文件。庫將會在應用啓動時自動加載,並在您的應用內部啓動必要的Reveal服務。windows

三種集成方式

靜態鏈接

將Reveal的靜態庫文件鏈接入應用,是最簡單快捷地啓用Reveal檢視的方式。xcode

警告: 不要將Reveal庫文件隨着正式應用一塊兒發佈。 下面的步驟將會展現如何經過構建配置,而把Reveal靜態庫文件,僅鏈接到調試構建的流程中。瀏覽器

  1. 在Xcode中打開您的iOS工程。ruby

  2. 啓動Reveal並選擇Help → Show Reveal Library in Finder,這將會打開Finder窗口,並顯示一個名爲iOS-Libraries的文件夾。bash

  3. 將 Reveal.framework 文件拖入Xcode中的Project Navigator面板。markdown

  4. 在下圖所顯示的Add to targets對話框中,選擇全部您但願與Reveal集成的target。可選步驟:選中Copy items if needed,將會把 Reveal.framework 拷貝到工程中——若是您這麼作了, 請記住,當更新Reveal至新版本時,也依照上述步驟再次更新此庫文件。網絡

  5. 點擊Finish。

  6. 選擇Build Settings標籤,在Other Linker Flags的Debug配置項中加入以下配置。

    -ObjC -lz -framework Reveal
  7. 若是您使用的是Xcode 7, 請確認 Reveal.framework 所在的目錄在您的工程配置項 「Framework Search Paths」 中。具體的內容看起來會像這樣。

    FRAMEWORK_SEARCH_PATHS = $(inherited) "$(SYSTEM_APPS_DIR)/Reveal.app/Contents/SharedSupport/iOS-Libraries"
  8. 在Xcode中,構建並運行您的應用。若是應用運行於真實設備之上,請確保此設備與正在運行Reveal的Mac機器,處於同一Wi-Fi網絡中。

    若是一切正常運行,請切換到Reveal應用,此時您的應用應會出如今應用選擇器的下拉列表當中。選中您的應用,確承認以看到此時正在模擬器(或設備)中運行的應用界面截圖。

動態加載

動態加載容許iOS應用在運行時,能夠按需地加載第三方庫。採用這種方式,庫文件無需鏈接入應用的可執行文件,而是被加入到了應用Bundle中去,從而在運行時能按需加載。這種方式使得開發者能夠在我的應用中,徹底自由地控制Reveal庫的加載,以及其服務的啓動與中止。

將Reveal加入您的Xcode工程,使得您團隊中的其餘成員無需任何額外的配置,就可使用Reveal。

警告: 永遠不要將包含Reveal動態庫文件的應用正式發佈。Apple不容許將含有動態加載庫文件的iOS應用發佈到Apple商店中。

    1. 在Xcode中打開您的iOS工程。

    2. 啓動Reveal並選擇Help → Show Reveal Library in Finder,這將會打開Finder窗口,並顯示一個名爲iOS-Libraries的文件夾。

    3. 將 libReveal.dylib 文件拖入Xcode中的Project Navigator面板。

    4. 在下圖所顯示的Add to targets對話框中,反選全部的target。這確保了Xcode不會在編譯時鏈接動態庫文件。可選步驟:選中Copy items if needed,將會把 libReveal.dylib 拷貝到工程中——若是您這麼作了, 請記住,當更新Reveal至新版本時,也依照上述步驟再次更新此庫文件。

    5. 點擊Finish。

    6. Copy Bundle Resources配置區域中,加入libReveal.dylib

    7. Link Binary With Libraries配置項中:

      • ​若是已有libReveal.dylib,請將其移除——不該在編譯時鏈接dylib文件。
      • 若是下列系統框架與庫文件還不存在,請將他們加入: 
        • libz.tdb
        • CFNetwork.framework
        • QuartzCore.framework
        • CoreGraphics.framework - Xcode通常默認會在工程中包含此框架文件。
    8. 爲了能在debugger以外,將庫文件動態地載入設備上的應用,您須要在構建過程當中加入對libReveal.dylib文件的code sign。

      進入target的Build Phases標籤頁,選擇Editor → Add Build Phase → Add Run Script菜單。在Run Script階段中加入如下內容:

      set -e if [ -n "${CODE_SIGN_IDENTITY}" ]; then codesign -fs "${CODE_SIGN_IDENTITY}" "${BUILT_PRODUCTS_DIR}/${FULL_PRODUCT_NAME}/libReveal.dylib" fi

  1. 將下面的代碼加入到項目中合適的類文件中(例如您的UIApplicationDelegate),適當修改使之知足您的須要:

    Swift:

    // MARK: - Reveal
    
    func loadReveal() {
        if NSClassFromString("IBARevealLoader") == nil { let revealLibName = "libReveal" // or "libReveal-tvOS" for tvOS targets let revealLibExtension = "dylib" var error: String? if let dylibPath = NSBundle.mainBundle().pathForResource(revealLibName, ofType: revealLibExtension) { print("Loading dynamic library \(dylibPath)") let revealLib = dlopen(dylibPath, RTLD_NOW) if revealLib == nil { error = String(UTF8String: dlerror()) } } else { error = "File not found." } if error != nil { let alert = UIAlertController(title: "Reveal library could not be loaded", message: "\(revealLibName).\(revealLibExtension) failed to load with error: \(error!)", preferredStyle: .Alert) alert.addAction(UIAlertAction(title: "OK", style: .Default, handler: nil)) UIApplication.sharedApplication().windows.first?.rootViewController?.presentViewController(alert, animated: true, completion: nil) } } }
  2. Objective-C:

    #pragma mark - Reveal - (void)loadReveal { if (NSClassFromString(@"IBARevealLoader") == nil) { NSString *revealLibName = @"libReveal"; // or @"libReveal-tvOS" for tvOS targets NSString *revealLibExtension = @"dylib"; NSString *error; NSString *dyLibPath = [[NSBundle mainBundle] pathForResource:revealLibName ofType:revealLibExtension]; if (dyLibPath != nil) { NSLog(@"Loading dynamic library: %@", dyLibPath); void *revealLib = dlopen([dyLibPath cStringUsingEncoding:NSUTF8StringEncoding], RTLD_NOW); if (revealLib == NULL) { error = [NSString stringWithUTF8String:dlerror()]; } } else { error = @"File not found."; } if (error != nil) { NSString *message = [NSString stringWithFormat:@"%@.%@ failed to load with error: %@", revealLibName, revealLibExtension, error]; UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Reveal library could not be loaded" message:message preferredStyle:UIAlertControllerStyleAlert]; [alert addAction:[UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:nil]]; [[[[[UIApplication sharedApplication] windows] firstObject] rootViewController] presentViewController:alert animated:YES completion:nil]; } } }
  3. 警告: 不要在發佈(release)構建中調用此方法,確保僅是在應用的調試(debug)構建中加載libReveal.dylib。

  4. 一個簡單的集成方式是,在-[UIApplicationDelegate applicationDidBecomeActive:]方法中調用上面聲明的- (void)loadReveal方法,以確保Reveal庫儘早地被加載進來。 
    Swift:

    1. func applicationDidBecomeActive:(application: UIApplication) { self.loadReveal() }
  5. Objective-C:

    (void)applicationDidBecomeActive:(UIApplication *)application { [self loadReveal]; }
  6. 提示: 在-[UIApplicationDelegate applicationDidBecomeActive:]方法返回以前加載庫的一個好處是,將會讓Reveal服務在應用啓動的同時也自動啓動。

    若是您不但願如上述步驟自動啓動Reveal服務,也能夠以手動的方式來啓動,例如經過一個Debug按鈕。在應用啓動後,本身調用loadReveal方法,而後再分發一個名爲IBARevealRequestStart的NSNotification: 
    Swift:

    func startReveal() {
        NSNotificationCenter.defaultCenter().postNotificationName("IBARevealRequestStart", object: nil) }
  7. Objective-C:

    - (void)startReveal { [[NSNotificationCenter defaultCenter] postNotificationName:@"IBARevealRequestStart" object:nil]; }
  8. 在Xcode中,構建並運行您的應用。若是一切正常運行,請切換到Reveal應用,此時您的應用應會出如今應用選擇器的下拉列表當中。選中您的應用,確承認以看到此時正在模擬器(或設備)中運行的應用界面截圖。

CocoaPods

CocoaPods 是一款針對iOS與OSX項目的依賴管理系統。它大大簡化了以往Xcode工程裏,對第三方庫的依賴管理與配置工做。

CocoaPods提供了Podspec用於將Reveal集成入您的項目。

警告: 不要將鏈接了Reveal庫文件的應用用於正式發佈。下面的指南描述了一種使用構建配置來使Reveal靜態庫文件僅在調試構建中鏈接的方式。

此說明要求您在以前已經在項目中配置好了CocoaPods,若否則,請先行配置Cocoapods。

  1. 將下面內容加入你的Podfile中:

    pod 'Reveal-iOS-SDK', :configurations => ['Debug']
  2. 在項目的根目錄下執行 pod install 命令(若是以前已經在項目中使用了Cocoapods,請執行 pod update 命令)。

從您的Xcode項目中移除Reveal

根據您實際所選擇的Reveal集成方式,請根據下述相關步驟來移除Reveal。

一旦庫文件成功的移除後,下面的內容將再也不會在您的應用啓動時出如今Xcode控制檯:

INFO: Reveal Server started (Protocol Version X).

靜態鏈接

  1. 打開您的Xcode工程。
  2. 從 Project Navigator 中刪除 Reveal.framework 的引用。
  3. 在Xcode的 Project Navigator中選中您的工程,對於每個集成了Reveal得target,請選擇 Build Settings 標籤頁,將下面內容從 Debug 配置中的 Other Linked Flags 設置中移除: 
    • -framework Reveal
    • -ObjC and -lz (刪除前請確認此配置內容僅是用於Reveal)。
  4. 搞定 - 運行應用,確認Reveal沒有和應用鏈接上。

動態鏈接

  1. 打開您的Xcode工程。
  2. 從 Project Navigator 中刪除 libReveal.dylib 的引用。
  3. 在Xcode的 Project Navigator中選中您的工程,對於每個集成了Reveal得target,選擇 Build Phases 標籤頁,若是下列庫文件僅供Reveal使用的話,請將它們從 Link Binary With Libraries 配置中移除: 
    • libz.dylib
    • CFNetwork.framework
    • QuartzCore.framework
    • CoreGraphics.framework
  4. 將自定義的codesign內容從 Build Phases 下的 Run Script 中刪除。
  5. 將 loadReveal / startReveal 方法從您的代碼中刪除。
  6. 搞定 - 運行應用,確認Reveal沒有和應用鏈接上。

CocoaPods

  1. 在您的Podfile文件中刪除下面這行內容:

    pod 'Reveal-iOS-SDK', :configurations => ['Debug']
  2. 在項目的根目錄下執行 pod update 命令。

  3. 若是您的 Podfile 中只有 Reveal-iOS-SDK 一個pod依賴,請根據此說明,將CocoaPods從項目中徹底移除。

  4. 搞定 - 運行應用,確認Reveal沒有和應用鏈接上。

顯示效果

上圖是Reveal的運行界面,其界面主要分紅3部分:

  • 左邊部分是整個界面的層級關係,在這裏能夠以樹形級層的方式來查看整個界面元素。

  • 中間部分是一個可視化的查看區域,用戶能夠在這裏切換2D或3D的查看方式,這裏看到的也是程序運行的實時界面。

  • 右邊部邊是控件的詳細參數查看區域,當咱們選中某一個具體的控件時,右邊就能夠顯示出該控件的具體的參數列表。咱們除了能夠查看這些參數值是否正確外,還能夠嘗試修改這些值。全部的修改均可以實時反應到中間的實時預覽區域。

重要提示

  1. 不要將鏈接了Reveal庫文件的應用正式發佈。 Reveal的檢視機制,會將您應用的許多內部信息暴露出來,而這將極可能致使您的應用被Apple審查團隊拒絕發佈。Reveal的目的僅用於內部開發與應用調試。
  2. 當iOS應用進入後臺後,Reveal服務將會自動中止。 當應用從新打開時,它又會自動啓動。
  3. Reveal支持基於iOS 7及更新版本而編譯的應用。 構建配置中的iOS Deployment Target也必須是’iOS 7.0’或更新版本。 若是iOS版本太舊,您有可能會在構建應用過程當中遇到鏈接錯誤。
  4. Reveal使用Bonjour協議來鏈接運行時的iOS應用。 若是您的iOS應用是運行在真實的設備之上,那麼此設備也須要處在同一個網絡以內,以便電腦上的Reveal應用可以與之鏈接。若是您在鏈接應用時仍遇到問題,請先檢查防火牆和代理設置,以確保它們沒有阻礙通信。

用Reveal調試其它應用界面

若是你的設備越獄了,那麼還能夠用Reveal來」調試「其它應用界面,何時會有這種奇怪的需求呢?——當咱們想學習別人是如何實現界面效果的時候。iOS設備的目錄/Library/MobileSubstrate/DynamicLibraries 下存放着全部在系統啓動時就須要加載的動態連接庫,因此咱們只須要將Reveal的動態連接庫上傳到該目錄便可。

對於越獄的設備,咱們能夠在安裝OpenSSH以後,用scp來上傳該文件。具體步驟以下:

將libReveal.dylib 上傳到 /Library/MobileSubstrate/DynamicLibraries 若是libReveal.dylib沒有執行權限,用chmod +x libReveal.dylib命令,給其增長執行權限 執行 killall SpringBoard 重啓桌面

相關文章
相關標籤/搜索