我正在为iOS应用程序编写网络类。该课程负责所有日志记录和网络流量。我遇到了一个问题,我必须一次发送数千个请求,但是NSURLConnections会超时,因为直到所有NSURLConnections都启动后,才会调用委托方法,届时超时期限届满。我为Drupal使用了一个休息API,不幸的是,我不知道用一个请求创建多个实例的方法。我怎样才能同时发送回复呢?如果我使用GCD来关闭NSURLConnections的创建,那么是否可以解决问题?我想我必须通过遍历对象的整个操作来发送和发送给GCD,以释放主线程以回应响应。为什么NSURLConnection在发送很多请求时会超时?
-(BOOL)sendOperation:(NetworkOperation)op
NetworkDataType:(NetworkDataType)dataType
JsonToSend:(NSArray *)json
BackupData:(NSArray *)data
{
if(loggingMode)
{
return YES;
}
NSURLConnection *networkConnection;
NSData *send;
NSString *uuid = [self generateUUID];
NSMutableArray *connections = [[NSMutableArray alloc] init];
NSMutableURLRequest *networkRequest;
for (int i=0; i<[json count] && (data ? i<[data count] : YES); i++)
{
if(op == Login)
{
/*Grab all cookies from the server domain and delete them, this prevents login failure
because user was already logged in. Probably find a better solution like recovering
from the error*/
NSArray *cookies = [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookiesForURL:
[[NSURL alloc] initWithString:networkServerAddress]];
for (NSHTTPCookie *cookie in cookies)
{
[[NSHTTPCookieStorage sharedHTTPCookieStorage] deleteCookie:cookie];
}
networkRequest = [[NSMutableURLRequest alloc] initWithURL:
[NSURL URLWithString:[networkServerAddress stringByAppendingString:@"/user/login"]]];
}
else if(op == StartExperiment)
{
networkRequest = [[NSMutableURLRequest alloc] initWithURL:
[NSURL URLWithString:[networkServerAddress stringByAppendingString:@"/node"]]];
}
else if(op == Event || op == EndExperiment || op == SendAll)
{
networkRequest = [[NSMutableURLRequest alloc] initWithURL:
[NSURL URLWithString:[networkServerAddress stringByAppendingString:@"/node"]]];
}
else if(op == Logout)
{
networkRequest = [[NSMutableURLRequest alloc] initWithURL:
[NSURL URLWithString:[networkServerAddress stringByAppendingString:@"/user/logout"]]];
}
send = [[json objectAtIndex:i] dataUsingEncoding:NSUTF8StringEncoding];
//Set the headers appropriately
[networkRequest setHTTPMethod:@"POST"];
[networkRequest setValue:@"application/json"
forHTTPHeaderField: @"Content-type"];
[networkRequest setValue:[NSString stringWithFormat:@"%d", [send length]]
forHTTPHeaderField:@"Content-length"];
[networkRequest setValue:@"application/json"
forHTTPHeaderField:@"Accept"];
//Set the body to the json encoded string
[networkRequest setHTTPBody:send];
//Starts async request
networkConnection = [[NSURLConnection alloc] initWithRequest:networkRequest delegate:self];
//Successfully created, we are off
if(networkConnection)
{
[networkConnectionsAndData setValue:[[NSMutableArray alloc] initWithObjects:uuid,
[[NSNumber alloc] initWithInt:op], [[NSNumber alloc] initWithInt:dataType], [[NSMutableData alloc] init], (data ? [data objectAtIndex:i] : [NSNull null]), nil]
forKey:[networkConnection description]];
}
else //Failed to conn ect
{
NSLog(@"Failed to create NSURLConnection");
return NO;
}
}
[[self networkOperationAndConnections] setObject:[[NSMutableDictionary alloc] initWithObjectsAndKeys:[[NSMutableArray alloc] initWithObjects:connections, nil], @"connections", [[NSMutableArray alloc] init], @"errors", nil]
forKey:uuid];
return YES;
}
的词典是用于跟踪与每个NSURLConnection的所述相关数据的和也以组NSURLConnections在一起成为一个组,以确定整个操作的最终成功或失败。
更新
AFNetworking在完成这个项目的关键。它不仅大大清理了代码,还处理了发送这么多请求时继承的所有线程问题。更不用说AFNetworking,我可以将所有请求一起分批到一个操作中。像AFNetworking使用块一样,使用块是比NSURLConnections的标准代表更清洁和更好的解决方案。
我是初始化时的印象,它正在那里开始一个异步请求。所以它不是一个异步请求,除非你使用sendAsynchronousRequest?谢谢你们的快速响应。 – 2012-01-27 22:14:13
对不起,我在那里不是很清楚。这里是编辑: 我注意到你对“'//启动异步请求”的评论“,我想确保你意识到你的调用并不是你期望的典型”异步“功能。真的,它只是同步发射请求,但由于它的Web请求,它本质上表现为异步。您希望将这些请求实际放置在另一个线程上以实现完全异步行为。 – MechEthan 2012-01-30 17:27:05
添加链接到我见过的第三方库,可以帮助你在这里推荐 – MechEthan 2012-01-30 19:56:33