Object-c/iOS: как использовать ASynchronous для получения данных из URL?

Мой друг видел мой код, часть - получить данные plist из URL

И он сказал мне не использовать Synchronous, использовать ASynchronous

Но я не знаю, как сделать 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 для получения данных?

Большое спасибо за все ответы и ответы :)


person Webber Lai    schedule 22.12.2010    source источник
comment
работает, но подход устарел   -  person Daij-Djan    schedule 09.10.2013


Ответы (2)


Короткий ответ: вы можете использовать

+ (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
person Manny    schedule 22.12.2010
comment
Могу ли я задать еще один вопрос: что если я хочу получать данные plist по URL-ссылке каждые 3 секунды для перезагрузки, код, который я использую, будет вызван утечкой памяти? Или у вас есть какие-либо предложения? - person Webber Lai; 22.12.2010
comment
3 секунды — очень маленький интервал для непрерывной серверной транзакции. Зачем вам это нужно? Если вам нужно сделать это, вы можете сначала убедиться, что предыдущее соединение завершило загрузку первым, или сначала ОТМЕНИТЕ предыдущее соединение, прежде чем выполнять ту же транзакцию. - person Manny; 22.12.2010
comment
Я думаю, что делаю очень большую ошибку, каждые 3 секунды, чтобы сделать это, потому что мне нужно обновить представление с обновлением данных, теперь я меняю код следующим образом: - (void)refreshTheView{ NSURL *theURL = [[NSURL alloc ]initWithString:@theurllink.php]; NSArray *receivePlistData = [NSArray arrayWithContentsOfURL:plistURL];} - person Webber Lai; 24.12.2010

Для асинхронной загрузки исходного кода 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];
person X Sham    schedule 15.02.2013