Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to download files and save to local using AFNetworking 3.0?

In my project, I need to download a small video. In the previous version, I use this:

- (void)downloadFileURL:(NSString *)aUrl savePath:(NSString *)aSavePath fileName:(NSString *)aFileName tag:(NSInteger)aTag;

How can I do this in AFNetworking 3.0?

like image 953
KingStar Avatar asked Feb 01 '16 18:02

KingStar


2 Answers

This code:

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

Is on the README for the project: https://github.com/AFNetworking/AFNetworking

like image 152
Lou Franco Avatar answered Oct 20 '22 00:10

Lou Franco


I realise the original question is in Obj-C, but this comes up in a Google search, so for anyone else stumbling upon it and and needing the Swift version of @Lou Franco's answer, here it is:

let configuration = URLSessionConfiguration.default
let manager = AFURLSessionManager(sessionConfiguration: configuration)
let url = URL(string: "http://example.com/download.zip")! // TODO: Don't just force unwrap, handle nil case
let request = URLRequest(url: url)

let downloadTask = manager.downloadTask(
    with: request,
    progress: { (progress: Progress) in
                    print("Downloading... progress: \(String(describing: progress))")
                },

    destination: { (targetPath: URL, response: URLResponse) -> URL in
                    // TODO: Don't just force try, add a `catch` block
                    let documentsDirectoryURL = try! FileManager.default.url(for: .documentDirectory,
                                                                             in: .userDomainMask,
                                                                             appropriateFor: nil,
                                                                             create: false)

                    return documentsDirectoryURL.appendingPathComponent(response.suggestedFilename!) // TODO: Don't just force unwrap, handle nil case
                },

    completionHandler: { (response: URLResponse, filePath: URL?, error: Error?) in
                            print("File downloaded to \(String(describing: filePath))")
                        }
)

downloadTask.resume()

Couple of notes here:

  • This is Swift 3 / Swift 4
  • I added a progress closure as well (just a print statement). But of course it's totally fine to pass nil there as in the original example.
  • There are three places (marked with TODO:) with no error handling where things might fail. Obviously you should handle these errors, instead of just crashing.
like image 38
Nikolay Suvandzhiev Avatar answered Oct 20 '22 00:10

Nikolay Suvandzhiev