iOS 库的依赖管理

发布于 2024-12-23 09:43:12 字数 1815 浏览 1 评论 0原文

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

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

我按照此处列出的步骤添加了 RestKit。 我知道 RestKit 已正确“安装”到我的项目中,因为当我执行 #import 时,项目构建得很好。

现在,我正在使用 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

The error is being returned by line 292 in RKClient.m

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

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

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

First off: Why is dependency management for obj-c projects such a pain?!

I am writing a wrapper for my RESTful service in objective-c. The server is a simple sinatra app running locally on 'http://localhost:4567'.

I've included RestKit by following the steps outlined here.
I know RestKit is 'installed' correctly into my project because when I do #import <RestKit/RestKit.h> the project builds just fine.

Now, I'm testing my library using SenTesting.Framework. I have a class in my main library that looks like this:

#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

And my unit test class:

#import "CITWCoreTests.h"

@implementation CITWCoreTests


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

@end

When I run the tests using ⌘U the test fails with this message:

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

The error is being triggered by line 292 in RKClient.m

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

There is a header file in the RestKit project called "NSString+RestKit.h" which contains the -isIPAddress method declaration, and as far as I can tell it is getting included, so I have no idea why the compiler/run-time does not know about that particular method. Is there something wrong with the way I've configured my testing target? How can I create an instance of RKObjectManager and get this test to pass?

More abstractly: How are people managing dependencies like this? I'm looking at things like VenderKit, but it seems lacking in documentation and I don't think I have the proper understanding of how compilers and linkers work to go to that big of an abstraction. What are some general guidelines when linking static libraries into my project, which is itself a static library?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

Saygoodbye 2024-12-30 09:43:12

仔细检查“其他链接器标志”的项目构建设置在构建目标上是否具有“-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”,那么当您运行它时,您将看到完全相同相同的错误。

Double check that your project build settings for "Other Linker Flags" has "-all_load" and "-ObjC" on your build target. While you are in there, check that you created the "Header Search Paths" entry ("$(SOURCE_ROOT)/RestKit").

The "Installing-RestKit-in-Xcode-4.x" page that you linked to, is slightly out of date with a) Xcode and b) RestKit HEAD (the build process was simplified recently. FMI see the mailing list.

If you want to see a project correctly setup (I just created it recently, with the newest Xcode and Restkit) take a look at https://github.com/lottadot/lottadot-restkit-ios-rails3-1-advanced

My guess is if you clone that project, edit it's configuration and remove "-all_load" you will see the exact same error, when you run it.

小瓶盖 2024-12-30 09:43:12

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

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

#import 不一定会链接或编译所有必需的依赖项。您可能需要手动执行此操作。 Xc4可能自动检测依赖关系,并在启用该选项的情况下为您构建和链接它 - 但它并不总是正确(这对于基本依赖关系很有用) 。

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

事实并非如此,国际海事组织。编译 C 系列语言时,您需要习惯指定要编译的文件和要链接的库。除非你想更具体地讨论这个批评......

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

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

In this case, you need to find the file (or image/library) which defines/exports -[NSString isIPAddress]. Then you would need to add that file to your compile phase (if it is a source file), or link the library to your final binary (if it is a library or object file). In addition to linking it to your app, you will also need to compile and or link it into your unit test executable.

I know RestKit is 'installed' correctly into my project because when I do #import the project builds just fine.

#importing will not necessarily link or compile all of the necessary dependencies. You may have to do this manually. Xc4 may detect the dependency automatically, and build and link it for you if the option is enabled -- but it does not always get it right (it's good for basic dependencies).

Why is dependency management for obj-c projects such a pain?!

It's really not, IMO. Specifying files to compile and libraries to link with is something you'll need to get used to when compiling C family languages. Unless you want to be more specific about this criticism…

How are people managing dependencies like this?

Add the dependent projects to your Xcode projects. Configure them as build dependencies -- this will ensure they build before your app is built, and that the builds are up to date. For static libraries (targeting iOS), save the link stage for the final executables. In more complex scenarios, you will want to use xcconfig files in order to easily define build settings for any/all dependencies.

情话难免假 2024-12-30 09:43:12

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

CocoaPods 是一个非常强大且成熟的依赖关系管理工具,它可以管理库、它们所依赖的库(传递依赖项)以及编译器和标头标志。

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

One simple solution is to use cocoapods, which is good dependency management tool similar to maven in Java world.

CocoaPods is quite a powerful and maturing dependency management tool that can manage libraries, the libraries these depend on (transitive dependencies) as well as compiler and header flags.

It works by linking your project to another workspace that includes the libraries in source form, where the main target emits a static lib. This gives a good compromise between speed and being able to see the source-code.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文