// // MassURLDataDownloader.m // SixToEight // // Created by Adam Wright on 14/07/2010. // Copyright 2010 Adam Wright. All rights reserved. // #import "MassURLDataDownloader.h" @implementation MassURLDataDownloader @synthesize delegate; - (id)init { return [self initWithURLSet:nil]; } - (id)initWithURLSet:(NSArray*)urls { self = [super init]; if (self) { if (urls) pendingURLs = [[NSMutableArray arrayWithArray:urls] retain]; else pendingURLs = [[NSMutableArray alloc] init]; obtainedData = [[NSMutableDictionary alloc] init]; complete = NO; cancel = NO; [self performSelectorInBackground:@selector(internalDoDownloading) withObject:nil]; } return self; } - (void)dealloc { cancel = YES; @synchronized (self) { [pendingURLs release]; [obtainedData release]; } [super dealloc]; } - (NSData*)scheduleDownloadOrReturnData:(NSURL*)url { @synchronized (self) { if ([obtainedData objectForKey:url] == nil) [pendingURLs addObject:url]; else return [obtainedData objectForKey:url]; if (complete) { complete = FALSE; [self performSelectorInBackground:@selector(internalDoDownloading) withObject:nil]; } } return nil; } - (NSData*)dataForURL:(NSURL*)url { @synchronized (self) { return [obtainedData objectForKey:url]; } } - (void)cancel { cancel = TRUE; } - (void)internalDoDownloading { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; while (true) { NSURL *nextURL = nil; @synchronized (self) { if ([pendingURLs count] > 0) { nextURL = [pendingURLs objectAtIndex:0]; [nextURL retain]; [pendingURLs removeObjectAtIndex:0]; } else { break; } } NSData *result = [NSData dataWithContentsOfURL:nextURL]; if (result) { @synchronized (self) { [obtainedData setObject:result forKey:nextURL]; } [self performSelectorOnMainThread:@selector(deliverNotification:) withObject:nextURL waitUntilDone:NO]; } [nextURL release]; } complete = YES; [pool release]; } - (void)deliverNotification:(NSURL*)url { id del = self.delegate; if (del && !cancel) { [del dataReady:[self dataForURL:url] fromURL:url forDownloader:self]; } } @end