STNetTaskQueue 是一个用于 iOS 和 OS X 的网络队列库。它高度抽象,可以在不同的协议中实现。
STNetTaskQueue 避免您直接处理 "url"、"请求打包" 和 "响应解析"。所有网络任务都通过子类化 STNetTask 来描述和处理,这为您在 UI 层面上处理网络时提供了干净的代码风格。
STHTTPNetTaskQueueHandler 是 STNetTaskQueueHandler 的基于 HTTP 的实现。它提供了不同的方式来打包请求和解析响应,例如,STHTTPNetTaskRequestJSON 用于 JSON 格式的请求体,STHTTPNetTaskResponseJSON 用于 JSON 格式的响应数据,STHTTPNetTaskRequestFormData 用于表单数据格式的请求体,这在上传文件时最常用。
STNetTask 是抽象的,它为子类化提供基本属性和回调。
STNetTaskDelegate 是观察 STNetTask 结果的代理协议,通常用于视图中。
STNetTaskChain 是一个链,它会顺序地处理一个 STNetTask 数组。只有当链中的所有网络任务无错误结束时,才会认为网络任务链是成功的。
一个执行网络任务的序列或并发任务组。
platform :ios, '7.0'
pod 'STNetTaskQueue'
NSURL *baseUrl = [NSURL URLWithString:@"http://jsonplaceholder.typicode.com"];
STHTTPNetTaskQueueHandler *httpHandler = [[STHTTPNetTaskQueueHandler alloc] initWithBaseURL:baseUrl];
[STNetTaskQueue sharedQueue].handler = httpHandler;
@interface STTestPostNetTask : STHTTPNetTask
@property (nonatomic, strong) NSString *title;
@property (nonatomic, strong) NSString *body;
@property (nonatomic, strong) NSDate *date;
@property (nonatomic, assign) int userId;
@property (nonatomic, strong) NSString<STIgnore> *ignored; // This property is ignored when packing the request.
@property (nonatomic, strong, readonly) NSDictionary *post;
@end
@implementation STTestPostNetTask
- (STHTTPNetTaskMethod)method
{
return STHTTPNetTaskPost;
}
- (NSString *)uri
{
return @"posts";
}
// Optional. Retry 3 times after error occurs.
- (NSUInteger)maxRetryCount
{
return 3;
}
// Optional. Retry for all types of errors
- (BOOL)shouldRetryForError:(NSError *)error
{
return YES;
}
// Optional. Retry after 5 seconds.
- (NSTimeInterval)retryInterval
{
return 5;
}
// Optional. Custom headers.
- (NSDictionary *)headers
{
return @{ @"custom_header": @"value" };
}
// Optional. Add parameters which are not inclued in requestObject and net task properties.
- (NSDictionary *)parameters
{
return @{ @"other_parameter": @"value" };
}
// Optional. Transform value to a format you want.
- (id)transformValue:(id)value
{
if ([value isKindOfClass:[NSDate class]]) {
return @([value timeIntervalSince1970]);
}
return value;
}
- (void)didResponseDictionary:(NSDictionary *)dictionary
{
_post = dictionary;
}
@end
STTestPostNetTask *testPostTask = [STTestPostNetTask new];
testPostTask.title = @"Test Post Net Task Title";
testPostTask.body = @"Test Post Net Task Body";
testPostTask.userId = 1;
testPostTask.date = [NSDate new];
testPostTask.ignored = @"test";
[[STNetTaskQueue sharedQueue] addTaskDelegate:self uri:testPostTask.uri];
[[STNetTaskQueue sharedQueue] addTask:testPostTask];
// The net task will be sent as described below.
/*
URI: posts
Method: POST
Request Type: Key-Value String
Response Type: JSON
Custom Headers:
{
"custom_header" = value;
}
Parameters:
{
body = "Test Post Net Task Body";
date = "1452239110.829915";
"other_parameter" = value;
title = "Test Post Net Task Title";
"user_id" = 1;
}
*/
[testPostTask subscribeState:STNetTaskStateFinished usingBlock:^{
if (testPostTask.error) {
// Handle error cases
return;
}
// Access result from net task
}];
- (void)netTaskDidEnd:(STNetTask *)task
{
if (task.error) {
// Handle error cases
return;
}
// Access result from net task
}
[STNetTaskObserve(testPostTask) subscribeCompleted:^(
if (testPostTask.error) {
// Handle error cases
return;
}
// Access result from net task
}];
更详细的信息,请查看单元测试。
有时我们需要设置并发图像下载任务以避免同时产生太多数据。
STNetTaskQueue *downloadQueue = [STNetTaskQueue new];
downloadQueue.handler = [[STHTTPNetTaskQueueHandler alloc] initWithBaseURL:[NSURL URLWithString:@"http://example.com"]];
downloadQueue.maxConcurrentTasksCount = 2;
/*
[downloadQueue addTask:task1];
[downloadQueue addTask:task2];
[downloadQueue addTask:task3]; // task3 will be sent after task1 or task2 is finished.
*/
STNetTaskGroup 支持两种模式:STNetTaskGroupModeSerial 和 STNetTaskGroupConcurrent。STNetTaskGroupModeSerial 会在前一个网络任务完成后执行一个网络任务。STNetTaskGroupModeConcurrent 将并发执行所有网络任务。
STTestGetNetTask *task1 = [STTestGetNetTask new];
task1.id = 1;
STTestGetNetTask *task2 = [STTestGetNetTask new];
task2.id = 2;
STNetTaskGroup *group = [[STNetTaskGroup alloc] initWithTasks:@[ task1, task2 ] mode:STNetTaskGroupModeSerial];
[group subscribeState:STNetTaskGroupStateFinished usingBlock:^(STNetTaskGroup *group, NSError *error) {
if (error) {
// One of the net task is failed.
return;
}
// All net tasks are finished without error.
}];
[group start];
或者这是一种便捷的方法
STTestGetNetTask *task1 = [STTestGetNetTask new];
task1.id = 1;
STTestGetNetTask *task2 = [STTestGetNetTask new];
task2.id = 2;
[[[@[ task1, task2 ] serialNetTaskGroup] subscribeState:STNetTaskGroupStateFinished usingBlock:^(STNetTaskGroup *group, NSError *error) {
if (error) {
// One of the net task is failed.
return;
}
// All net tasks are finished without error.
}] start];