1 votes

Télécharger un fichier en utilisant Cocoa

Je veux télécharger un fichier dans le dossier de téléchargement. J'ai cherché sur Google et j'ai trouvé la classe NSURLDownload. J'ai lu la page dans le centre de développement et j'ai créé ce code (avec un peu de copier-coller) :

@implementation Downloader
@synthesize downloadResponse;

- (void)startDownloadingURL:(NSString*)downloadUrl destenation:(NSString*)destenation {
    // créer la requête
    NSURLRequest *theRequest=[NSURLRequest requestWithURL:[NSURL URLWithString:downloadUrl]
                                              cachePolicy:NSURLRequestUseProtocolCachePolicy
                                          timeoutInterval:60.0];
    // créer la connexion avec la requête
    // et commencer à charger les données
    NSURLDownload  *theDownload=[[NSURLDownload alloc] initWithRequest:theRequest
                                                              delegate:self];
    if (!theDownload) {
        NSLog(@"Le téléchargement n'a pas pu être effectué...");
    }
}

- (void)download:(NSURLDownload *)download decideDestinationWithSuggestedFilename:(NSString *)filename {
    NSString *destinationFilename;
    NSString *homeDirectory=NSHomeDirectory();

    destinationFilename=[[homeDirectory stringByAppendingPathComponent:@"Desktop"]
                         stringByAppendingPathComponent:filename];
    [download setDestination:destinationFilename allowOverwrite:NO];
}

- (void)download:(NSURLDownload *)download didFailWithError:(NSError *)error {
    // libérer la connexion
    [download release];

    // informer l'utilisateur
    NSLog(@"Échec du téléchargement ! Erreur - %@ %@",
          [error localizedDescription],
          [[error userInfo] objectForKey:NSErrorFailingURLStringKey]);
}

- (void)downloadDidFinish:(NSURLDownload *)download {
    // libérer la connexion
    [download release];

    // faire quelque chose avec les données
    NSLog(@"downloadDidFinish");
}

- (void)setDownloadResponse:(NSURLResponse *)aDownloadResponse {
    [aDownloadResponse retain];
    [downloadResponse release];
    downloadResponse = aDownloadResponse;
}

- (void)download:(NSURLDownload *)download didReceiveResponse:(NSURLResponse *)response {
    // réinitialiser la progression, cela peut être appelé plusieurs fois
    bytesReceived = 0;

    // retenir la réponse pour une utilisation ultérieure
    [self setDownloadResponse:response];
}

- (void)download:(NSURLDownload *)download didReceiveDataOfLength:(unsigned)length {
    long long expectedLength = [[self downloadResponse] expectedContentLength];

    bytesReceived = bytesReceived+length;

    if (expectedLength != NSURLResponseUnknownLength) {
        percentComplete = (bytesReceived/(float)expectedLength)*100.0;
        NSLog(@"Pour cent - %f",percentComplete);
    } else {
        NSLog(@"Octets reçus - %d",bytesReceived);
    }
}

-(NSURLRequest *)download:(NSURLDownload *)download
          willSendRequest:(NSURLRequest *)request
         redirectResponse:(NSURLResponse *)redirectResponse {
    NSURLRequest *newRequest=request;
    if (redirectResponse) {
        newRequest=nil;
    }
    return newRequest;
}
@end

Mais mon problème est maintenant, il n'apparaît pas sur le bureau comme spécifié. Et je veux le mettre dans les téléchargements et pas sur le bureau... Que dois-je faire ?

MODIFIER : Dernier stack :

#0  0x92169ed7 in objc_msgSend
#1  0x01390090 in ??
#2  0x90443107 in URLDownload::didReceiveResponse
#3  0x903ecfc0 in URLConnectionClient::_clientSendDidReceiveResponse
#4  0x90465705 in URLConnectionClient::ClientConnectionEventQueue::processAllEventsAndConsumePayload
#5  0x904658b2 in URLConnectionClient::ClientConnectionEventQueue::processAllEventsAndConsumePayload
#6  0x903e0ace in URLConnectionClient::processEvents
#7  0x903e096f in MultiplexerSource::perform
#8  0x953df15b in __CFRunLoopDoSources0
#9  0x953dcc1f in __CFRunLoopRun
#10 0x953dc0f4 in CFRunLoopRunSpecific
#11 0x953dbf21 in CFRunLoopRunInMode
#12 0x96bc10fc in RunCurrentEventLoopInMode
#13 0x96bc0eb1 in ReceiveNextEventCommon
#14  0x96bc0d36 in BlockUntilNextEventMatchingListInMode
#15 0x9775d135 in _DPSNextEvent
#16  0x9775c976 in -[NSApplication nextEventMatchingMask:untilDate:inMode:dequeue:]
#17  0x9771ebef in -[NSApplication run]
#18  0x97716c85 in NSApplicationMain
#19  0x00002628 in main at main.m:13

3voto

Ken Points 8074

Vous n'avez jamais utilisé cette chaîne de destination dans -startDownloadingURL:destination:. Apparemment, vous vouliez appeler -[NSURLDownload setDestination:allowOverwrite:].

-[NSFileManager URLsForDirectory:NSDownloadsDirectory inDomains:NSUserDomainMask] devrait vous aider à obtenir le répertoire de téléchargements. Je n'ai pas eu besoin d'utiliser cette méthode moi-même, et je pense que la documentation indique qu'il n'est pas garanti qu'il y ait effectivement un répertoire au retour de la méthode. Vous avez donc besoin d'un plan de secours pour ce cas.

2voto

RecursivelyIronic Points 251

1voto

Peter Hosey Points 66275
#0  0x92169ed7 in objc_msgSend
#1  0x01390090 in ??
#2  0x90443107 in URLDownload::didReceiveResponse

Il semble que vous n'ayez pas conservé votre téléchargeur, donc il est mort et le téléchargement a ensuite envoyé un message de délégué à votre objet téléchargeur mort.

Assurez-vous que quelque chose continue de posséder le téléchargeur aussi longtemps qu'il a besoin de télécharger quelque chose. Vous pouvez utiliser l’instrument ObjectAlloc d’Instruments pour suivre la création, les rétentions, et les libérations du téléchargeur, pour voir lesquelles des libérations vous ne devriez pas faire.

N'oubliez pas de lire ou relire les documents sur la gestion de la mémoire (récemment réécrits), pendant que vous y êtes.

0voto

user3539639 Points 1

J'espère que cela fonctionnera, cela fonctionne pour moi :

-(void)createDownloadContentService:(NSURL *)url{
    NSLog(@"URL : %@",url);
    NSString *tempFilePath = //Donnez le chemin du répertoire, assurez-vous qu'il existe et donnez également le nom du fichier, par exemple /Bureau/téléchargement/nomfichier.zip//;
    NSFileManager *fileManager = [NSFileManager defaultManager];
    if ([fileManager fileExistsAtPath:tempFilePath]) {
             //Non nécessaire si vous ne voulez pas reprendre//
        NSURLDownload *download = [[NSURLDownload alloc] initWithResumeData:resumeData delegate:self path:tempFilePath];
        [download setDeletesFileUponFailure:NO];
        [download setDestination:tempFilePath allowOverwrite:YES];
    }else{
        NSURLDownload *download = [[NSURLDownload alloc] initWithRequest:[NSURLRequest requestWithURL:url] delegate:self];
        [download setDeletesFileUponFailure:NO];
        [download setDestination:tempFilePath allowOverwrite:YES];
    }
}

implémenter le délégué-----

- (void)downloadDidBegin:(NSURLDownload *)download{

}

- (void)download:(NSURLDownload *)download didReceiveResponse:(NSURLResponse *)response{
    _totalLength = response.expectedContentLength;
}

- (void)download:(NSURLDownload *)download willResumeWithResponse:(NSURLResponse *)response fromByte:(long long)startingByte{

}

- (void)download:(NSURLDownload *)download didReceiveDataOfLength:(NSUInteger)length{
    _recievedLength = _recievedLength + length;
}

- (void)downloadDidFinish:(NSURLDownload *)download{
    // Terminé, le fichier sera disponible//
}

- (void)download:(NSURLDownload *)download didFailWithError:(NSError *)error{
    NSLog(@"TÉLÉCHARGEMENT ÉCHOUÉ : %@",[error localizedDescription]);
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X