【问题标题】:NSArray with multiple nested requests具有多个嵌套请求的 NSArray
【发布时间】:2011-05-21 09:23:54
【问题描述】:

我有一个使用分段控件的应用程序。第一项是“全部”项,其余项是根据 Web 服务的结果从数组创建的。 When "All" is selected I want to request all the request.

我该怎么办呢,

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

我想将调用的所有结果收集到一个集合中,并在选择“All”项时将其显示在 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 并获取一个包含所有请求的所有数据的数组。

【问题讨论】:

  • 我推荐ASIHTTPRequest lib,它很容易将多个请求排队。转到页面并选择如何使用它,然后搜索使用队列
  • @Nick 好的,谢谢,但我可能可以在不使用 ASIHTTP 的情况下创建一个队列。对于将结果附加到同一个集合中的请求,我并没有真正的问题。但是我想当我从一开始就没有使用 ASIHTTP 时,我有点头晕目眩。我可能需要附加接收到的数据,而不是为每个连接创建一个新的 NSData 实例。
  • 我只是推荐了 ASIHTTP,因为它比 NSURLConnections 更容易使用。但是合并结果应该不是问题,当调用委托方法 requestFinished 时,只需使用 responseString,最终解析并填充您的模型。
  • @Nick 我发布了 som 代码以使我的问题更加清晰。我想在所有请求完成后回调我的 viewController,然后它可以获得一个包含所有响应数据的数组。
  • 回调检索时数组为空。但是我不能像以前那样将 viewController 传递给 GetSchedule 的类方法。

标签: iphone objective-c nsurlconnection nsurlrequest


【解决方案1】:

创建下载器

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

在委托中。

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

  2. 将这些对象存储在 NSMutableDictionary 中

  3. 每个对象的键都是 downloaderObjectId。这样当下载后调用委托方法时,您可以使用此键从 NSMutableDictionary 中取回确切的对象。

要点。

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

  2. 然后检查字典的计数。如果它为零,您可以确保您的下载已完成。所以你可以调用你的视图控制器。

【讨论】:

    猜你喜欢
    • 2017-05-28
    • 2016-05-24
    • 1970-01-01
    • 1970-01-01
    • 2019-05-07
    • 2018-12-11
    • 1970-01-01
    • 2014-11-26
    • 1970-01-01
    相关资源
    最近更新 更多