Wie lade ich eine Datei herunter und speichere sie mit AFNetworking in das Dokumentenverzeichnis?

StackOverflow https://stackoverflow.com/questions/8372661

  •  27-10-2019
  •  | 
  •  

Frage

Ich benutze die AFNetworking -Bibliothek. Ich kann nicht herausfinden, wie man eine Datei herunterlädt und sie in das Dokumenteverzeichnis speichert.

War es hilfreich?

Lösung

NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"..."]];
AFHTTPRequestOperation *operation = [[[AFHTTPRequestOperation alloc] initWithRequest:request] autorelease];

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *path = [[paths objectAtIndex:0] stringByAppendingPathComponent:@"filename"];
operation.outputStream = [NSOutputStream outputStreamToFileAtPath:path append:NO];

[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
    NSLog(@"Successfully downloaded file to %@", path);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
    NSLog(@"Error: %@", error);
}];

[operation start];

Andere Tipps

Ich werde @Mattts Antwort abprallen und eine Version für Afnetworking 2.0 verwenden AFHTTPRequestOperationManager.

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *path = [[paths objectAtIndex:0] stringByAppendingPathComponent:@"filename"];

AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
AFHTTPRequestOperation *op = [manager GET:@"http://example.com/file/to/download" 
                               parameters:nil
    success:^(AFHTTPRequestOperation *operation, id responseObject) {
         NSLog(@"successful download to %@", path);
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
         NSLog(@"Error: %@", error);
    }];
op.outputStream = [NSOutputStream outputStreamToFileAtPath:path append:NO];

Ich rede von Afnetworking 2.0

[AFHTTPRequestOperationManager manager] Erstellt das Manager -Objekt mit Standard -AfjsonresponseSerializer und führt Inhaltstypen ein. Schau dir das an

- (BOOL)validateResponse:(NSHTTPURLResponse *)response
                    data:(NSData *)data
                   error:(NSError * __autoreleasing *)error

Daher müssen wir einen Serializer ohne Antwort erstellen und verwenden AFHTTPRequestOperationManager wie normal.

Hier ist der Afnoneresponializer

@interface AFNoneResponseSerializer : AFHTTPResponseSerializer

+ (instancetype)serializer;

@end

@implementation AFNoneResponseSerializer

#pragma mark - Initialization
+ (instancetype)serializer
{
    return [[self alloc] init];
}

- (instancetype)init
{
    self = [super init];

    return self;
}

#pragma mark - AFURLResponseSerializer
- (id)responseObjectForResponse:(NSURLResponse *)response
                           data:(NSData *)data
                          error:(NSError *__autoreleasing *)error

{
    return data;
}

@end

Verwendungszweck

self.manager = [AFHTTPRequestOperationManager manager];
self.manager.responseSerializer = [AFNoneResponseSerializer serializer];

[self.manager GET:@"https://sites.google.com/site/iphonesdktutorials/xml/Books.xml"
           parameters:parameters
              success:^(AFHTTPRequestOperation *operation, id responseObject)
    {
        if (success) {
            success(responseObject);
        }
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
        if (failure) {
            failure(error);
        }
    }];

Damit können wir die gesamte Datei ohne Serialisierung erhalten

Dokumentationsseite hat ein Beispiel mit Abschnitt "Erstellen einer Download -Aufgabe":

NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:configuration];

NSURL *URL = [NSURL URLWithString:@"http://example.com/download.zip"];
NSURLRequest *request = [NSURLRequest requestWithURL:URL];

NSURLSessionDownloadTask *downloadTask = [manager downloadTaskWithRequest:request progress:nil destination:^NSURL *(NSURL *targetPath, NSURLResponse *response) {
    NSURL *documentsDirectoryURL = [[NSFileManager defaultManager] URLForDirectory:NSDocumentDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:NO error:nil];
    return [documentsDirectoryURL URLByAppendingPathComponent:[response suggestedFilename]];
} completionHandler:^(NSURLResponse *response, NSURL *filePath, NSError *error) {
    NSLog(@"File downloaded to: %@", filePath);
}];
[downloadTask resume];

NB! Code funktioniert mit iOS 7+ (getestet mit AFNetworking 2.5.1)

Aus AFNetworking Dokumente. Speichern Sie in geladenen Dateien in Ihren Dokumenten. Afnetworking 3.0

NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:configuration];

NSURL *URL = [NSURL URLWithString:@"http://example.com/download.zip"];
NSURLRequest *request = [NSURLRequest requestWithURL:URL];

NSURLSessionDownloadTask *downloadTask = [manager downloadTaskWithRequest:request progress:nil destination:^NSURL *(NSURL *targetPath, NSURLResponse *response) {
    NSURL *documentsDirectoryURL = [[NSFileManager defaultManager] URLForDirectory:NSDocumentDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:NO error:nil];
    return [documentsDirectoryURL URLByAppendingPathComponent:[response suggestedFilename]];
} completionHandler:^(NSURLResponse *response, NSURL *filePath, NSError *error) {
    NSLog(@"File downloaded to: %@", filePath);
}];
[downloadTask resume];
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];

manager.responseSerializer = [AFCompoundResponseSerializer serializer];

manager.responseSerializer.acceptableContentTypes = [NSSet setWithObject:@"application/octet-stream"];

AFHTTPRequestOperation *operation = [manager GET:url   parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
    if (responseObject) {
        // your code here
    } else {
        // your code here
    }
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {

}];

[operation start];

// Manager.ResponSerializer.AcceptableContentTypes = [nsset setWithObject: @"Anwendung/Oktett-Stream"]; kann variieren, je nachdem, was Sie erwarten

Ja, es ist besser zu verwenden AFNetworking 2.0 Weg mit AFHTTPRequestOperationManager. Mit der alten Art und Weise wurde meine Datei heruntergeladen, aber aus irgendeinem Grund hat sich das Dateisystem nicht aktualisiert.

Anhänge an Swilliams Antwort, um den Download -Fortschritt zu zeigen, in AFNetworking 2.0 Sie tun es ähnlich - setzen Sie einfach den Download -Fortschrittsblock nach dem Einstellen des Ausgabestreams fest.

__weak SettingsTableViewController *weakSelf = self;

operation.outputStream = [NSOutputStream outputStreamToFileAtPath:newFilePath append:NO];

[operation setDownloadProgressBlock:^(NSUInteger bytesWritten, long long totalBytesWritten, long long totalBytesExpectedToRead) {

    float progress = totalBytesWritten / (float)totalBytesExpectedToRead;

    NSString *progressMessage = [NSString stringWithFormat:@"%@ \n %.2f %% \n %@ / %@", @"Downloading ...", progress * 100, [weakSelf fileSizeStringWithSize:totalBytesWritten], [weakSelf fileSizeStringWithSize:totalBytesExpectedToRead]];

    [SVProgressHUD showProgress:progress status:progressMessage];
}];

Dies ist meine Methode, um Bytes -Zeichenfolge zu erstellen:

- (NSString *)fileSizeStringWithSize:(long long)size
{
    NSString *sizeString;
    CGFloat f;

    if (size < 1024) {
        sizeString = [NSString stringWithFormat:@"%d %@", (int)size, @"bytes"];
    }
    else if ((size >= 1024)&&(size < (1024*1024))) {
        f = size / 1024.0f;
        sizeString = [NSString stringWithFormat:@"%.0f %@", f, @"Kb"];
    }
    else if (size >= (1024*1024)) {
        f = size / (1024.0f*1024.0f);
        sizeString = [NSString stringWithFormat:@"%.0f %@", f, @"Mb"];
    }

    return sizeString;
}

Zusätzlich zu den vorherigen Antworten habe ich mit AFNetworking 2.5.0 und iOS7/8 festgestellt, dass der zusätzliche Schritt zum Öffnen des Ausgabestreams auch erforderlich ist, um zu verhindern, dass die App hängt (und schließlich vom Mangel an Speicher abfällt).

operation.outputStream = [NSOutputStream outputStreamToFileAtPath:dest
                                                          append:NO];
[operation.outputStream open];
[operation start];
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top