NitroConnection 1.0.1

NitroConnection 1.0.1

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

Daniel L. Alves维护。



 
依赖
NitroMisc~> 1.0.1
NitroKeychain~> 1.0.0
 

NitroConnection是一个为iOS设计的非常快速、简单和轻量级的HTTP连接包装器,作为AFNetworking的替代方案。

NitroConnection专注于性能,以及程序员不应该为不需要的功能付费的事实。换句话说,您的代码不应该因为保持连接而损失性能或引起不必要的网络流量,因为这应该已经被取消。尽管如此,NitroConnection力求易于使用,并提供常见的功能,如燃烧和忘记请求。

不多说了

[TNTHttpConnection get: @"https://octodex.github.com/images/plumber.jpg"
            onDidStart: {
                // Show loading feedback
                // ....
            }
            onSuccess: ^( NSHTTPURLResponse *response, NSData *data ) {
                // Image downloaded! Do something with it
                // ...
            }
            onError: ^( NSError *error ) {
                // Damn! Let's show an error feedback =/
                // ...
            }];

现在让我们谈谈其他 NitroConnection 功能

  • OAuth 2(不使用刷新令牌)。
  • 线程安全。
  • HTTP方法GETHEADDELETEPOSTPUTPATCH
  • 易于配置查询字符串、请求体参数和头。
  • 全局、按连接和按请求配置缓存策略和超时间隔。
  • 其回调有两种形式:通过代理和通过块。
  • 单个 NitroConnection可用于发送任意数量的请求。
  • 简单的重试!只需调用... retryRequest
  • 所有请求都运行在主队列之外,因此应用程序界面保持尽可能快。回调块/代理方法在请求发起的队列上调用,因此可以轻松保持应用程序逻辑流。
  • 提供将请求设为托管或非托管的方式,让您更多地控制后台发生的事情。更多关于此的内容请见下文。

托管请求

托管请求使其连接在它们创建的作用域之外保持活动状态。因此,用户应该知道,如果他们不取消它们,它们将一直运行到失败或成功,在整个过程中将连接保留在内存中。这是所有语法糖方法的默认行为

// This request will run until it fails, succeeds or is canceled
[TNTHttpConnection post: @"mysite.com/api/news/mark-as-read" 
                 params: @{ @"news-id": @1872 }
               delegate: nil];

当然,如果您可能想要在完成之前取消托管请求,只需保留对其的引用即可

@interface SomeClass
{
    TNTHttpConnection *apiConnection;
}
@end

@implementation SomeClass

-( void )dealloc
{
    // This is needed to save resources and/or we don't care
    // if the request is canceled 
    [apiConnection cancel];
}

-( void )markNewsAsRead
{
    // This request will run until it fails, succeeds or is canceled
    apiConnection = [TNTHttpConnection post: @"mysite.com/api/news/analytics" 
                                     params: @{ @"news-id": @1872 }
                                   delegate: nil];
}

@end

或者,甚至更好,您可以使用非托管请求。

非托管请求

与托管请求相反,非托管请求不会保持其连接活跃,因此当它们被创建的作用域结束时,这些连接将被释放。也就是说,在分配之前,用户不需要调用cancelRequest来关闭一个运行非托管请求的连接。因此,用户必须保持对连接的强引用以保证其活跃。

//
// WARNING: This will not work as intended
//
@implementation NitroConnectionMisuseClass

-( void )loadMoreVideos
{
    // DON'T DO THIS! This connection may never complete its request since
    // it will be released at the end of the scope
    [TNTHttpConnection unmanagedGet: @"mysite.com/api/videos/load-more-like-this" 
                             params: @{ @"video-id": @900 }
                           delegate: self];
}

@end

//
// THE RIGHT WAY: This is the right way to do it
//
@interface DevWithGreatFutureClass< TNTHttpConnectionDelegate >
{
    TNTHttpConnection *apiConnection;
}
@end

@implementation DevWithGreatFutureClass

// Differently from managed requests, we need no dealloc implementation here

-( void )loadMoreVideos
{
    apiConnection = [TNTHttpConnection unmanagedPost: @"mysite.com/api/videos/load-more-like-this"
                                              params: @{ @"video-id": @900 }
                                            delegate: self];
}

@end

托管请求与非托管请求的比较

那么,您应该使用哪种请求呢?就像生活中的事物一样,这取决于具体情况。一般规则是

  • 托管:非常适合一触即发的请求。例如:ping一个推荐或分析API。
  • 非托管:适合与接口上下文有强关系的请求。例如:在一个搜索结果页面上,当用户向上滚动时,会获取更多结果。当用户离开该页面时,应该取消连接。毕竟,搜索结果不再需要了。

话虽如此,您可以只使用托管请求,只要您别忘了对不再需要的每个连接调用cancelRequest。除此之外,如果您打算对一个连接发出多个请求,并且这些请求类型混合,那么当连接不再需要时,您应该始终调用cancelRequest,因为跟踪您发出的最后一个请求的类型毫无意义。

深入一级

NitroConnection为您的代码提供许多语法糖方法,使代码看起来更优美,您真的应该使用它们。但是,如果您想要深入一级,或者想要使用同一TNTHttpConnection对象发出多个请求,这是可能的。

TNTHttpConnection *conn = [TNTHttpConnection new];
conn.timeoutInterval = 5.0;
conn.cachePolicy = NSURLRequestReloadIgnoringCacheData;

// A way of firing an unmanaged request
// We are not passing parameters just for the sake of simplicity
[conn startRequestWithMethod: TNTHttpMethodGet
                         url: @"google.com"
                 queryString: nil
                        body: nil
                     headers: nil
                     managed: NO
                  onDidStart: /* A block */
                   onSuccess: /* A block */
                     onError: /* A block */];

// Another way of firing a request, this time a managed one
conn.delegate = /* an object */;
NSURLRequest *request = /* request creation */;
[conn startRequest: request managed: YES];

正如我们之前所说,改变连接行为的,是它的当前请求。如果您不想混淆,不要在同一个连接对象中混合请求类型,或者当连接不再需要时,始终调用cancelRequest

OAuth 2

NitroConnection支持没有刷新令牌的OAuth 2。这个功能旨在透明地工作。让我们看看它的流程,但请记住,只有第一步会涉及您的工作。

  1. 在发出任何请求之前(例如在应用启动后不久是不错的选择)设置认证项。

    [TNTHttpConnection 
       authenticateServicesMatchingRegexString: @"^https://myservice\\.mysite\\.com/api/v1/.+"
                        usingRequestWithMethod: TNTHttpMethodPost
                                      tokenUrl: @"https://accounts.mysite.com/token"
                                   queryString: nil
                                          body: nil
                                       headers: nil
                                keychainItemId: @"com.mysite.accounts"
                       keychainItemAccessGroup: nil /* If you want to share this token with other
                                                       apps, set this parameter */
                           onInformCredentials: ^NSString *( NSURLRequest *originalRequest ) {
    
                               NSString* credentials = [NSString stringWithFormat: @"%@:%@", username, password];
                               return credentials;
    
                           } onParseTokenFromResponse: ^NSString *( NSURLRequest *originalRequest, 
                                                                    NSHTTPURLResponse *authenticationResponse, 
                                                                    NSData *data ) {
    
                               @try
                               {
                                   NSString *token = [[NSString alloc] initWithData: data encoding: NSUTF8StringEncoding];
                                   return token;
                               }
                               @catch( NSException *exception )
                               {
                                   // Log error
                                   // ...
    
                                   return nil;
                               }
    
                           } onAuthenticationError: ^BOOL( NSURLRequest *originalRequest, 
                                                           NSHTTPURLResponse *authenticationResponse, 
                                                           NSError *error ) {
    
                               // Log error
                               // ...
    
                               BOOL retry = false;
                               return retry;
                           }];

    我知道这是一个很长的方法调用,但您将会随着时间的推移开始喜欢它的简洁性。

  2. 之后,任何失败的带有401 HTTP错误码的请求,并且与认证项匹配的请求,将暂时挂起,直到获得认证令牌。

  3. 将发出认证令牌请求。该头将与其他您可能或可能没有设置的头部一起包含。

    @{ @"Authorization": @"Basic <credentials>" }
  4. 在获取令牌的同时,如果发出与相同的认证项匹配的其他请求(实际上可以是任意数量的请求),它们也将被挂起。

  5. 如果认证令牌请求...

    1. 成功,将在所有挂起的连接上调用retryRequest,并且
      它们仍然活跃。

      @{ @"Authorization" : @"Bearer <token>" }
    2. 失败,您将有机会重试认证令牌请求或放弃。如果您...

      1. 放弃,所有依然活跃的挂起连接将会有它们的代理错误回调/错误块被调用,就像没有认证过程一样。

      2. 想要重试,您将回到第三步。

  6. 当令牌过期时,您将回到步骤2。

如您所见,除了设置身份验证项目外,您不需要做更多的事情。您只需像以前一样使用 NitroConnection =D

NitroConnection 自动为您处理 HTTPS 身份验证挑战:身份验证令牌 url 和与身份验证项正则表达式匹配的所有 url 都将被信任。

有关 OAuth 2HTTP 基本身份验证 的更多信息,请参阅

需求

iOS 6.0 或更高版本,仅限于 ARC

安装

NitroConnection 可以通过 CocoaPods 获得。要安装它,只需将以下行添加到您的 Podfile 中

pod 'NitroConnection'

作者

许可

NitroConnection 在 MIT 许可下可用。有关更多信息,请参阅 LICENSE 文件。