47

I'm new to Objective-C and I want to download a file from the web (if it was changed on the webserver) and save it locally so it can be used by my application.

Mainly I want to implement what wget --timestamp <url> does.

bogdan
  • 9,056
  • 10
  • 37
  • 42

6 Answers6

150

I'm not sure what wget is, but to get a file from the web and store it locally, you can use NSData:

NSString *stringURL = @"http://www.somewhere.com/thefile.png";
NSURL  *url = [NSURL URLWithString:stringURL];
NSData *urlData = [NSData dataWithContentsOfURL:url];
if ( urlData )
{
  NSArray       *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
  NSString  *documentsDirectory = [paths objectAtIndex:0];  

  NSString  *filePath = [NSString stringWithFormat:@"%@/%@", documentsDirectory,@"filename.png"];
  [urlData writeToFile:filePath atomically:YES];
}
Henning
  • 2,710
  • 2
  • 17
  • 16
17

NSURLSession introduced in iOS 7, is the recommended SDK way of downloading a file. No need to import 3rd party libraries.

NSURL *url = [NSURL URLWithString:@"http://www.something.com/file"];
NSURLRequest *downloadRequest = [NSURLRequest requestWithURL:url];
NSURLSessionConfiguration *sessionConfig = [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession *urlSession = [NSURLSession sessionWithConfiguration:sessionConfig delegate:self delegateQueue:nil];
self.downloadTask = [self.urlSession downloadTaskWithRequest:downloadRequest];
[self.downloadTask resume];

You can then use the NSURLSessionDownloadDelegate delegate methods to monitor errors, download completion, download progress etc... There are inline block completion handler callback methods too if you prefer. Apples docs explain when you need to use one over the other.

Have a read of these articles:

objc.io NSURLConnection to NSURLSession

URL Loading System Programming Guide

bandejapaisa
  • 26,576
  • 13
  • 94
  • 112
  • 1
    Will this work asynchromnously – Hari Swaminathan Apr 06 '16 at 05:24
  • It would be strange for a Network API not to work asynchronously. So yes, the NSURLSession API is highly asynchronous: https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/URLLoadingSystem/Articles/UsingNSURLSession.html – bandejapaisa May 12 '16 at 16:07
  • Handling the delegate part is annoying. – Cœur Nov 01 '17 at 02:14
  • Use `[NSURLSession downloadTaskWithRequest:completionHandler:]` to work with a completion handler instead of a delegate – Yoav Jun 05 '18 at 09:43
15

I would use an asynchronous access using a completion block.

This example saves the Google logo to the document directory of the device. (iOS 5+, OSX 10.7+)

NSString *documentDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
NSString *filePath = [documentDir stringByAppendingPathComponent:@"GoogleLogo.png"];

NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"https://www.google.com/images/srpr/logo11w.png"]];
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue currentQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
    if (error) {
        NSLog(@"Download Error:%@",error.description);
    }
    if (data) {
        [data writeToFile:filePath atomically:YES];
        NSLog(@"File is saved to %@",filePath);
    }
}];
Tibidabo
  • 21,461
  • 5
  • 90
  • 86
6

I think a much easier way is to use ASIHTTPRequest. Three lines of code can accomplish this:

ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request setDownloadDestinationPath:@"/path/to/my_file.txt"];
[request startSynchronous];

Link to Reference

UPDATE: I should mention that ASIHTTPRequest is no longer maintained. The author has specifically advised people to use other framework instead, like AFNetworking

pixelfreak
  • 17,714
  • 12
  • 90
  • 109
1

Sometime ago I implemented an easy to use "download manager" library: PTDownloadManager. You could give it a shot!

Ali
  • 1,396
  • 14
  • 37
0

There are so many ways:

  1. NSURL

  2. ASIHTTP

  3. libcurl

  4. easyget, a commercial one with powerful features.

Jorge Fuentes González
  • 11,568
  • 4
  • 44
  • 64
johnson
  • 11
  • 1
  • is ASIHTTP still supported somewhere? The website advises use of something else: http://allseeing-i.com/ASIHTTPRequest/ – Robert Jun 05 '13 at 13:48
  • 1
    No. Don't use ASIHTTP. For a high level tool use AFNetworking instead: https://github.com/AFNetworking/AFNetworking – GnarlyDog May 21 '14 at 23:00