Voici un composant qui permet de télécharger des fichiers de manières asynchrone. L'avantage de cette méthode est, hormis une gestion plus précise des événements de téléchargement, de libérer du temps/machine pour faire autre chose pendant la session de téléchargement. Typiquement, l'ajout d'un progressView à ce composant est assez facile.

VSDownloadManager utilise NSURLConnection en mode asynchrone (et non NSURLDownload qui n'est pas implémenté sur l'iPhone).

Téléchargement des sources !

Exemple d'utilisation de VSDownloadManager

#import "VSDownloadManager.h"

....

....

- (void) downloadManagerDemo {

VSDownloadManager *downloadManager = [VSDownloadManager getInstance];

// set the delegate that will receive the "

[downloadManager setDelegate:self];

// Empty the current queue

[downloadManager clearItems];

// Adding an element to download

VSDownloadManagerItem *dwlItem = [[VSDownloadManagerItem alloc] initWithURL:@"http://blog.visuaweb.com/public/Images/springboard.jpeg" AndFile:@"/var/root/springboard.jpeg" AndText:nil];

[downloadManager addItem:dwlItem];

[dwlItem release];

// Addning an element to download

VSDownloadManagerItem *dwlItem = [[VSDownloadManagerItem alloc] initWithURL:@"http://blog.visuaweb.com/public/Files/snap_joe.jpg" AndFile:@"/var/root/joe.jpeg" AndText:nil];

[downloadManager addItem:dwlItem];

[dwlItem release];

// Start the download session

[downloadManager start];

}

- (void) VSDownloadManagerDidFinishedDownloadSession:(VSDownloadManager *) sender {

NSLog(@"Download session finiched!");

VSDownloadManager.h

//

//  VSDownloadManager.h

//

//  Created by Jeremie Engel on 28/12/07.

//  Copyright 2007 VISUAWEB - http://blog.visuaweb.com. All rights reserved.

//

#import <CoreFoundation/CoreFoundation.h>

#import <Foundation/Foundation.h>

@interface VSDownloadManagerItem : NSObject {

NSString*url;

NSString*filename;

NSString*text;

}

- (id) initWithURL:(NSString*) inURL AndFile:(NSString *) inFilename AndText:(NSString *) inText;

- (NSString *) url;

- (NSString *) filename;

- (NSString *) text;

@end

@interface VSDownloadManager : NSObject {

NSMutableArray*items;

VSDownloadManagerItem * currentItem;

iddelegate;

NSURLConnection*urlConnection;

NSMutableData*receivedData;

intstate;

}

+ (void) initialize;

+ (id) getInstance;

+ (id) allocWithZone:(NSZone *)zone;

- (id) init;

- (void) addItem:(VSDownloadManagerItem *) inItem ;

- (void) clearItems ;

- (void) setDelegate:(id) inDelegate ;

- (void) start ;

@end

VSDownloadManager.m

//

//  VSDownloadManager.m

//

//  Created by Jeremie Engel on 28/12/07.

//  Copyright 2007 VISUAWEB - http://blog.visuaweb.com. All rights reserved.

//

#import "VSLog.h"

#import "VSDownloadManager.h"

@implementation VSDownloadManagerItem

- (id) initWithURL:(NSString*) inURL AndFile:(NSString *) inFilename AndText:(NSString *) inText {

if ((self=[super init])) {

[inURL retain];

url = inURL;

[inFilename retain];

filename = inFilename;

if (inText) {

[inText retain] ;

text = inText;

}

return self;

}

return nil;

}

- (NSString*) url { return url; }

- (NSString*) filename { return filename; }

- (NSString*) text { return text; }

- (NSString *) description {

return url;

}

@end

/*****************************************************************************/

static VSDownloadManager  *defaultVSDownloadManager = nil;

@implementation VSDownloadManager

+ (void) initialize { }

+ (id) getInstance {

    @synchronized(self) {

        if (defaultVSDownloadManager == nil) {

            [[self alloc] init]; // assignment not done here

        }

    }

    returndefaultVSDownloadManager;

}

+ (id)allocWithZone:(NSZone *)zone

{

    @synchronized(self) {

        if (defaultVSDownloadManager == nil) {

            defaultVSDownloadManager = [super allocWithZone:zone];

            returndefaultVSDownloadManager// assignment and return on first allocation

        }

    }

    return nil; //on subsequent allocation attempts return nil

}

- (id) init {

NSLog(@"VSDownloadManager initialize");

if ((self=[super init])) {

items = [[NSMutableArray alloc] init];

//receivedData = [[NSMutableData data] retain];

}

returnself;

}

- (void) setDelegate:(id) inDelegate {

if (delegate) [delegate release];

[inDelegate retain];

delegate = inDelegate;

}

- (void) addItem:(VSDownloadManagerItem *) inItem {

if (![items containsObject:inItem]) [items addObject:inItem];

}

- (void) clearItems {

[items removeAllObjects];

}

- (void) start {

NSLog(@"Starting download");

int i;

for (i=0; i<[items count]; i++) {

state = 1;

receivedData = [[NSMutableData alloc] initWithLength: 0];

currentItem = [items objectAtIndex:i];

NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:[currentItem url]] cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:5];

urlConnection = [[NSURLConnection alloc] initWithRequest:request delegate:self];

while(state == 1) {

[[NSRunLoop currentRunLoop] runUntilDate: [NSDate dateWithTimeIntervalSinceNow: 0.1f] ];

}

}

if (delegate && [delegate respondsToSelector:@selector(VSDownloadManagerDidFinishedDownloadSession:)]) {

[delegate performSelector:@selector(VSDownloadManagerDidFinishedDownloadSession:) withObject: self];

}

}

/************** NSURLConnection Delegates *****************/

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {

[receivedData setLength:0];

}

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {

    [receivedData appendData:data];

}

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

    [receivedData release];

[connection release];

state = -1;

    NSLog(@"Connection failed! Error - %@ %@",

          [error localizedDescription],

          [[error userInfo] objectForKey:NSErrorFailingURLStringKey]);

}

- (void)connectionDidFinishLoading:(NSURLConnection *)connection {

if ([currentItem filename]) [[NSFileManager defaultManager] createFileAtPath:[currentItem filename]  contents:receivedData attributes:nil] ;

[connection release];

    [receivedData release];

state = 0;

NSLog(@"Download finished for %@", [currentItem url]);

}

/***********************************************************/

- (void) dealloc {

if (receivedData) [receivedData release];

if (urlConnection) [urlConnection release];

[items release];

[superdealloc];

}

@end