【问题标题】:Dependency Management for iOS LibraryiOS 库的依赖管理
【发布时间】:2011-12-31 21:16:01
【问题描述】:

首先:为什么 obj-c 项目的依赖管理如此痛苦?!

我正在 Objective-c 中为我的 RESTful 服务编写一个包装器。服务器是一个简单的 sinatra 应用程序,在本地运行在 'http://localhost:4567' 上。

我按照here 列出的步骤包含了 RestKit。 我知道 RestKit 已正确“安装”到我的项目中,因为当我执行 #import <RestKit/RestKit.h> 时,项目构建得很好。

现在,我正在使用 SenTesting.Framework 测试我的库。我的主库中有一个类,如下所示:

#import "CITWCore.h"
#import <RestKit/RestKit.h>
@implementation CITWCore

- (id)init
{
    self = [super init];
    if (self) {
      RKObjectManager *manager = [RKObjectManager objectManagerWithBaseURL:@"http://localhost:4567"];
        // Initialization code here.
    }

    return self;
}

@end

还有我的单元测试类:

#import "CITWCoreTests.h"

@implementation CITWCoreTests


- (void)testItCreatesAnInstance
{
  CITWCore *newCoreObject = [[CITWCore alloc]init];
  STAssertNotNil(newCoreObject, @"new object should not be nil");
}

@end

当我使用 ⌘U 运行测试时,测试失败并显示以下消息:

error: testExample (CITWCoreTests) failed: -[__NSCFString isIPAddress]: unrecognized selector sent to instance 0xa115880

RKClient.m 中的第 292 行触发了错误

if ([newBaseURLString isEqualToString:@"localhost"] || [hostName isIPAddress]) {

RestKit 项目中有一个名为“NSString+RestKit.h”的头文件,其中包含 -isIPAddress 方法声明,据我所知,它被包含在内,所以我不知道为什么编译器/运行-time 不知道那个特定的方法。我配置测试目标的方式有问题吗?如何创建 RKObjectManager 的实例并让这个测试通过?

更抽象地说:人们如何管理这样的依赖关系?我正在查看VenderKit 之类的东西,但它似乎缺乏文档,而且我认为我对编译器和链接器如何工作以达到那么大的抽象没有正确的理解。将静态库链接到我的项目(它本身就是一个静态库)时,有哪些一般准则?

【问题讨论】:

  • 有人吗?这个问题没有意义吗?
  • 您确定#import &lt;RestKit/RestKit.h&gt; 在 CITWCoreTests.m 中吗?如果没有,那么您将收到该错误

标签: objective-c ios xcode restkit


【解决方案1】:

仔细检查“其他链接器标志”的项目构建设置在构建目标上是否具有“-all_load”和“-ObjC”。当您在那里时,检查您是否创建了“标题搜索路径”条目(“$(SOURCE_ROOT)/RestKit”)。

您链接到的“Installing-RestKit-in-Xcode-4.x”页面与 a) Xcode 和 b) RestKit HEAD 稍有过时(最近简化了构建过程。FMI 请参阅邮件列表.

如果您想查看正确设置的项目(我最近使用最新的 Xcode 和 Restkit 创建了它),请查看 https://github.com/lottadot/lottadot-restkit-ios-rails3-1-advanced

我的猜测是,如果你克隆那个项目,编辑它的配置并删除“-all_load”,你会在运行它时看到exact相同的错误。

【讨论】:

  • 谢谢@lottadot。你的测试项目帮助了我。我必须将链接器标志和标头搜索路径添加到 both 我的库目标 我的测试目标。
【解决方案2】:

在这种情况下,您需要找到定义/导出-[NSString isIPAddress] 的文件(或图像/库)。然后您需要将该文件添加到您的编译阶段(如果它是源文件),或者将库链接到您的最终二进制文件(如果它是库或目标文件)。除了将其链接到您的应用之外,您还需要将其编译和/或链接到您的单元测试可执行文件中

我知道 RestKit 已正确“安装”到我的项目中,因为当我执行 #import 时,项目构建得很好。

#importing 不一定会链接或编译所有必要的依赖项。您可能必须手动执行此操作。 Xc4 可能自动检测依赖关系,如果启用该选项,则为您构建和链接它——但它并不总是正确(它对基本依赖关系有好处) .

为什么 obj-c 项目的依赖管理如此痛苦?!

真的不是,IMO。在编译 C 系列语言时,您需要习惯于指定要编译的文件和要链接的库。除非您想更具体地说明这种批评……

人们如何管理这样的依赖关系?

将依赖项目添加到您的 Xcode 项目中。将它们配置为构建依赖项——这将确保它们在构建您的应用程序之前构建,并且构建是最新的。对于静态库(针对 iOS),保存最终可执行文件的链接阶段。在更复杂的场景中,您需要使用 xcconfig 文件来轻松定义任何/所有依赖项的构建设置。

【讨论】:

    【解决方案3】:

    一个简单的解决方案是使用cocoapods,这是一个很好的依赖管理工具,类似于Java世界中的maven。

    CocoaPods 是一个非常强大且成熟的依赖管理工具,可以管理库,这些依赖的库(传递依赖)以及编译器和标头标志。

    它通过将您的项目链接到另一个工作区来工作,该工作区包含源形式的库,其中主要目标发出一个静态库。这在速度和能够查看源代码之间做出了很好的折衷。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-08-07
      • 2021-12-08
      • 1970-01-01
      • 2012-06-30
      • 1970-01-01
      • 1970-01-01
      • 2019-02-14
      • 2021-11-18
      相关资源
      最近更新 更多