NSArray с несколькими вложенными запросами - PullRequest
1 голос
/ 21 мая 2011

У меня есть приложение, которое использует segmentedControl.Первый элемент - это элемент «Все», где остальное создается из массива на основе результатов веб-службы.Когда выбрано «Все», я хочу запросить все запросы.

Как я могу это сделать,

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 голосов
/ 21 мая 2011

Создание загрузчика

  1. Создание класса загрузчика с помощью NSURLConnection.
  2. Сохраните переменную-член с именем downloaderObjectId.
  3. Напишите метод делегата для этого объекта.Этот метод передает загруженные данные и downloaderObjectId обратно делегату.

В делегате.

  1. Создание нескольких объектов загрузчика (Согласно вашей необходимости) с уникальным значением для downloaderObjectId.

  2. Храните эти объекты в NSMutableDictionary

  3. Ключом для каждого объекта будет downloaderObjectId.так что когда метод делегата вызывается после загрузки, вы берете точный объект обратно из NSMutableDictionary с помощью этого ключа.

Основная точка.

  1. Каждый раз, когда вызывается делегат.Вы должны удалить объект из словаря (Объект, который завершил загрузку и вызвал его delgate. Вы можете идентифицировать этот объект по ключу downloaderObjectId, который он держит.)

  2. Затем проверьте счетсловаря.Если оно равно нулю, вы можете убедиться, что загрузка завершена.Таким образом, вы можете позвонить своему viewcontroller.

...