2013-02-25 4 views
8

Я знаю, что этот вопрос был задан вопрос много раз на SO, но я не смог заставить его работать в моем проекте ...IOS - Асинхронный NSURLConnection внутри NSOperation

Итак, я хочу подкласс NSOperation и сделать его загрузите файл, используя NSURLConnection. Каков правильный способ сделать это? вот мой код, который не работает: Во-первых, я добавляю все мои операции в цикле:

DownloadFileOperation *operation; 
NSOperationQueue *queue = [[NSOperationQueue alloc] init]; 
for (int i=0; i<10; i++) { 
operation = [[DownloadFileOperation alloc] init]; 
operation.urlString = pdfUrlString; 
[queue addOperation:operation]; 
operation = nil; } 

А вот мой подкласс:

@interface DownloadHandbookOperation : NSOperation <NSURLConnectionDelegate> 
{ 

} 

@property (strong, nonatomic) NSString *urlString; 

@end 


@implementation DownloadHandbookOperation 
{ 
    NSString *filePath; 
    NSFileHandle *file; 
    NSURLConnection * connection; 
} 

- (void)start 
{ 
    if (![NSThread isMainThread]) 
    { 
     [self performSelectorOnMainThread:@selector(start) withObject:nil waitUntilDone:NO]; 
     return; 
    } 

    NSURL *url = [[NSURL alloc] initWithString:[self.urlString stringByAddingPercentEscapesUsingEncoding: NSUTF8StringEncoding]]; 

    NSMutableURLRequest *req = [NSMutableURLRequest requestWithURL:url]; 
    [req addValue:@"Basic ***=" forHTTPHeaderField:@"Authorization"]; 
    connection = [[NSURLConnection alloc] initWithRequest:req delegate:self startImmediately:YES]; 

} 

- (void)connection:(NSURLConnection *)conn didReceiveResponse:(NSURLResponse *)response 
{ 
    NSString *filename = [[conn.originalRequest.URL absoluteString] lastPathComponent]; 
    filename = [filename stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; 

    filePath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0] stringByAppendingPathComponent:filename]; 
    [[NSFileManager defaultManager] createFileAtPath:filePath contents:nil attributes:nil]; 

    file = [NSFileHandle fileHandleForUpdatingAtPath:filePath] ; 
    if (file) 
    { 
     [file seekToEndOfFile]; 
    } 
    else 
     [self finish]; 
} 

- (void)connection:(NSURLConnection *)conn didReceiveData:(NSData *)data 
{ 
    if (file) { 
     [file seekToEndOfFile]; 
    } 
    [file writeData:data]; 
} 

- (void)connectionDidFinishLoading:(NSURLConnection *)conn 
{ 
    [file closeFile]; 
    [self finish]; 
} 

- (void)connection:(NSURLConnection *)conn didFailWithError:(NSError *)error 
{ 
    connection = nil; 

    [self finish]; 
} 

- (void)cancel 
{ 
    [super cancel]; 
    [connection cancel]; 
} 


- (void)finish 
{ 
    NSLog(@"operationfinished."); 
} 


@end 

Что я делаю неправильно ?

+0

Я думаю, 'NSURLConnection' должен вызываться из главного потока, это не делает что угодно, если вы вызываете из фонового потока ... И даже если он вызывается из основного потока, он по-прежнему на самом деле делает сетевое содержимое в фоновом режиме, а затем снова вызывает ваши функции делегата из основного потока ... – jjv360

+0

Правильно, так как можно Я заставляю выполнить NSOperation на основном потоке? – Oleg

+0

Попробуйте '[[NSOperationQueue mainQueue] addOperation: operation]' ... – jjv360

ответ

8

Вам необходимо правильно настроить работу для выполнения в качестве «параллельной работы»

Concurrency Programming Guide: Configuring Operations for Concurrent Execution

Вы должны вернуть isConcurrent = YES и правильно управлять другими государственными флагами, isExecuting и isFinished в податливой манере КВО.


Чтобы проиллюстрировать общую идею здесь пост от инженеров в импульсе, который описывает их решение с некоторыми легко следовать демо-код, который вы можете скачать и обзор.

Pulse Engineering Blog: Concurrent Downloads using NSOperationQueues **

Этот код также обрабатывает требование NSURLConnection запускается на нитку с активным runloop, гарантируя, что он запускает его в основном потоке.

(** ссылка теперь archive.org, я думаю, что импульс был приобретен и взял свой старый сайт вниз)

+0

Спасибо за ссылку, это помогло! – Oleg

+0

Спасибо за ответ :-) – Arkan

+0

ссылка сломана. :( – Suz

Смежные вопросы