Object-c / iOS:如何使用ASynchronous从URL获取数据?

时间:2010-12-22 02:09:52

标签: ios asynchronous nsurlconnection

我的朋友看到​​了我的代码,其中一部分是从URL获取plist数据

他告诉我不要使用Synchronous,Use Asynchronous

但我不知道如何以简单的方式进行异步

这是我在程序中使用的代码

NSURL *theURL =  [[NSURL alloc]initWithString:@"http://someurllink.php" ];
NSURLRequest *theRequest=[NSURLRequest requestWithURL:theURL
                                          cachePolicy:NSURLRequestUseProtocolCachePolicy
                                          timeoutInterval:60.0];
NSData *returnData = [NSURLConnection sendSynchronousRequest:theRequest returningResponse:nil error:nil]; 
NSString *listFile = [[NSString alloc] initWithData:returnData encoding:NSUTF8StringEncoding];   
self.plist = [listFile propertyList];
[self.tableView reloadData];
[listFile autorelease];

如何更改我的代码使用ASynchronous获取数据?

非常感谢所有回复和答案:)

2 个答案:

答案 0 :(得分:17)

简短回答:您可以使用

+ (NSURLConnection *)connectionWithRequest:(NSURLRequest *)request delegate:(id)delegate;

请参阅NSURLConnectionDelegate了解非正式委托协议(所有方法都是可选的)

答案很长

异步下载数据并不像同步方法那样简单。首先,您必须创建自己的数据容器,例如文件容器

//under documents folder/temp.xml
file = [[SomeUtils getDocumentsDirectory] stringByAppendingPathComponent:@"temp.xml"]
NSFileManager *fileManager = [NSFileManager defaultManager];
if(![fileManager fileExistsAtPath:file]) {
  [fileManager createFileAtPath:file contents:nil attributes:nil];
}

连接到服务器时:

[NSURLConnection connectionWithRequest:myRequest delegate:self];

您必须使用异步接收的数据填充容器:

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
  NSFileHandle *fileHandle = [NSFileHandle fileHandleForUpdatingAtPath:file];
  [fileHandle seekToEndOfFile];
  [fileHandle writeData:data];
  [fileHandle closeFile];
}

您必须使用以下方式管理遇到的错误:

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error 

如果要捕获服务器响应:

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSHTTPURLResponse *)response

连接完成加载时处理:

- (void)connectionDidFinishLoading:(NSURLConnection *)connection

答案 1 :(得分:0)

对于HTML源代码的异步提取,我建议您使用AFNetworking

1)然后继承AFHTTPCLient子类,例如:

//WebClientHelper.h
#import "AFHTTPClient.h"

@interface WebClientHelper : AFHTTPClient{

}

+(WebClientHelper *)sharedClient;

@end

//WebClientHelper.m
#import "WebClientHelper.h"
#import "AFHTTPRequestOperation.h"

NSString *const gWebBaseURL = @"http://dummyBaseURL.com/";


@implementation WebClientHelper

+(WebClientHelper *)sharedClient
{
    static WebClientHelper * _sharedClient = nil;
    static dispatch_once_t oncePredicate;
    dispatch_once(&oncePredicate, ^{
        _sharedClient = [[self alloc] initWithBaseURL:[NSURL URLWithString:gWebBaseURL]];
    });

    return _sharedClient;
}

- (id)initWithBaseURL:(NSURL *)url
{
    self = [super initWithBaseURL:url];
    if (!self) {
        return nil;
    }

    [self registerHTTPOperationClass:[AFHTTPRequestOperation class]];
    return self;
}
@end

2)请求异步HTML源代码,将此代码放在任何相关部分

NSString *testNewsURL = @"http://whatever.com";
    NSURL *url = [NSURL URLWithString:testNewsURL];
    NSURLRequest *request  = [NSURLRequest requestWithURL:url];

    AFHTTPRequestOperation *operationHttp =
    [[WebClientHelper sharedClient] HTTPRequestOperationWithRequest:request success:^(AFHTTPRequestOperation *operation, id responseObject)
     {
         NSString *szResponse = [[[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding] autorelease];
         NSLog(@"Response: %@", szResponse );
     }
     failure:^(AFHTTPRequestOperation *operation, NSError *error)
     {
         NSLog(@"Operation Error: %@", error.localizedDescription);
     }];

    [[WebClientHelper sharedClient] enqueueHTTPRequestOperation:operationHttp];