Cumulus 为 Objective C 提供了一个简单、低级的接口,通过创建、获取、更新和删除远程资源关联的 HTTP 请求方法来访问 REST 服务。它的使用非常简单,使得将 iOS 或 Mac 应用连接到 Web 服务变得非常简单。
Cumulus 从头开始设计就是为了使用 Grand Central Dispatch (GCD),允许大量并发——你可以多快、多宽地运行仅受硬件和系统限制。
设计上,Cumulus 只做一件事,而且是做得很好的:与应用程序与 REST 资源交互,并且自动编码/解码跨线传输的来自本机和通用类型的数据。由于这个原因,你可以将 Cumulus 放入任何系统中,它将填补这个角色,而不需要对其现有代码进行大量更改。它不提供任何类型的缓存或持久层,没有资源的高层接口,也没有 UI,但它通过广泛使用 blocks 非常易于集成,你可以在几分钟内连接到这些服务;在这种情况下,blocks 就像 UNIX 管道一样用于连接不同的工具。由于 Cumulus 非常容易集成,因此它是构建更高层框架的绝佳基础。
Cumulus 还被创建成一个令人愉悦的使用体验。主要接口都是通过 blocks 实现的,因此你可以忘记编写千种委托协议的实现或添加指针——只需在您想要它们的地方定义意图并享受剩下的时间和空间。所有用于公共接口的 blocks 都是类型的,因此您可以一次定义并重复使用它们,如果方便的话。
配置 Cumulus,实际上,您根本不需要配置 Cumulus。您只需为要使用的每个服务设置一个基本资源,嵌套资源将自动从它们父级继承信息。您也不需要配置任何内容来创建嵌套资源。通过传递对象、格式字符串和参数到任何资源,您可以创建一个可供使用的子资源。如果需要,您可以在子资源中覆盖任何继承的设置。
Cumulus 为您处理最常见的用例,但提供了定义良好的接口,使您能够轻松扩展其功能。存在身份验证协议,允许您将任何类型的身份验证系统集成进来,以及用于处理 MIME 类型的协议,使您能够将资源序列化/反序列化到任何类型的编码。
Cumulus 使用了自动引用计数(ARC)。它需要 iOS 6 或更高版本和/或 Mac OS 10.8 或更高版本。
在您的项目中使用 Cumulus 最简单的方法是在 CocoaPods 的 Podfile 中包含 pod 'Cumulus'
。确保您的目标是 iOS 6 和/或 OS X 10.8(例如 platform :ios, '6.0'
)。
在 Xcode 项目中使用 Cumulus 最低技术的方法是仅仅将“源”中的文件复制到您自己的项目中。
要跟踪 Cumulus 的开发分支,请将其设置为 git 子模块,并将项目拖入工作区,然后将其中的库 Cumulus.a(iOS)或 Cumulus.framework(Mac OS)添加到您的目标链接阶段。
如果您使用的是 Mac OS 框架,头文件会自动包含在您的头文件搜索路径中。为了在 iOS 中添加它们,请将 "${SRCROOT}/relative/path/to/Cumulus/Source" 添加到您的 HEADER_SEARCH_PATHS 构建设置,并勾选递归框。
在 Mac OS 上,您的源中将按如下方式导入 Cumulus:
#import <Cumulus/Cumulus.h>
在 iOS 上,使用
#import "Cumulus.h"
确保链接了 Security 框架(处理证书基于身份验证)和 MobileCoreServices 框架(iOS);或者对于 Mac OS 是 CoreServices 框架。
您必须使用 -ObjC 链接器标志(至少——如果您希望更加积极,还可以使用 -force_load="${BUILT_PRODUCTS_DIR}/libCumulus.a" 或 -all_load)以链接 Cumulus 中定义的类别。
如果您打算运行测试,请确保使用 git clone --recursive
获取存储库(或者如果您只是在将 Cumulus 添加为子模块,请使用 git submodule update --recursive
)以确保检索 Cumulus 的外部依赖项,因为这些是运行 spec 的必需项。
以上就是全部内容了。如果您需要有关如何设置工作区的更多信息,请参阅 Cumulus 编程指南。
使用 Cumulus 的最常见方法是设置一个基础资源和一些子资源,定义几个块,并开始进行请求。
CMResource *site = [CMResource withURL:@"http://example.com"];
site.timeout = 20;
[site setValue:@"foo" forHeaderField:@"X-MyCustomHeader"];
site.contentType = CMContentTypeJSON;
site.username = @"foo";
site.password = @"bar";
通常,您会将其存储在可以从您的应用程序的任何地方访问的地方,比如您的应用程序代理或上下文对象。
获取东西
CMResource *posts = [site resource:@"posts"];
[posts getWithCompletionBlock:^(CMResponse *response) {
postsController.posts = response.result;
}];
[posts getWithCompletionBlock:^(CMResponse *response) {
recentPostsController.posts = response.result;
} query:[NSDictionary dictionaryWithObject:@"today" forKey:@"postDate"]];
创建东西
CMProgressBlock postProgressBlock = ^(CMProgressInfo *progressInfo) {
postProgressView.progress = [progressInfo.progress floatValue];
};
NSDictionary *postData = ...;
CMResource *firstPost = [posts resource:@(1)];
[firstPost post:postData withProgressBlock:postProgressBlock completionBlock:^(CMResponse *response) {
if (response.wasSuccessful) {
[postsController addPost:postData];
}
}];
映射东西
CMResource *user123 = [site resourceWithFormat:@"users/%@",@(123)];
__block MyUserClass *user;
[user123 getWithCompletionBlock:^(CMResponse *response) {
if (response.wasSuccessful) {
user = [MyUserClass withUserData:response.result];
}
}];
保护东西
CMResource *admin = [site resource:@"admin"];
admin.preflightBlock = ^(CMRequest * request){
if (NO == [accountController isAuthorized:request]) {
NSDictionary *userInfo = [NSDictionary dictionaryWithObject:@"You need to log in to see this" forKey:NSLocalizedDescriptionKey];
[errorReporter report:[NSError errorWithDomain:@"MyDomain" code:-1 userInfo:userInfo]];
return NO;
}
return YES;
};
直接将东西下载到磁盘
CMResource *images = [site resource:@"images"];
[images downloadWithProgressBlock:nil completionBlock:^(CMResponse *response) {
NSURL *downloadedFile = [(CMProgressInfo *)response.result tempFileURL];
// Move the file to where you want it
}
测试东西——甚至在您的服务准备好之前!
CMResource *posts = [site resource:@"posts.json"];
[posts setFixture:[NSArray arrayWithObjects:postOne,postTwo,nil] forHTTPMethod:kCumulusHTTPMethodGET];
[posts getWithCompletionBlock:^(CMResponse *response) {
postsController.posts = response.result;
}];
// the array from the fixture is turned into data and decoded & postprocessed normally into response.result
// You can even set your fixtures all in one place, or load them from a plist:
[Cumulus loadFixturesNamed:@"MyService"];
[Cumulus useFixtures:YES];
// now all resources will also check in with Cumulus to see if they have a fixture, yay!
使用块将一系列请求组合在一起
CMResourceContext *context = [CMResourceContext withName:@"Posts Context"];
[context performRequestsAndWait:^() {
CMResource *users = [site resource:@"users.json"];
CMResponse *users = [users get];
// Do something with users
CMResource *posts = [site resource:@"test/get/item"];
[posts getWithCompletionBlock:^(CMResponse *response) {
// Do something with posts
}];
} withCompletionBlock:^(BOOL success, NSSet *responses) {
NSLog(@"All my updates were %@",success ? @"successful" : @"not successful");
}];
在作用域对象释放时自动取消请求组
// PostsController.m
- (void) viewDidLoad {
CMResourceContext *context = [CMResourceContext withName:@"Posts Context"];
[context performRequests:^{
for (int i = 0; i < 10; i++) {
[[self.posts resource:@(i)] getWithCompletionBlock:...];
}
} inScope:self];
}
// When the posts controller deallocates, any requests still running will cancel automatically
// There is also a convenience category on NSObject that lets you scope requests directly on any object
[self performRequestsInScope:^{...}];
Cumulus 还具有更多功能,例如从磁盘上传、分块下载、OAuth2 和 S3 认证、请求自动排队和取消、请求自动并发优化以及在后台线程上的后处理(适用于在子上下文中进行 Core Data 映射)。有关更详细的示例,请参阅Cumulus 编程指南。
您可以通过在 Xcode 中运行“安装 Cumulus 文档”方案来安装 Cumulus Xcode 文档集。
Cumulus 采用BSD 许可协议发布。
Cumulus最初由John Clayton创建,并由他维护[email protected]
查看贡献者图表,了解所有为 Cumulus 规格工作的人。
欢迎提交补丁,拉取请求让我们大家都非常兴奋。
Cumulus 界面设计中的很多灵感来自 Ruby 的 rest-client
Cumulus 使用 Appledoc 生成 API 文档