从Xcode项目中添加和移除Reveal


参考链接

添加Reveal

为了让Reveal能够在运行时,检视及调试您的iOS应用,首先您需将Reveal库文件连接入您的应用当中。而所需的Reveal库文件已经内置在Reveal的应用程序当中。

Reveal提供了以下三种方式来集成库文件与您的iOS应用:

静态连接

将Reveal的静态库文件连接入应用,是最简单快捷地启用Reveal检视的方式。

警告: 不要将Reveal库文件随着正式应用一起发布。 下面的步骤将会展示如何通过构建配置,而把Reveal静态库文件,仅连接到调试构建的流程中。

  • 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。可选步骤:选中__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网络中。

Reveal App Chooser showing Soundstagram

如果一切正常运行,请切换到Reveal应用,此时您的应用应会出现在应用选择器的下拉列表当中。选中您的应用,确认可以看到此时正在模拟器(或设备)中运行的应用界面截图。
  • 8、再次运行您的应用,这一次,请选择基于Releasescheme。请确认此时,Reveal不再能连接上您的应用。如果应用仍然与Reveal保持连接,请确认 Reveal.framework 没有出现在Build Phases标签的Link Binary With Libraries配置项中。

集成Reveal无需添加任何代码,无需引入任何头文件。库将会在应用启动时自动加载,并在您的应用内部启动必要的Reveal服务。

如果您希望对集成的方式拥有更多地控制,请参考动态加载之集成步骤。

动态连接

对于那些想要完全控制应用程序加载库文件时机的开发者,动态加载是一个不错的方式。采用动态加载的方式,Reveal的代码只会在运行时,根据您的需要而加载。

将动态库文件集成入您的iOS应用的方式有两种:

将Reveal加入您的Xcode工程

将Reveal加入您的Xcode工程,使得您团队中的其他成员无需任何额外的配置,就可以使用Reveal。

警告: 永远不要将包含Reveal动态库文件的应用正式发布。Apple不允许将含有动态加载库文件的iOS应用发布到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不会在编译时连接动态库文件。可选步骤:选中__Copy items if needed__,将会把 libReveal.dylib 拷贝到工程中——如果您这么做了, 请记住,当更新Reveal至新版本时,也依照上述步骤再次更新此库文件

Copy resource to project dialog

  • 点击Finish

  • XcodeProject Navigator中,选中您的工程,然后将以下步骤应用在所有您希望适配Revealtarget之上:

Copy library to bundle resources

* 在__Copy Bundle Resources__配置区域中,加入*libReveal.dylib*。
* 在**Link Binary With Libraries**配置项中:
    * 如果已有*libReveal.dylib*,请将其移除——不应在编译时连接dylib文件。
    * 如果下列系统框架与库文件还不存在,请将他们加入:
        * libz.dylib
        * CFNetwork.framework
        * QuartzCore.framework
        * CoreGraphics.framework - Xcode一般默认会在工程中包含此框架文件。
  • 为了能在debugger之外,将库文件动态地载入设备上的应用,您需要在构建过程中加入对libReveal.dylib文件的code sign。

Add Run Script phase

进入targetBuild 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
  • 将下面的代码加入到项目中合适的类文件中(例如您的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];
            }
        }
    }

警告: 不要在发布release构建中调用此方法,确保仅是在应用的调试debug构建中加载libReveal.dylib

  • 一个简单的集成方式是,在-[UIApplicationDelegate application: didFinishLaunchingWithOptions:]方法中调用上面声明的- (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按钮。在应用启动后,自己调用loadReveal方法,然后再分发一个名为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应用,此时您的应用应会出现在应用选择器的下拉列表当中。选中您的应用,确认可以看到此时正在模拟器(或设备)中运行的应用界面截图。

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

此方法仅适用于在iOS模拟器上运行的应用。

通过不修改Xcode工程文件来加载Reveal的方式,您可以检视任何一个您正在开发的iOS应用,而不需要对这些应用的工程做任何修改。另一个好处就是,您不需要再担心,犯下一不小心将Reveal库连接到应用中发布了的错误。

  • 打开您的iOS工程,选择View → Navigators → Show Breakpoint Navigator

  • 在面板左下角,点击 + 按钮并选择Add Symbolic Breakpoint

Adding Symbolic Breakpoint to Xcode project

  • Symbol 输入区内输入 UIApplicationMain

  • 点击 Add Action 按钮, 确认 Action 被设置为 Debugger Command

  • 将以下内容拷贝到 Action 的输入区内:

    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

  • 右击刚才新创建的断点,选择 Move Breakpoint To → User.

Moving the Breakpoint to the User

您可以像其他断点一样,禁用或启用此断点。用户级别断点在所有的Xcode工程中都可以使用。

  • 在iOS模拟器上构建并运行您的应用。

Reveal App Chooser showing Soundstagram

如果一切正常运行,请切换到Reveal应用,此时您的应用应会出现在应用选择器的下拉列表当中。选中您的应用,确认可以看到此时正在模拟器中运行的应用界面截图。

CocoaPods

CocoaPods 是一款针对iOSOSX项目的依赖管理系统。它大大简化了以往Xcode工程里,对第三方库的依赖管理与配置工作。

CocoaPods提供了Podspec用于将Reveal集成入您的项目。

警告: 不要将连接了Reveal库文件的应用用于正式发布。下面的指南描述了一种使用构建配置来使Reveal静态库文件仅在调试构建中连接的方式。

此说明要求您在之前已经在项目中配置好了CocoaPods,若不然,请先行配置Cocoapods

  • 将下面内容加入你的Podfile中:

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

  • 在项目的根目录下执行 pod install 命令(如果之前已经在项目中使用了Cocoapods,请执行 pod update 命令)。

提示:

  1. 我们一直致力让CocoaPods仓库中的Reveal Podspec保持最新,但有时它还是有可能稍稍落后于最近发布的Reveal版本。

  2. 如果您使用的CocoaPods版本早于0.34,那么在执行 pod install 或者 pod update 命令时,可能会在控制台看到如下的错误:

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

请通过更新CocoaPods至最新版本来解决此问题。

移除Reveal

根据您实际所选择的Reveal集成方式,请根据下述相关步骤来移除Reveal。

一旦库文件成功的移除后,下面的内容将不再会在您的应用启动时出现在Xcode控制台:

INFO: Reveal Server started (Protocol Version X).

静态连接

  1. 打开您的Xcode工程。
  2. 从 Project Navigator 中删除 Reveal.framework 的引用。
  3. 在Xcode的 Project Navigator中选中您的工程,对于每一个集成了Revealtarget,请选择 Build Settings 标签页,将下面内容从 Debug 配置中的 Other Linked Flags 设置中移除:
        -framework Reveal
        -ObjC and -lz (删除前请确认此配置内容仅是用于Reveal)。
  1. 搞定 - 运行应用,确认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
  1. 将自定义的codesign内容从 Build Phases 下的 Run Script 中删除。
  2. 将 loadReveal / startReveal 方法从您的代码中删除。
  3. 搞定 - 运行应用,确认Reveal没有和应用连接上。

CocoaPods

  1. 在您的Podfile文件中删除下面这行内容:
    pod 'Reveal-iOS-SDK', :configurations => ['Debug']

  1. 在项目的根目录下执行 pod update 命令。

  2. 如果您的 Podfile 中只有 Reveal-iOS-SDK 一个pod依赖,请根据此说明,将CocoaPods从项目中完全移除。

  3. 搞定 - 运行应用,确认Reveal没有和应用连接上。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,294评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,493评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,790评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,595评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,718评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,906评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,053评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,797评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,250评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,570评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,711评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,388评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,018评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,796评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,023评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,461评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,595评论 2 350

推荐阅读更多精彩内容

  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 12,066评论 4 62
  • Reveal是iOS开发工具中的神器之一,它能够在应用程序运行过程中调试应用程序界面。 通过Reveal我们可以连...
    jackfrued阅读 12,415评论 2 48
  • 近些日子再读陈忠实先生所著《白鹿原》,与之前第一次读入心的程度又深了些,认真地读进去,对一些场面印象很深刻,文章本...
    爱画画的littleZoe阅读 684评论 0 0
  • 银耳是个好东西,被誉为平价的燕窝,是养颜护肤圣品。除此之外还有补脾开胃、益气清肠、安眠补脑、养阴清热、润燥的功效。...
    三木三木酱阅读 5,146评论 1 10
  • 起这个名字是在我情绪完全不正常的情况下。。正常我怎么会起这种名字呢!正常我为什么要写这些呢。以上。 纯属自 hi ...
    Fiona写写画画阅读 175评论 0 0