测试已测试 | ✗ |
Lang语言 | Obj-CObjective C |
许可证 | MIT |
发布最后发布 | 2015年5月 |
由Alexey Belkevich维护。
依赖于 | |
ABMultiton | = 1.2.2 |
SCNetworkReachability | = 1.2.0 |
ABRequestManager是一个用于iOS/OS X的轻量级且可扩展的请求管理器。它只需要一个NSURLRequest(或NSMutableURLRequest)的实例。所有请求都存储在队列中。请求管理器从队列中取出头部请求并运行它。以此类推,直到队列为空。
在您的项目中安装Request Manager的推荐方式是通过CocoaPods。这很简单。只需将ABRequestManager
Pod添加到您的Podfile中
#import "NSURLRequest+RequestManager.h"
...
- ...
{
...
NSURLRequest *request = [NSURLRequest requestWithURL:someURL];
[request startWithCompleteBlock:^(NSHTTPURLResponse *response, id data)
{
// do some response routine
...
} failBlock:^(NSError *error)
{
// handle error
...
}];
...
}
注意使用
self
时的保留周期
#import "NSURLRequest+RequestManager.h"
...
- (...
{
...
NSURLRequest *request = [NSURLRequest requestWithURL:someURL];
[request startWithDelegate:self];
...
}
...
- (void)request:(NSURLRequest *)request didReceiveResponse:(id)response
{
// do some response routine
...
}
...
- (void)request:(NSURLRequest *)request didReceiveError:(NSError *)error
{
// handle error
...
}
...
请求代理不会被请求管理器保留。这意味着如果您不确定请求在代理释放之前是否完成,则必须取消请求
如果需要异步解析接收到的数据,请使用使用解析块启动
。以下为JSON响应解析的示例
...
NSURLRequest *request = [NSURLRequest requestWithURL:someURL];
[request startWithCompletedBlock:^(NSHTTPURLResponse *response, id result)
{
// do something with parse JSON-object
...
} failedBlock:^(NSError *error)
{
// handle error
...
} parsingBlock:^id(NSData *data)
{
// parse data to JSON object
id response = [NSJSONSerialization JSONObjectWithData:data
options:NSJSONReadingMutableContainers
error:nil];
return response;
}];
与delegate
相同
...
NSURLRequest *request = [NSURLRequest requestWithURL:someURL];
[request startWithDelegate:self
parsingBlock:^id(NSData *data)
{
// parse data to JSON object
id response = [NSJSONSerialization JSONObjectWithData:data
options:NSJSONReadingMutableContainers
error:nil];
return response;
}];
所有在block中执行的操作都将运行在后台线程中!请尝试避免调用主线程的对象。否则,您应该同步调用
请求将从请求队列中删除。如果它在运行,连接将被断开
[request cancelRequest];
使用ABRequestFactory
创建请求很方便
ABRequestFactory *factory = [ABRequestFactory requestFactory];
NSMutableURLRequest *requestGET = [factory createGETRequest:path];
NSMutableURLRequest *requestPOST = [factory createPOSTRequest:path data:data];
NSMutableURLRequest *requestPUT = [factory createPUTRequest:path data:data];
NSMutableURLRequest *requestDELETE = [factory createDELETERequest:path];
NSMutableURLRequest *requestCustom = [factory createRequest:path method:@"custom_method" data:data];
如果要避免每次都实例化它,请使用
[ABRequestFactory sharedInstance]
使用自定义选项创建请求:基本主机路径、请求超时时间、是否处理cookies、缓存策略、HTTP头
ABRequestFactory *factory = [ABRequestFactory requestFactory];
factory.options.basePath = @"https://api.my-service.com/";
factory.options.timeout = 30.f;
factory.cookies = NO;
factory.cache = NSURLRequestReturnCacheDataDontLoad;
factory.headers = @{@"Content-Type", @"application/json"};
NSMutableURLRequest *request = [factory createGETRequest:@"news"]
默认的
ABRequestFactory
选项与默认的NSURLRequest
选项相同
以下是 ABRequestManager
的一些高级功能
在 请求管理器 中,每个请求都被包装在 ABRequestWrapper
中。有时使用包装器而不是原始请求会更好。
ABRequestWrapper *wrapper = [[ABRequestWrapper alloc] initWithURLRequest:request];
// set completed and failed blocks
[wrapper setCompletedBlock:^(ABRequestWrapper *wrapper, id result)
{
// do some completion actions
...
} failedBlock:^(ABRequestWrapper *wrapper)
{
// show error
...
}];
// set parsing block
[wrapper setParsingBlock:^id(ABRequestWrapper *wrapper)
{
id result = nil;
// do parsing
...
return result;
}];
您不仅限于只有一个 sharedInstance
。您可以使用 ABRequestManager
的自定义实例。但在这种情况下,您应该使用 ABRequestWrapper
而不是 NSMutableURLRequest
ABRequestManager *manager = [[ABRequestManager alloc] init];
ABRequestWrapper *wrapper = [[ABRequestWrapper alloc] initWithURLRequest:request];
[wrapper setCompletedBlock:^(ABRequestWrapper *wrapper, id result)
{
MyModel *model = [[MyModel alloc] initWithData:wrapper.data];
[self updateViewWithModel:model];
} failedBlock:^(ABRequestWrapper *wrapper)
{
[UIAlertView showError:wrapper.error.localizedDescription];
}];
[manager addRequestWrapper:wrapper];
这是一个复杂问题的简单解决方案的示例。想象一下,应用程序需要通过令牌访问API。当令牌过期时,它返回HTTP状态码 401。如果应用程序收到这个代码,它应该发送 '获取访问令牌' 请求,然后重试最后一个请求。
ABRequestWrapper *wrapper = [[ABRequestWrapper alloc] initWithURLRequest:request];
[wrapper setCompletedBlock:^(ABRequestWrapper *wrapper, id result)
{
if (wrapper.response.statusCode == 200)
{
// everything is OK, do something with result
...
}
else if (wrapper.response.statusCode == 401)
{
// send 'get access token'
ABRequestWrapper *getTokenWrapper= [self getAccessTokenRequestWrapper];
[[ABRequestManager sharedInstance] addRequestWrapperFirst:getTokenWrapper];
// retry current requeset
[[ABRequestManager sharedInstance] addRequestWrapper:wrapper];
}
else
{
// handle other status codes
...
}
} failedBlock:^(ABRequestWrapper *wrapper)
{
[UIAlertView showError:wrapper.error.localizedDescription];
}];
首先,您可以设置要检查可达性的主机。
...
{
...
[[ABRequestManager sharedInstance] setReachabilityCheckHost:@"https://api.myhost.com"];
...
}
...
默认可达性检查主机是 "www.google.com"
有时当互联网连接变得可用时重新启动未完成的请求可能会有用。但当主机不可达时,请求将从队列中删除。为了避免这种情况,您可以通过实现 ABRequestDelegate
的可选方法来重新启动请求。
- (void)requestWrapperDidBecomeUnreachable:(ABRequestWrapper *)wrapper
{
// restarting request
[[ABRequestManager sharedInstance] addRequestWrapperFirst:wrapper];
}
如果您不实现此方法,委托将在互联网连接丢失时接收到
requestWrapper:didFail:
通知
请关注 请求管理器 在 @okolodev 上的更新