[英]How to batch request with AFNetworking 2?
So I'm rewriting an app for iOS 7 with AFNetworking 2.0 and I'm running into the issue of sending a batch of requests at once and tracking their progress. 因此,我正在使用AFNetworking 2.0重写iOS 7的应用程序,我遇到了一次发送一批请求并跟踪其进度的问题。 In the old AFNetworking there was the
enqueueBatchOfHTTPRequestOperations:progressBlock:completionBlock:
method on AFHTTPClient
, this is clearly refactored out and I'm a bit confused on how to enqueue multiple requests. 在旧AFNetworking存在的
enqueueBatchOfHTTPRequestOperations:progressBlock:completionBlock:
在方法AFHTTPClient
,这显然是重构出来,我就如何排队多个请求有点糊涂了。
I have created a subclass of AFHTTPSessionManager
and I'm using the POST:...
and GET:...
methods to communicate with the server. 我已经创建了
AFHTTPSessionManager
的子类,我正在使用POST:...
和GET:...
方法与服务器通信。 But I can't find anything in the code and/or docs to enqueue multiple requests at once like with the old AFHTTPClient
. 但我无法在代码和/或文档中找到任何内容,可以像使用旧的
AFHTTPClient
一样将多个请求排入AFHTTPClient
。
The only thing I can find is the undocumented batchOfRequestOperations:progressBlock:completionBlock:
method on AFURLConnectionOperation
, but that looks like the iOS 6 way of doing this. 我能找到的唯一的事情就是无证
batchOfRequestOperations:progressBlock:completionBlock:
在方法AFURLConnectionOperation
,但看起来像这样做的iOS 6的方式。
Clearly I'm missing something in the new NSURLSession
concept that I should use to batch requests or looking over a new AFNetworking feature. 显然,我在新的
NSURLSession
概念中遗漏了一些东西,我应该用它来批量请求或查看新的AFNetworking功能。 Hope someone can help me on the right track here! 希望有人能在这里帮助我走上正轨!
tl;dr: How can I send a batch of requests with my AFHTTPSessionManager
subclass? tl; dr:如何使用
AFHTTPSessionManager
子类发送一批请求?
Thanks Sendoa for the link to the GitHub issue where Mattt explains why this functionality is not working anymore. 感谢Sendoa获取GitHub问题的链接, 其中Mattt解释了为什么此功能不再起作用。 There is a clear reason why this isn't possible with the new
NSURLSession
structure; 有一个明确的原因,为什么新的
NSURLSession
结构无法做到这一点; Tasks just aren't operations, so the old way of using dependencies or batches of operations won't work. 任务不是操作,因此使用依赖关系或批量操作的旧方法将不起作用。
I've created this solution using a dispatch_group
that makes it possible to batch requests using NSURLSession
, here is the (pseudo-)code: 我使用
dispatch_group
创建了这个解决方案,可以使用NSURLSession
批处理请求,这里是(伪)代码:
// Create a dispatch group
dispatch_group_t group = dispatch_group_create();
for (int i = 0; i < 10; i++) {
// Enter the group for each request we create
dispatch_group_enter(group);
// Fire the request
[self GET:@"endpoint.json"
parameters:nil
success:^(NSURLSessionDataTask *task, id responseObject) {
// Leave the group as soon as the request succeeded
dispatch_group_leave(group);
}
failure:^(NSURLSessionDataTask *task, NSError *error) {
// Leave the group as soon as the request failed
dispatch_group_leave(group);
}];
}
// Here we wait for all the requests to finish
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
// Do whatever you need to do when all requests are finished
});
I want to look write something that makes this easier to do and discuss with Matt if this is something (when implemented nicely) that could be merged into AFNetworking. 我想看一些能让这更容易做的事情,并与Matt讨论,如果这是可以合并到AFNetworking的东西(当很好地实现时)。 In my opinion it would be great to do something like this with the library itself.
在我看来,用图书馆本身做这样的事情会很棒。 But I have to check when I have some spare time for that.
但我必须检查一下我有空闲时间。
Just updating the thread... I had the same problem and after some researches I found some good solutions, but I decided to stick with this one: 只是更新线程......我有同样的问题,经过一些研究后我发现了一些很好的解决方案,但我决定坚持这个:
I am using the project called Bolts . 我正在使用名为Bolts的项目。 So, for the same sample above posted by @Mac_Cain13, it would be:
因此,对于@ Mac_Cain13发布的上述相同示例,它将是:
[[BFTask taskWithResult:nil] continueWithBlock:^id(BFTask *task) {
BFTask *task = [BFTask taskWithResult:nil];
for (int i = 0; i < 10; i++) {
task = [task continueWithBlock:^id(BFTask *task) {
return [self executeEndPointAsync];
}];
}
return task;
}] continueWithBlock:^id(BFTask *task) {
// Everything was executed.
return nil;
}];;
- (BFTask *) executeEndPointAsync {
BFTaskCompletionSource *task = [BFTaskCompletionSource taskCompletionSource];
[self GET:@"endpoint.json" parameters:nil
success:^(NSURLSessionDataTask *task, id responseObject) {
[task setResult:responseObject];
}
failure:^(NSURLSessionDataTask *task, NSError *error) {
[task setError:error];
}];
}];
return task.task;
}
Basically, it's stacking all of the tasks, waiting and unwrapping until there is no more tasks, and after everything is completed the last completion block is executed. 基本上,它正在堆叠所有任务,等待和解包,直到没有更多任务,并且在完成所有任务之后,执行最后一个完成块。
Another project that does the same thing is RXPromise, but for me the code in Bolts was more clear. 另一个做同样事情的项目是RXPromise,但对我来说, Bolts中的代码更清晰。
For request
which can be post
or get
, you can use AFNetworking 2.0
for batch operation as firstly you need to create operation like this: 对于可以
post
或get
request
,您可以使用AFNetworking 2.0
进行批量操作,因为首先您需要创建如下操作:
//Request 1
NSString *strURL = [NSString stringWithFormat:@"your url here"];
NSLog(@"scheduleurl : %@",strURL);
NSDictionary *dictParameters = your parameters here
NSMutableURLRequest *request = [[AFHTTPRequestSerializer serializer] requestWithMethod:@"POST" URLString:strURL parameters:dictParameters error: nil];
AFHTTPRequestOperation *operationOne = [[AFHTTPRequestOperation alloc] initWithRequest:request];
operationOne = [AFHTTPResponseSerializer serializer];
[operationOne setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject)
{
//do something on completion
}
failure:^(AFHTTPRequestOperation *operation, NSError *error)
{
NSLog(@"%@",[error description]);
}];
//Request 2
NSString *strURL1 = [NSString stringWithFormat:@"your url here"];
NSLog(@"scheduleurl : %@",strURL);
NSDictionary *dictParameters1 = your parameters here
NSMutableURLRequest *request1 = [[AFHTTPRequestSerializer serializer] requestWithMethod:@"POST" URLString:strURL1 parameters:dictParameters1 error: nil];
AFHTTPRequestOperation *operationTwo = [[AFHTTPRequestOperation alloc] initWithRequest:request1];
operationTwo = [AFHTTPResponseSerializer serializer];
[operationTwo setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject)
{
//do something on completion
}
failure:^(AFHTTPRequestOperation *operation, NSError *error)
{
NSLog(@"%@",[error description]);
}];
//Request more here if any
Now perform batch operation like this : 现在执行批量操作,如下所示:
//Batch operation
//Add all operation here
NSArray *operations = [AFURLConnectionOperation batchOfRequestOperations:@[operationOne,operationTwo] progressBlock:^(NSUInteger numberOfFinishedOperations, NSUInteger totalNumberOfOperations)
{
NSLog(@"%i of %i complete",numberOfFinishedOperations,totalNumberOfOperations);
//set progress here
yourProgressView.progress = (float)numberOfFinishedOperations/(float)totalNumberOfOperations;
} completionBlock:^(NSArray *operations)
{
NSLog(@"All operations in batch complete");
}];
[[NSOperationQueue mainQueue] addOperations:operations waitUntilFinished:NO];
在AFNetworking 2.0上, AFHTTPClient
已经在AFHTTPRequestOperationManager
和AFHTTPSessionManager
上进行了拆分,因此可能你可以从第一个具有operationQueue
属性开始。
Currently, NSURLSession
tasks are not suitable for the same kind of patterns request operations use. 目前,
NSURLSession
任务不适合同类模式请求操作使用。 See the answer from Mattt Thompson here regarding this issue. 请参阅从马特·汤普森的答案在这里就这个问题。
Direct answer: if you need dependencies or batches, you'll still need to use request operations. 直接回答:如果您需要依赖关系或批处理,您仍然需要使用请求操作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.