从Xcode项目中添加和移除Reveal

作者: 681916139107 | 来源:发表于2016-09-08 11:28 被阅读972次

参考链接

添加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没有和应用连接上。

相关文章

网友评论

    本文标题: 从Xcode项目中添加和移除Reveal

    本文链接:https://www.haomeiwen.com/subject/rwysettx.html