具有多个嵌套请求的 NSArray

发布于 2024-11-09 00:29:06 字数 5266 浏览 0 评论 0原文

我有一个使用分段控件的应用程序。第一项是“全部”项,其余项是根据 Web 服务的结果从数组创建的。当选择“全部”时,我想请求所有请求。

我该如何解决这个问题,

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

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

-(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 并获取一个包含所有请求的所有数据的数组。

I have an app that uses a segmentedControl. First item is an "All" item, where the rest is created from an array based on result from webservice. When "All" is selected I want to request all the request.

How can I go about this,

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

I want to collect all result from the calls into a collection and display it in a UITableView when the "All" item is selected and probably in viewDidLoad.
For the other segments only one of the request is issued and callback with an array that then is used in:

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

I have tried to look at this example for making the request from the array MultipleDownloads

Thanks,

The method in my viewController to initiate the multiple download:

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

This is how the multiple request gets handled:

#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

When all data is received I want to call back to my ViewController and get an array with all data from all request made.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

仅此而已 2024-11-16 00:29:06

创建下载器

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

在委托中。

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

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

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

要点。

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

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

Create a downloader

  1. Create a downloader class using NSURLConnection.
  2. Keep a member variable called downloaderObjectId.
  3. Write a delegate method for this object. This method will pass the downloaded data and downloaderObjectId back to the delegate.

In the delegate.

  1. Create multiple downloader objects(As per your ncessity) with unique value for the downloaderObjectId.

  2. Store these objects in a NSMutableDictionary

  3. Key for each object will be downloaderObjectId. so that when the delegate method is called after download you take the exact object back from the NSMutableDictionary using this key.

Main point.

  1. Each time delegate is called. You should remove the object from dictionary(The object who is done with the download and called his delgate. You can identify this object by the key downloaderObjectId he holds. )

  2. Then check the count of dictionary. If it is zero you can make sure that your downloads are completed. So you can call your viewcontroller.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文