從Xcode項目中添加和移除Reveal


參考鏈接

添加Reveal

為了讓Reveal能夠在運行時,檢視及調(diào)試您的iOS應用,首先您需將Reveal庫文件連接入您的應用當中。而所需的Reveal庫文件已經(jīng)內(nèi)置在Reveal的應用程序當中。

Reveal提供了以下三種方式來集成庫文件與您的iOS應用:

靜態(tài)連接

將Reveal的靜態(tài)庫文件連接入應用,是最簡單快捷地啟用Reveal檢視的方式。

警告: 不要將Reveal庫文件隨著正式應用一起發(fā)布。 下面的步驟將會展示如何通過構建配置,而把Reveal靜態(tài)庫文件,僅連接到調(diào)試構建的流程中。

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

  • 2、啟動Reveal并選擇__Help → Show Reveal Library in Finder__,這將會打開Finder窗口,并顯示一個名為*iOS-Libraries*的文件夾。
    Show Reveal Library in Finder

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

  • 4、在下圖所顯示的__Add to targets__對話框中,選擇所有您希望與Reveal集成的target??蛇x步驟:選中__Copy items if needed__,將會把 Reveal.framework 拷貝到工程中——如果您這么做了, 請記住,當更新Reveal至新版本時,也依照上述步驟再次更新此庫文件。

Copy resource to project dialog

  • 5、點擊Finish。

  • 6、在XcodeProject Navigator中,選中您的工程,然后將以下步驟應用于所有您希望與Reveal集成的target之上:

    • 選擇Build Phases標簽,如果在Link Binary With Libraries配置項中已有Reveal.framework,請將其移除。

      Remove Reveal framework from target
      
    • 選擇Build Settings標簽,在Other Linker FlagsDebug配置項中加入如下配置:

      -ObjC -lz -framework Reveal
      
      Add linker flags to target
      
  • 7、在Xcode中,選擇基于Debug配置的scheme,構建并運行您的應用。如果應用運行于真實設備之上,請確保此設備與正在運行Reveal的Mac機器,處于同一Wi-Fi網(wǎng)絡中。

Reveal App Chooser showing Soundstagram

如果一切正常運行,請切換到Reveal應用,此時您的應用應會出現(xiàn)在應用選擇器的下拉列表當中。選中您的應用,確認可以看到此時正在模擬器(或設備)中運行的應用界面截圖。
  • 8、再次運行您的應用,這一次,請選擇基于Releasescheme。請確認此時,Reveal不再能連接上您的應用。如果應用仍然與Reveal保持連接,請確認 Reveal.framework 沒有出現(xiàn)在Build Phases標簽的Link Binary With Libraries配置項中。

集成Reveal無需添加任何代碼,無需引入任何頭文件。庫將會在應用啟動時自動加載,并在您的應用內(nèi)部啟動必要的Reveal服務。

如果您希望對集成的方式擁有更多地控制,請參考動態(tài)加載之集成步驟。

動態(tài)連接

對于那些想要完全控制應用程序加載庫文件時機的開發(fā)者,動態(tài)加載是一個不錯的方式。采用動態(tài)加載的方式,Reveal的代碼只會在運行時,根據(jù)您的需要而加載。

將動態(tài)庫文件集成入您的iOS應用的方式有兩種:

將Reveal加入您的Xcode工程

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

警告: 永遠不要將包含Reveal動態(tài)庫文件的應用正式發(fā)布。Apple不允許將含有動態(tài)加載庫文件的iOS應用發(fā)布到Apple商店中。

  • Xcode中打開您的iOS工程。

  • 啟動Reveal并選擇__Help → Show Reveal Library in Finder__,這將會打開Finder窗口,并顯示一個名為iOS-Libraries的文件夾。

Show Reveal Library in Finder

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

  • 在下圖所顯示的__Add to targets__對話框中,__反選所有的target__。這確保了Xcode不會在編譯時連接動態(tài)庫文件??蛇x步驟:選中__Copy items if needed__,將會把 libReveal.dylib 拷貝到工程中——如果您這么做了, 請記住,當更新Reveal至新版本時,也依照上述步驟再次更新此庫文件。

Copy resource to project dialog

  • 點擊Finish。

  • XcodeProject Navigator中,選中您的工程,然后將以下步驟應用在所有您希望適配Revealtarget之上:

Copy library to bundle resources

* 在__Copy Bundle Resources__配置區(qū)域中,加入*libReveal.dylib*。
* 在**Link Binary With Libraries**配置項中:
    * 如果已有*libReveal.dylib*,請將其移除——不應在編譯時連接dylib文件。
    * 如果下列系統(tǒng)框架與庫文件還不存在,請將他們加入:
        * libz.dylib
        * CFNetwork.framework
        * QuartzCore.framework
        * CoreGraphics.framework - Xcode一般默認會在工程中包含此框架文件。
  • 為了能在debugger之外,將庫文件動態(tài)地載入設備上的應用,您需要在構建過程中加入對libReveal.dylib文件的code sign。

Add Run Script phase

進入targetBuild Phases標簽頁,選擇Editor → Add Build Phase → Add Run Script菜單。在Run Script階段中加入以下內(nèi)容:

    set -e

    if [ -n "${CODE_SIGN_IDENTITY}" ]; then
        codesign -fs "${CODE_SIGN_IDENTITY}" "${BUILT_PRODUCTS_DIR}/${FULL_PRODUCT_NAME}/libReveal.dylib"
    fi
  • 將下面的代碼加入到項目中合適的類文件中(例如您的UIApplicationDelegate),適當修改使之滿足您的需要:
  Swift:
    // MARK: - Reveal

    func loadReveal() {
        if NSClassFromString("IBARevealLoader") == nil {
            let revealLibName = "libReveal"
            let revealLibExtension = "dylib"
            var error: String?

            if let dylibPath = NSBundle.mainBundle().pathForResource(revealLibName, ofType: revealLibExtension) {
                println("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 {
                UIAlertView(title: "Reveal library could not be loaded",
                          message: "\(revealLibName).\(revealLibExtension) failed to load with error: \(error!)",
                         delegate: nil,
                cancelButtonTitle: "OK").show()
            }
        }
    }
    Objective-C:

    #pragma mark - Reveal
    #import <dlfcn.h>

    - (void)loadReveal
    {
        if (NSClassFromString(@"IBARevealLoader") == nil)
        {
            NSString *revealLibName = @"libReveal";
            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];
                [[[UIAlertView alloc] initWithTitle:@"Reveal library could not be loaded" message:message delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil] show];
            }
        }
    }

警告: 不要在發(fā)布release構建中調(diào)用此方法,確保僅是在應用的調(diào)試debug構建中加載libReveal.dylib。

  • 一個簡單的集成方式是,在-[UIApplicationDelegate application: didFinishLaunchingWithOptions:]方法中調(diào)用上面聲明的- (void)loadReveal方法,以確保Reveal庫盡早地被加載進來。
    Swift:

    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
        self.loadReveal()
        return true
    }

    Objective-C:

    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
    {
        [self loadReveal];
        return YES;
    }

提示: 在-[UIApplicationDelegate application: didFinishLaunchingWithOptions:]方法返回之前加載庫的一個好處是,將會讓Reveal服務在應用啟動的同時也自動啟動。

  • 如果您不希望如上述步驟自動啟動Reveal服務,也可以以手動的方式來啟動,例如通過一個Debug按鈕。在應用啟動后,自己調(diào)用loadReveal方法,然后再分發(fā)一個名為IBARevealRequestStartNSNotification:
    Swift:

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

    Objective-C:

    - (void)startReveal
    {
        [[NSNotificationCenter defaultCenter] postNotificationName:@"IBARevealRequestStart" object:nil];
    }
  • Xcode中,選擇基于Debug配置的scheme,構建并運行您的應用。

    Reveal App Chooser showing Soundstagram

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

不修改您的Xcode工程并加載Reveal

此方法僅適用于在iOS模擬器上運行的應用。

通過不修改Xcode工程文件來加載Reveal的方式,您可以檢視任何一個您正在開發(fā)的iOS應用,而不需要對這些應用的工程做任何修改。另一個好處就是,您不需要再擔心,犯下一不小心將Reveal庫連接到應用中發(fā)布了的錯誤。

  • 打開您的iOS工程,選擇View → Navigators → Show Breakpoint Navigator。

  • 在面板左下角,點擊 + 按鈕并選擇Add Symbolic Breakpoint

Adding Symbolic Breakpoint to Xcode project

  • Symbol 輸入?yún)^(qū)內(nèi)輸入 UIApplicationMain 。

  • 點擊 Add Action 按鈕, 確認 Action 被設置為 Debugger Command

  • 將以下內(nèi)容拷貝到 Action 的輸入?yún)^(qū)內(nèi):

    expr (Class)NSClassFromString(@"IBARevealLoader") == nil ? (void *)dlopen("/Applications/Reveal.app/Contents/SharedSupport/iOS-Libraries/libReveal.dylib", 0x2) : ((void*)0)

注意: 請確認Reveal.app的路徑信息符合您Mac的實際位置

  • 選中 Automatically continue after evaluating actions 選項。

Setting up Symbolic Breakpoint in Xcode project

  • 右擊剛才新創(chuàng)建的斷點,選擇 Move Breakpoint To → User.

Moving the Breakpoint to the User

您可以像其他斷點一樣,禁用或啟用此斷點。用戶級別斷點在所有的Xcode工程中都可以使用。

  • 在iOS模擬器上構建并運行您的應用。

Reveal App Chooser showing Soundstagram

如果一切正常運行,請切換到Reveal應用,此時您的應用應會出現(xiàn)在應用選擇器的下拉列表當中。選中您的應用,確認可以看到此時正在模擬器中運行的應用界面截圖。

CocoaPods

CocoaPods 是一款針對iOSOSX項目的依賴管理系統(tǒng)。它大大簡化了以往Xcode工程里,對第三方庫的依賴管理與配置工作。

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

警告: 不要將連接了Reveal庫文件的應用用于正式發(fā)布。下面的指南描述了一種使用構建配置來使Reveal靜態(tài)庫文件僅在調(diào)試構建中連接的方式。

此說明要求您在之前已經(jīng)在項目中配置好了CocoaPods,若不然,請先行配置Cocoapods。

  • 將下面內(nèi)容加入你的Podfile中:

pod 'Reveal-iOS-SDK', :configurations => ['Debug']

  • 在項目的根目錄下執(zhí)行 pod install 命令(如果之前已經(jīng)在項目中使用了Cocoapods,請執(zhí)行 pod update 命令)。

提示:

  1. 我們一直致力讓CocoaPods倉庫中的Reveal Podspec保持最新,但有時它還是有可能稍稍落后于最近發(fā)布的Reveal版本。

  2. 如果您使用的CocoaPods版本早于0.34,那么在執(zhí)行 pod install 或者 pod update 命令時,可能會在控制臺看到如下的錯誤:

[!] Unknown external source parameters for `Reveal-iOS-SDK`: `{:configurations=>["Debug"]}`

請通過更新CocoaPods至最新版本來解決此問題。

移除Reveal

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

一旦庫文件成功的移除后,下面的內(nèi)容將不再會在您的應用啟動時出現(xiàn)在Xcode控制臺:

INFO: Reveal Server started (Protocol Version X).

靜態(tài)連接

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

動態(tài)連接

  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
  1. 將自定義的codesign內(nèi)容從 Build Phases 下的 Run Script 中刪除。
  2. 將 loadReveal / startReveal 方法從您的代碼中刪除。
  3. 搞定 - 運行應用,確認Reveal沒有和應用連接上。

CocoaPods

  1. 在您的Podfile文件中刪除下面這行內(nèi)容:
    pod 'Reveal-iOS-SDK', :configurations => ['Debug']

  1. 在項目的根目錄下執(zhí)行 pod update 命令。

  2. 如果您的 Podfile 中只有 Reveal-iOS-SDK 一個pod依賴,請根據(jù)此說明,將CocoaPods從項目中完全移除。

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

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,763評論 6 539
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,238評論 3 428
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,823評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,604評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,339評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,713評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,712評論 3 445
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,893評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,448評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 41,201評論 3 357
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,397評論 1 372
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,944評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,631評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,033評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,321評論 1 293
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,128評論 3 398
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,347評論 2 377

推薦閱讀更多精彩內(nèi)容

  • 發(fā)現(xiàn) 關注 消息 iOS 第三方庫、插件、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關注 2017.06.26 09:4...
    肇東周閱讀 12,162評論 4 61
  • Reveal是iOS開發(fā)工具中的神器之一,它能夠在應用程序運行過程中調(diào)試應用程序界面。 通過Reveal我們可以連...
    jackfrued閱讀 12,505評論 2 48
  • 近些日子再讀陳忠實先生所著《白鹿原》,與之前第一次讀入心的程度又深了些,認真地讀進去,對一些場面印象很深刻,文章本...
    愛畫畫的littleZoe閱讀 712評論 0 0
  • 銀耳是個好東西,被譽為平價的燕窩,是養(yǎng)顏護膚圣品。除此之外還有補脾開胃、益氣清腸、安眠補腦、養(yǎng)陰清熱、潤燥的功效。...
    三木三木醬閱讀 5,166評論 1 10
  • 起這個名字是在我情緒完全不正常的情況下。。正常我怎么會起這種名字呢!正常我為什么要寫這些呢。以上。 純屬自 hi ...
    Fiona寫寫畫畫閱讀 215評論 0 0