2013-02-25 14 views
8

So che questa domanda è stato chiesto molte volte su SO, ma non sono riuscito a farlo funzionare nel mio progetto ...iOS - Async NSURLConnection all'interno NSOperation

Quindi, voglio sottoclasse NSOperation e renderlo scarica un file usando NSURLConnection. Qual è il modo giusto per farlo? Ecco il mio codice che non funziona: In primo luogo, sto aggiungendo tutte le mie operazioni in un ciclo:

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

Ed ecco il mio sottoclasse:

@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 

Che cosa sto facendo di sbagliato ?

+0

penso 'NSURLConnection' deve essere chiamato dal thread principale, non fa qualsiasi cosa, se chiamata da un thread in background ... Anche se è chiamata dal thread principale, fa ancora effettivamente le cose in rete sullo sfondo, e quindi chiama nuovamente le funzioni delegate dal thread principale ... – jjv360

+0

Esatto, quindi come può Allora faccio funzionare NSOperation sul thread principale? – Oleg

+0

Provare '[[NSOperationQueue mainQueue] addOperation: operation]' ... – jjv360

risposta

8

è necessario configurare correttamente l'operazione da eseguire come un "mascherato"

Concurrency Programming Guide: Configuring Operations for Concurrent Execution

È necessario tornare isConcurrent = YES e correttamente gestire le altre bandiere statali, isExecuting e isFinished in modo conforme KVO.


per illustrare l'idea generale: ecco un post dal ingegneri a impulsi che descrive la loro soluzione con un po 'facile da seguire il codice demo è possibile scaricare e revisione.

Pulse Engineering Blog: Concurrent Downloads using NSOperationQueues **

Questo codice gestisce anche il requisito che NSURLConnection viene avviato su un filo con un runloop attivo garantendo che inizia sul filo principale.

(** collegamento è ora archive.org, penso impulso è stato acquistato e hanno preso il loro vecchio sito verso il basso)

+0

Grazie per il collegamento, ha aiutato! – Oleg

+0

Grazie per la risposta :-) – Arkan

+0

collegamento rotto. :( – Suz

Problemi correlati