我正在爲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