BBHTTP 0.9.7

BBHTTP 0.9.7

测试已测试
语言语言 Obj-CObjective C
许可证 Apache 2
发布最后发布2014年12月

未指明 维护。



BBHTTP 0.9.7

  • 作者:
  • Bruno de Carvalho

BBHTTP 是用 Objective-C 编写的针对 libcurl 的丰富包装器。

这是一个仅适用于 ARC 的库,它使用 Clang 3.1 引入的特性。因此,它仅适用于 iOS 5+ 和 OSX 10.7+。

它拥有一个极其简单且紧凑的接口,允许您将发送 HTTP 请求的代码缩小到几行清晰的代码,同时如果您需要更多功能时,仍能提供全部的灵活性。

[[BBHTTPRequest getResource:@"http://foo.bar/baz"] execute:^(BBHTTPResponse* r) {
     NSLog(@"Finished: %u %@ -- received %u bytes of '%@'.",
           r.code, r.message, r.contentSize, r[@"Content-Type"]);
 } error:^(NSError* e) {
     NSLog(@"Request failed: %@", [e localizedDescription]);
 }];

// Finished: 200 OK -- received 68364 bytes of 'text/html'.

目前还有很多需要磨光的边缘,需要修复的错误以及缺少的功能,才能使其与其他类似项目相匹敌。我计划逐步添加这些功能,但总是欢迎帮助,因此请务必为功能打开问题,或在我的 Twitter 上发表评论 @biasedbit

API 很可能在此达到 1.0 之前继续变化。

亮点

  • 简洁的异步驱动使用

    [[BBHTTPRequest deleteResource:@"http://foo.bar/baz/1"] execute:^(BBHTTPResponse* r) {
        // handle response
    } error:nil]];

    您甚至不需要保留对请求的引用,只需发射并忘记。

  • 方便的常用模式

    [[BBHTTPRequest getResource:@"http://foo.bar/baz/1"] setup:^(id request) {
        // Prepare request...
    } execute:^(BBHTTPResponse* response) {
        // Handle response...
    } error:^(NSError* error) {
        // Handle error...
    } finally:^{
        // Do after error OR success.
    }];
    
    
    * Get JSON effortlessly:
    
    ```objc
    [[[BBHTTPRequest getResource:@"http://foo.bar/baz.json"] asJSON] execute:^(BBHTTPResponse* r) {
        NSLog(@"User email: %@", r.content[@"user.email"]);
        NSLog(@"# of followers: %@", r.content[@"user.followers.@count"]);
    } error:^(NSError* error) {
        // Handle request *or* JSON decoding error
    }];

    请注意,键路径运算符的行为与 valueForKeyPath: 相似,而不是 valueForKey:。这是因为会产生 NSDictionary 的 JSON 响应被包装在 BBJSONDictionary 中。有关收集运算符的更多信息,请参阅这里

    • 图像也如此
    [[BBHTTPRequest getResource:@"http://foo.bar/baz.png"] setup:^(id request) {
        [request downloadContentAsImage];
    } execute:^(BBHTTPResponse* response) {
        UIImage* image = response.content; // NSImage on OSX
        NSLog(@"image size: %@", NSStringFromCGSize(image.size));
    } error:nil];

    该示例使用 downloadContentAsImagesetup 块中设置图像下载和转换,但您也可以使用类似于上例 JSON 的流畅语法(asImage)。

    • NSInputStream 或直接从文件进行的流式上传
    [[BBHTTPRequest createResource:@"http://foo.bar/baz" withContentsOfFile:@"/path/to/file"]
     setup:^(BBHTTPRequest* request) {
         request[@"Extra-Header"] = @"something else";
     } execute:^(BBHTTPResponse* response) {
         // handle response
     } error:nil];

    请求的内容类型和内容长度标头将根据文件属性自动设置。

    • 将下载到内存缓冲区或直接流到文件/ NSOutputStream
    [[BBHTTPRequest getResource:@"http://foo.bar/baz"] setup:^(BBHTTPRequest* request) {
        [request downloadToFile:@"/path/to/file"];
    } execute:^(BBHTTPResponse* response) {
        // handle response
    } error:nil];

    如果下载在中间失败,无需删除文件;BBHTTP 会负责保持一切整洁。

    • 当需要更多控制时使用 power-dev API
    BBHTTPExecutor* twitterExecutor = [BBHTTPExecutor initWithId:@"twitter.com"];
    BBHTTPExecutor* facebookExecutor = [BBHTTPExecutor initWithId:@"facebook.com"];
    twitterExecutor.maxParallelRequests = 10;
    facebookExecutor.maxParallelRequests = 2;
    ...
    BBHTTPRequest* request = [[BBHTTPRequest alloc]
                              initWithURL:[NSURL URLWithString:@"http://twitter.com/resource"]
                              andVerb:@"GET"];
    
    request[@"Accept-Language"] = @"en-us";
    request.downloadProgressBlock = ^(NSUInteger current, NSUInteger total) { /* ... */ };
    request.finishBlock = ^(BBHTTPRequest* request) { /* ... */ };
    
    [twitterExecutor executeRequest:request];

    还有其他内置方法来处理响应内容。请务必阅读有关响应内容处理的详细指南

    可能待办事项列表

    • 多部分上传助手
    • 跟随重定向
    • 使用 curl 的多处理
    • 您的bright idea here

    要查看完整列表,请务必访问 路线图 维基页面。

    为什么?

    除了它的简洁API或它底层使用libcurl的事实吗?

    好吧,不同于 NSURLConnection 和,相应地,任何依赖它的库,BBHTTP...

    • 完全遵循RFC 2616的第8.2.3节,即令人不快的 Expect: 100-Continue 标头;
    • 可以在上传过程中接收服务器错误响应——而不是继续向套接字伊甸园泵送数据,并最终报告连接超时而不是服务器发送的实际错误响应。

    "但我的上传工作得很好..."

    • 如果你只编写了上传到服务器的代码,你可能从未注意到上述任一问题;
    • 如果你编写了客户端和服务器端代码来处理上传,那么你很可能从未遇到过上述情况的任一;
    • 如果你很认真,写了自己的服务器和客户端并且注意到 NSURLConnection 忽略错误直到上传完成,那么这就是适合你的HTTP框架。同时也是,为编写了服务器和客户端而拍手称好。并且注意到规范。

    更严肃地说,创建这个libcurl包装器的动机是在开发Droplr的API服务器时,我们注意到每当API拒绝上传并立即关闭连接——这是一个合法且合理的行为——基于Cocoa的客户端会继续报告上传进度(尽管我知道套接字已经被关闭),最终以 "请求超时" 失败,而不是服务器通过管道发送的响应。

    这意味着

    1. NSURLConnection 在发送请求体之前没有等待 100-Continue 的临时响应;
    2. NSURLConnection 在上传完所有数据后才意识到响应已经发送且连接正在死亡。《顽皮的混蛋,不是吗?》

    我确实提交了一个错误报告,但在等待了一年并得到回应后,我决定提出一个可行的替代方案。巧合的是,我开始公开这个库的那天,我收到了苹果的回复——将错误报告作为其他我无法访问的报告的副本关闭。

    用curl的命令行版本进行了一些快速测试后证明curl知道如何正确处理这些边缘情况,因此是时候为Cocoa构建一个新的HTTP框架。

    在这个过程中,产生了这个方便的构建脚本这个方便的构建脚本,所以即使你不打算使用这个库,但仍然对在iOS上运行curl感兴趣,也请查看它!

    依赖项

    • libcurl(以下阅读)
    • libz.dylib
    • Security框架
    • CoreServices框架 在OSX上,MobileCoreServices框架 在iOS上
    • AppKit框架 在OSX上,UIKit框架 在iOS上

    注意:您可以在 Build/iOS/Static lib/libcurlBuild/OSX/Static lib/libcurl 下找到 libcurl 7.29.1-DEV 的二进制文件和头文件。iOS 有两个版本,针对 6.1 SDK 编译。《libcurl.iOS.dev.a》支持 i386(模拟器),armv7 和 armv7s(iPhone 3GS 及以上),而《libcurl.iOS.appstore.a》仅支持 arm 架构——使其文件尺寸更小,因此更适合发布使用。OSX 版本针对 10.8 SDK 编译,支持 x86_64(64 位 Intel)。如果您想构建自己的定制版本,请尝试 这个。所有二进制文件都带有调试符号,因此虽然它们看起来很大,但最终文件大小会在 400~600KB。

    文档

    有关如何设置和使用此库的指南,请参阅 Wiki 页面

    项目还包括全面的类级别文档。如果您已经安装了 appledoc,只需在 Docs 文件夹上运行 generate 脚本,它将在 Docs/html 下创建 HTML 文档。

    致谢

    • Daniel Stenberg 以及所有参与 cURL 和 libcurl 开发的团队
    • Nick Zitzmann 为 Secure Transport TLS/SSL curl 插件
    • Ben Copsey 为 ASIHTTPRequest,这是我自 iOS 以来一直使用的 HTTP 工具

    许可

    BBHTTP 采用 Apache 软件许可证 2.0 版本授权

    取得联系

    我在 @biasedbit 上有 Twitter。我偶尔也会 写文章