具有多个嵌套请求的NSArray

时间:2011-05-21 09:23:55

标签: iphone objective-c nsurlconnection nsurlrequest

我有一个使用segmentedControl的应用。第一项是“全部”项,其余的是基于来自webservice的结果从数组创建的。选择“全部”时,我想请求所有请求。

我该怎么做呢,

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];
}
}

这是处理多个请求的方式:

#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并获取一个数组,其中包含来自所有请求的所有数据。

1 个答案:

答案 0 :(得分:0)

创建下载程序

  1. 使用NSURLConnection创建下载程序类。
  2. 保留名为downloaderObjectId的成员变量。
  3. 为此对象编写委托方法。此方法将下载的数据和downloaderObjectId传递回委托。
  4. 在代表中。

    1. 使用downloaderObjectId的唯一值创建多个下载器对象(根据您的需要)。

    2. 将这些对象存储在NSMutableDictionary

    3. 每个对象的键将是downloaderObjectId。因此,在下载后调用委托方法时,使用此密钥从NSMutableDictionary中取回确切的对象。
    4. 要点。

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

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