2011-05-21 48 views
1

我有一个应用程序,使用segmentedControl。第一项是一个“全部”项,其余的是根据webservice的结果从数组创建的。当选择“全部”时,我想请求所有请求。NSArray与多个嵌套请求

我怎么能去这,

NSArray *urls = [NSArray arrayWithObjects:@"http://service/group/1/", 
              @"http://service/group/2/", nil]; 

我想收集从电话到一个集合中的所有结果,并在一个UITableView显示它时选择了“全部”项并可能在viewDidLoad中。 对于其它段仅请求中的一个被发出,并用一个数组回调然后在使用:

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 

我试图看这个例子,用于从阵列发出请求MultipleDownloads

谢谢,

在我的viewController的方法来启动多重下载:

- (void)requestChildrenInBackground { 

queue = [[NSOperationQueue alloc] init]; 

//Todo remove hard coded and get from previous request respons 
NSArray *urls = [NSArray arrayWithObjects: @"http://service/1/children", 
       @"http://service/2/children", 
       @"http://service/3/children", nil]; 

NSLog(@"%@", urls);  
for (NSString * url in urls) 
{ 
    GetSchedule *operation = 
    [GetSchedule urlDownloaderWithUrlString:url]; 
    [queue addOperation:operation]; 
} 
} 

这是豪w多重请求得到处理:

#import "GetSchedule.h" 

#import "JSON.h" 
#import "Authentication.h" 
#import "AttendanceReportViewController.h" 

@interface GetSchedule() 

- (void)finish; 

@end 

@implementation GetSchedule 

@synthesize appDelegate; 

@synthesize username; 
@synthesize password; 
@synthesize authenticationString; 
@synthesize encodedLoginData; 
@synthesize schedulesArray; 

@synthesize url = _url; 
@synthesize statusCode = _statusCode; 
@synthesize data = _data; 
@synthesize error = _error; 
@synthesize isExecuting = _isExecuting; 
@synthesize isFinished = _isFinished; 

+ (id)urlDownloaderWithUrlString:(NSString *)urlString { 

NSURL * url = [NSURL URLWithString:urlString]; 
GetSchedule *operation = [[self alloc] initWithUrl:url]; 
return [operation autorelease]; 
} 

- (id)initWithUrl:(NSURL *)url { 

self = [super init]; 
if (self == nil) 
    return nil; 

_url = [url copy]; 
_isExecuting = NO; 
_isFinished = NO; 

return self; 
} 

- (void)dealloc 
{ 
[username release]; 
[password release]; 
[encodedLoginData release]; 

[_url release]; 
[_connection release]; 
[_data release]; 
[_error release]; 
[super dealloc]; 
} 

- (BOOL)isConcurrent 
{ 
return YES; 
} 

- (void)start 
{ 
if (![NSThread isMainThread]) 
{ 
    [self performSelectorOnMainThread:@selector(start) withObject:nil waitUntilDone:NO]; 
    return; 
} 
self.username = appDelegate.username; 
self.password = appDelegate.password; 

Authentication *auth = [[Authentication alloc] init]; 
authenticationString = (NSMutableString*)[@"" stringByAppendingFormat:@"%@:%@", username, password];  
self.encodedLoginData = [auth encodedAuthentication:authenticationString]; 
[auth release]; 

NSLog(@"operation for <%@> started.", _url); 

[self willChangeValueForKey:@"isExecuting"]; 
_isExecuting = YES; 
[self didChangeValueForKey:@"isExecuting"]; 

// Setup up the request with the url 
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] 
           initWithURL:_url]; 

[request setHTTPMethod:@"GET"]; 
[request setValue:[NSString stringWithFormat:@"Basic %@", encodedLoginData] forHTTPHeaderField:@"Authorization"]; 

_connection = [[NSURLConnection alloc] initWithRequest:request 
               delegate:self]; 
if (_connection == nil) 
    [self finish]; 
else { 
    _data = [[NSMutableData alloc] init]; 
} 

} 

    - (void)finish 
{ 
NSLog(@"operation for <%@> finished. " 
     @"status code: %d, error: %@, data size: %u", 
     _url, _statusCode, _error, [_data length]); 

[_connection release]; 
_connection = nil; 

[self willChangeValueForKey:@"isExecuting"]; 
[self willChangeValueForKey:@"isFinished"]; 

_isExecuting = NO; 
_isFinished = YES; 

[self didChangeValueForKey:@"isExecuting"]; 
[self didChangeValueForKey:@"isFinished"]; 
} 

#pragma mark - 
#pragma mark NSURLConnection delegate 

- (void)connection:(NSURLConnection *)connection 
didReceiveResponse:(NSURLResponse *)response 
{ 
//[_data release]; 
//_data = [[NSMutableData alloc] init]; 

[_data setLength:0]; 

NSHTTPURLResponse * httpResponse = (NSHTTPURLResponse *)response; 
_statusCode = [httpResponse statusCode]; 
} 

- (void)connection:(NSURLConnection *)connection 
didReceiveData:(NSData *)data 
{ 
[_data appendData:data]; 
} 

- (void)connectionDidFinishLoading:(NSURLConnection *)connection 
{ 
// Parse the responseData of json objects retrieved from the service 
SBJSON *parser = [[SBJSON alloc] init]; 

NSString *jsonString = [[NSString alloc] initWithData:_data encoding:NSUTF8StringEncoding]; 
NSDictionary *jsonData = [parser objectWithString:jsonString error:nil]; 
NSMutableArray *array = [jsonData objectForKey:@"Children"]; 

schedulesArray = [NSMutableArray array]; 
[schedulesArray addObject:array]; 

// Callback to AttendanceReportViewController that the responseData finished loading 
[attendanceReportViewController loadSchedule]; 

[self finish]; 

} 

- (void)connection:(NSURLConnection *)connection 
didFailWithError:(NSError *)error 
{ 
_error = [error copy]; 
[self finish]; 
} 

@end 

当收到所有数据时,我想回到我的ViewController并获取所有请求中的所有数据的数组。

+0

我推荐[ASIHTTPRequest](http://allseeing-i.com/ASIHTTPRequest/)lib,很容易用它排队多个请求。转到页面并选择如何使用它,然后搜索**使用队列**。 – 2011-05-21 09:28:50

+0

@Nick好的谢谢,但从这我可以创建一个队列,而不使用ASIHTTP。我并没有将请求作为附加结果添加到同一个集合中的问题。但是我想,从一开始就不使用** ASIHTTP **的时候,我的脑袋里冒出了一些水。我可能需要附加收到的数据,而不是为每个连接创建一个新的** NSData **实例。 – Silversnail 2011-05-21 09:43:27

+0

我刚刚建议使用ASIHTTP,因为它比NSURLConnections更易于使用。不过,合并结果应该不成问题,当调用委托方法requestFinished时,只需使用responseString,最终解析并填充模型。 – 2011-05-21 09:46:14

回答

0

创建一个下载

  1. 创建使用NSURLConnection的一个下载器类。
  2. 保留名为downloaderObjectId的成员变量。
  3. 为此对象编写委托方法。该方法将下载的数据和downloaderObjectId传回给委托。

在委托中。

  1. 与该downloaderObjectId独特的价值创建多个下载对象(根据你的ncessity)。

  2. 存放在的NSMutableDictionary

  3. 重点为每个对象,这些对象将被downloaderObjectId。以便下载后调用委托方法时,使用此项从NSMutableDictionary中取回确切的对象。

要点。

  1. 每次调用委托时。你应该从字典中删除对象(对象完成下载并调用他的delgate,你可以通过他保存的关键字downloaderObjectId来识别这个对象。)

  2. 然后检查字典的数量。如果它是零,你可以确保你的下载完成。所以你可以调用你的viewcontroller。