Downloading Data using NSURLConnection in IOS using Objective-C

Downloading Data using NSURLConnection in IOS using Objective-C

There are several cases when you need to download an image from a specific url, so it is better that you know how to do it easily and effectively. Today I’m gonna show you how it can be achieved using NSURLConnection.

The case is that you downloaded and parsed your .json data and now you have a String of an url that you suppose to be displaying. How you do that? Well, surely you cannot set that string to be the image of your UIImageView, so you need to call that url and download it.

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

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

- (void)connectionDidFinishLoading:(NSURLConnection *)theConnection

Next lets define a couple of fields that we’ll use to store data and keep track of our connection.

NSMutableData* _dataResponse;
NSURLConnection* _connection;

Now lets get to the fun part. Once you have a url for downloading a chunk of data, you can create your NSURLConnection object:

_connection = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:NO];

The first parameter is your NSURLRequest, followed by the object that implemented the NSURLConnectionDelegate that I mentioned earlier.

In this instance i’m going to tell it not to start immediately. The reason for this is that i don’t want other threads to block it from downloading. What i mean by this, is that if you were doing anything else while it was downloading, it could actually stop the connection from downloading until you finished.

Since we created the connection, but have not told it to start yet, we need to manually tell it to begin downloading.

[_connection scheduleInRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];
[_connection start];

By scheduling it in the main loop, we make sure that it doesn’t get blocked.

So now that we’ve begun downloading, lets capture the data that is returned. That will happen in the following protocol method:

- (void)connection:(NSURLConnection *)theConnection didReceiveData:(NSData *)data
{
if (_dataResponse == nil)
_dataResponse = [[NSMutableData alloc] initWithCapacity:2048];

[_dataResponse appendData:data];
}

Depending on how large your file is, this method can get called multiple times until your file is fully downloaded. If you know the size of the file you’re downloading, this is a good place to insert a progress indicator code that you can show your users.

If we haven’t instantiated our NSMutableData object yet, we’ll go ahead and do that here, and then append any data we’ve downloaded.

During the download there could be an error thrown, for example if the user lost their internet connection. That should be handled in the following protocol method:

- (void)connection:(NSURLConnection *)theConnection didFailWithError:(NSError *)error
{
// Handle any error that occured.
}

Finally, when the download has completed the last method in our protocol will be invoked. At that point we can take our data and process it. For example, if it was JSON data, we could then use the NSJSONSerialization to load it:

- (void)connectionDidFinishLoading:(NSURLConnection *)theConnection
{
NSDictionary *results =[NSJSONSerialization JSONObjectWithData:_dataResponse options:kNilOptions error:nil];

_dataResponse = nil;

// Do Something with the json.
}

One last thing. If for some reason something happens in your App and you want to stop downloading a particular connection, you can simply call cancel on your connection object:

[_connection cancel];

Downloading Data using NSURLConnection in IOS using Objective-C

Alternate Code

NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:self.imageURL]];
__weak typeof(self) weakSelf = self;
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue new] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
if (connectionError)
{
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
NSLog(@"Error occurred: %@", connectionError.localizedDescription);
[weakSelf.loadingIndicator stopAnimating];
}];
}
else
{
UIImage *image = [[UIImage alloc] initWithData:data];
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
[weakSelf.loadingIndicator stopAnimating];
weakSelf.ImageView.image = image;
}];
}
}];

Scroll to Top

Discover more from CODE t!ps

Subscribe now to keep reading and get access to the full archive.

Continue reading