Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NSURLConnection works perfectly in iOS 4.3 but not in iOS 5 / iOS 6

I am having some really strange problems with NSURLConnection so I hope you can help me out.

What I am trying to do is download some data from a given URL using NSURLConnection.

I made my own helper class which receives data path, downloads it, and notifies the caller via delegate when the download completes.

The thing works perfectly on my iPhone with iOS 4.3. However, when tested on iOS 5 or iOS6, the connection:(NSURLConnection *)connection didReceiveData:(NSData *)data method is never called and I do not get the desired result.

The class .h file contains:

#import <Foundation/Foundation.h>

@protocol NIAsyncDownloaderDelegate
@required
- (void) asyncDownloaderDataDownloadComplete:(NSData *)data withError:(bool) error;
@end

@interface NIAsyncImageDownloader : NSObject <NSURLConnectionDataDelegate>
{
    NSURLConnection *theConnection;
    NSMutableData* myData;

    NSURL *downloadURL;

    id delegate;
}

-(id) initWithDataDownloadString:(NSString *) stringAddress;

@property (nonatomic, retain) id delegate;

@end

And the .m file looks like this:

#import "NIAsyncDownloader.h"

@implementation NIAsyncImageDownloader

@synthesize delegate;

-(id) initWithDataDownloadString:(NSString *)stringAddress
{
    if (self = [super init])
    {
        [self loadDataFromURL:[NSURL URLWithString:stringAddress]];
    }
    return self;
}

- (void)loadDataFromURL:(NSURL*)url
{
    NSLog(@"Called: %@", NSStringFromSelector(_cmd));
    downloadURL = url;

    NSURLRequest* request = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0];
    theConnection = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:YES];
}

-(void) connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
    NSLog(@"Called: %@", NSStringFromSelector(_cmd));
    NSLog(@"The response is: %@, status code %i, url %@", response.description, ((NSHTTPURLResponse*)response).statusCode, ((NSHTTPURLResponse*)response).URL.description);
}

-(void) connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
    NSLog(@"Called: %@", NSStringFromSelector(_cmd));

    if (myData == nil)
    {
        myData = [[NSMutableData alloc] initWithCapacity:2048];
    }

    [myData appendData:data];
}

//CALLED ON iOS 4.3
- (void)connectionDidFinishLoading:(NSURLConnection*)connection
{
    //so self data now has the complete image
    NSLog(@"Called: %@", NSStringFromSelector(_cmd));
    [self handleDownloadSuccess];
}

//CALLED ON iOS 5, iOS 6
-(void) connectionDidFinishDownloading:(NSURLConnection *)connection destinationURL:(NSURL *)destinationURL
{
    NSLog(@"Called: %@", NSStringFromSelector(_cmd));
    [self handleDownloadSuccess];
}

-(void) handleDownloadSuccess
{    
    NSLog(@"Called: %@", NSStringFromSelector(_cmd));
    [theConnection release];
    theConnection = nil;

    [delegate asyncDownloaderDataDownloadComplete:myData withError:NO];

    [myData release];
    myData = nil;
}

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
    NSLog(@"Called: %@", NSStringFromSelector(_cmd));
    [delegate asyncDownloaderDataDownloadComplete:nil withError:YES];
}

@end

Here are some screenshots to show you what I am talking about:

This is what happens when I run the application on iOS5 or iOS6, the request initializes itself, receives a response, and calls connectionDidFinishDownloading:(NSURLConnection *)connection destinationURL:(NSURL *)destinationURL right away ios5 ios6

However, when I run the same application on iOS 4.3, everything works perfectly as you can see from the screenshots below:

ios4.3 1iOS4.3 2

I also noticed that iOS 5 and iOS 6 do not call the same 'finish' method like the iOS 4.3, but I don't think that has has anything to do with my current issue.

And as a final thing, the documentation over here says that the method in question (connection:didReceiveData) is actually deprecated as of iOS 4.3: http://developer.apple.com/library/ios/#documentation/Foundation/Reference/NSURLConnectionDelegate_Protocol/DeprecationAppendix/AppendixADeprecatedAPI.html

However, another reference states that it is a part of NSURLConnectionDataDelegate protocol and is available since iOS 2: http://developer.apple.com/library/ios/#documentation/Foundation/Reference/NSURLConnectionDataDelegate_protocol/Reference/Reference.html

XCode seems to agree that it is deprecated:

xcode

Just in case anyone wonders how I am using the downloader, it is pretty trivial really:

In .h:

#import <UIKit/UIKit.h>
#import "NIAsyncDownloader.h"

@interface DTViewController : UIViewController <NIAsyncDownloaderDelegate>
{
    NIAsyncImageDownloader *downloader;
}

@end

And in .m :

#import "DTViewController.h"

@interface DTViewController ()

@end

@implementation DTViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

    downloader = [[NIAsyncImageDownloader alloc] initWithDataDownloadString:@"http://www.freeimageslive.com/galleries/sports/sportsgames/pics/whitedice1.jpg"];
    downloader.delegate = self;
}

-(void) asyncDownloaderDataDownloadComplete:(NSData *)data withError:(bool)error
{
    if (data == nil || error)
    {
        NSLog(@"DOWNLOAD FAILED");
    }
    else
    {
        NSLog(@"DOWNLOAD SUCCEEDED");
    }
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end

So, summed up, why am I having problems and what to do?

Thanks in advance :)

like image 297
DarkoB Avatar asked Nov 13 '22 04:11

DarkoB


1 Answers

This may or may not be the problem, but when I set up to do a similar thing I implement the NSURLConnectionDelegate and the NSURLConnectionDataDelegate protocols. I haven't tested on iOS versions previous to 5, but it has worked in both 5 and 6 for me:

@interface NIAsyncImageDownloader : NSObject <NSURLConnectionDelegate, NSURLConnectionDataDelegate> {

}
like image 137
ModernCarpentry Avatar answered Nov 15 '22 05:11

ModernCarpentry