Problems getting NSURLConnection to work
-
Greetings and Salutations,
I've setup a class as a delegate for NSURLConnection, though when I
create the NSURLConnection and provide it a delegate (self), the
delegate methods don't get called. I know they don't get called as
I've put in NSLog() statements and these statements don't get displayed.
Is there something I'm missing?
Follows is the code from the class implementation file:
Thanks,
Matthew Delves
----------------
// Instance methods
- (id) initWithUrl:(NSURL *)aUrl
{
/*
NSURLConnection why won't you work?
I follow your documentation, why won't you work?
I remove garbage collection, why won't you work?
I change the thread you run on, why won't you work?
NSURLConnection why won't you work?
*/
url = [aUrl copy]; // copy the url
[url retain];
NSLog(@"%@", url);
responseString = nil;
responseCode = 0.0;
document = nil;
urlConnection = nil;
urlRequest = nil;
urlResponse = nil;
urlData = nil;
urlRequest = [[NSMutableURLRequest alloc] initWithURL:url
cachePolicy:NSURLRequestReloadIgnoringLocalCacheData
timeoutInterval:60.0];
[urlRequest retain];
[urlRequest setMainDocumentURL:url];
[urlRequest setURL:url];
if([NSURLConnection canHandleRequest:urlRequest])
urlConnection = [NSURLConnection connectionWithRequest:urlRequest
delegate:self];
if(urlConnection) {
[urlConnection retain];
urlData = [[NSMutableData alloc] init];
[urlConnection start];
[urlData retain];
} else {
finishedDownload = YES;
failedDownload = YES;
NSLog(@"urlConnection has become a pointer to nil");
}
failedDownload = NO;
finishedDownload = NO;
downloading = NO;
document = nil;
NSLog(@"end of fetcher init");
if(!urlConnection)
NSLog(@"blah!");
return self;
}
- (void) dealloc
{
[urlConnection release];
urlConnection = nil;
[urlRequest release];
urlRequest = nil;
[urlResponse release];
urlResponse = nil;
[responseString release];
responseString = nil;
[document release];
document = nil;
[urlData release];
urlData = nil;
[url release];
url = nil;
[super dealloc];
}
// NSURLConnection delegate methods
- (void)connection:(NSURLConnection *)connection
didCancelAuthenticationChallenge:(NSURLAuthenticationChallenge
*)challenge
{
NSLog(@"cancel of authentication request");
}
- (void)connection:(NSURLConnection *)connection didFailWithError:
(NSError *)error
{
NSLog(@"Connection failed! Error - %@ %@",
[error localizedDescription],
[[error userInfo] objectForKey:NSErrorFailingURLStringKey]);
failedDownload = YES;
downloading = NO;
[urlRequest release];
[urlResponse release];
[urlConnection release];
}
- (void)connection:(NSURLConnection *)connection
didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge
*)challenge
{
NSLog(@"Authentication request received");
}
- (void)connection:(NSURLConnection *)connection didReceiveData:
(NSData *)data
{
NSLog(@"received data");
if(!urlData){
urlData = [[NSMutableData alloc] init];
[urlData setLength:0];
}
[urlData appendData:data];
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:
(NSURLResponse *)response
{
NSLog(@"Response received");
downloading = YES;
[urlData setLength:0];
}
- (NSCachedURLResponse *)connection:(NSURLConnection *)connection
willCacheResponse:(NSCachedURLResponse *)cachedResponse
{
NSCachedURLResponse *newCachedResponse=cachedResponse;
NSDictionary *newUserInfo;
newUserInfo=[NSDictionary dictionaryWithObject:[NSCalendarDate date]
forKey:@"Cached Date"];
newCachedResponse=[[[NSCachedURLResponse alloc] initWithResponse:
[cachedResponse response]
data:[cachedResponse data]
userInfo:newUserInfo
storagePolicy:[cachedResponse storagePolicy]]
autorelease];
return newCachedResponse;
}
- (NSURLRequest *)connection:(NSURLConnection *)connection
willSendRequest:(NSURLRequest *)aRequest
redirectResponse:(NSURLResponse *)redirectResponse
{
NSURLRequest *newRequest = aRequest;
if (redirectResponse) {
newRequest=nil;
}
return newRequest;
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
finishedDownload = YES;
downloading = NO;
NSLog(@"Finished downloading file", url);
NSError *err= [[NSError alloc] init];
document = [[NSXMLDocument alloc] initWithData:urlData
options:(NSXMLNodePreserveWhitespace|
NSXMLNodePreserveCDATA)
error:&err];
[document retain];
[urlConnection release];
[urlRequest release];
[urlResponse release];
}
--------------- -
On Feb 8, 2008, at 10:19 PM, Matthew Delves wrote:
> I've setup a class as a delegate for NSURLConnection, though when I
> create the NSURLConnection and provide it a delegate (self), the
> delegate methods don't get called. I know they don't get called as
> I've put in NSLog() statements and these statements don't get
> displayed.
>
> Is there something I'm missing?
Why aren't you setting self to [super init] or the superclass's
initializer in the -initWithURL: method? Also, you're over-retaining
some memory. Are you using GC?
Nick Zitzmann
<http://www.chronosnet.com/> -
On Feb 9, 2008, at 07:19, Matthew Delves wrote:
> I've setup a class as a delegate for NSURLConnection, though when I
> create the NSURLConnection and provide it a delegate (self), the
> delegate methods don't get called. I know they don't get called as
> I've put in NSLog() statements and these statements don't get
> displayed.
>
> Is there something I'm missing?
>
> Follows is the code from the class implementation file:
> - (id) initWithUrl:(NSURL *)aUrl
> {
> /*
> NSURLConnection why won't you work?
> I follow your documentation, why won't you work?
> I remove garbage collection, why won't you work?
> I change the thread you run on, why won't you work?
On which thread do you run this? It works fine on the main thread.
> NSURLConnection why won't you work?
> */
>
> url = [aUrl copy]; // copy the url
Why copy the url?
> [url retain];
And then retain it!?
> NSLog(@"%@", url);
Can you access this url with a browser?
> responseString = nil;
> responseCode = 0.0;
responseCode is a float?!
> document = nil;
> urlConnection = nil;
> urlRequest = nil;
> urlResponse = nil;
> urlData = nil;
>
> urlRequest = [[NSMutableURLRequest alloc] initWithURL:url
> cachePolicy:NSURLRequestReloadIgnoringLocalCacheData
> timeoutInterval:60.0];
>
> [urlRequest retain];
Why retain an object created with alloc?
> [urlRequest setMainDocumentURL:url];
> [urlRequest setURL:url];
Why do you set the url again?
>
> if([NSURLConnection canHandleRequest:urlRequest])
> urlConnection = [NSURLConnection connectionWithRequest:urlRequest
> delegate:self];
>
> if(urlConnection) {
> [urlConnection retain];
If you want to retain the object, why not create it with –
initWithRequest:delegate:?
> urlData = [[NSMutableData alloc] init];
> [urlConnection start];
start? NSURLConnection does not respond to this. The connection
starts when you create it.
I guess that at this point an exception is raised and your
initializer fails. This is why you don't get any notifications.
Best Regards,
Nir Soffer -
On Feb 9, 2008, at 15:14, Nir Soffer wrote:
>> [urlConnection start];
>
> start? NSURLConnection does not respond to this. The connection
> starts when you create it.
>
> I guess that at this point an exception is raised and your
> initializer fails. This is why you don't get any notifications.
I see that -start was added in 10.5, so you don't get an exception
here. Looks like not calling [super init] is the issue.
Best Regards,
Nir Soffer -
On 10/02/2008, at 12:31 AM, Nir Soffer wrote:
>
> On Feb 9, 2008, at 15:14, Nir Soffer wrote:
>
>>> [urlConnection start];
>>
>> start? NSURLConnection does not respond to this. The connection
>> starts when you create it.
>>
>> I guess that at this point an exception is raised and your
>> initializer fails. This is why you don't get any notifications.
>
> I see that -start was added in 10.5, so you don't get an exception
> here. Looks like not calling [super init] is the issue.
>
Unfortunately not. I placed in a call to [super init] though that made
no difference.
With the comments from your previous email, I have been scratching my
head over a lot of it including using an NSMutableURLRequest and
setting the url of it a second time. As far as threads are concerned,
I've run in on the main thread and a seperate thread and get the same
results.
Any suggestions would be greatly appreciated.
Thanks,
Matthew Delves -
on 2/9/08 7:23 AM, <cocoa-dev-request...> at
<cocoa-dev-request...> wrote:
> Unfortunately not. I placed in a call to [super init] though that made
> no difference.
>
> With the comments from your previous email, I have been scratching my
> head over a lot of it including using an NSMutableURLRequest and
> setting the url of it a second time. As far as threads are concerned,
> I've run in on the main thread and a seperate thread and get the same
> results.
>
> Any suggestions would be greatly appreciated.
Do what I did the day before yesterday when I used NSURLConnection for the
first time, help yourself to Apple code that works perfectly, at least it
did for me immediately.
http://developer.apple.com/samplecode/LSMSmartCategorizer/listing17.html
If it does work for you as well, then go through and try and sort out what
the significant difference is with your code, if it doesn't ... then your
real problem is probably not NSURLConnection related.
--
Alex Curylo -- <alex...> -- http://www.alexcurylo.com/
"The reason I didn't go into the clouds was I saw you fly in first...
I'm not flying into any cloud with a crazy Curylo brother in it."
-- Jim Reich -
On Feb 9, 2008, at 17:08, Matthew Delves wrote:
> Unfortunately not. I placed in a call to [super init] though that
> made no difference.
>
> With the comments from your previous email, I have been scratching
> my head over a lot of it including using an NSMutableURLRequest and
> setting the url of it a second time. As far as threads are
> concerned, I've run in on the main thread and a seperate thread and
> get the same results.
>
> Any suggestions would be greatly appreciated.
This is what I would:
1. Create a new cocoa app for testing, and setup an application delegate
2. Add this minimal code in the application delegate:
/* AppDelegate.h */
#import <Cocoa/Cocoa.h>
@interface AppDelegate : NSObject
{
NSURLConnection *connection;
}
@end
/* AppDelegate.m */
#import "AppDelegate.h"
@implementation AppDelegate
- (void)applicationDidFinishLaunching:(NSNotification *)notification;
{
NSURL *url = [NSURL URLWithString:@"http://www.apple.com/"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
connection = [[NSURLConnection alloc] initWithRequest:request
delegate:self];
if (connection == nil) {
NSLog(@"cannot create connection");
return;
}
}
-(void)connection:(NSURLConnection *)sender didReceiveResponse:
(NSURLResponse *)response;
{
NSLog(@"received response");
}
@end
3. Compile and test
4. Add more features one by one: save received data, handle
redirects, caching, etc.
5. When you finish, integrate with your app.
Best Regards,
Nir Soffer -
On 8 Feb '08, at 9:19 PM, Matthew Delves wrote:
> I've setup a class as a delegate for NSURLConnection, though when I
> create the NSURLConnection and provide it a delegate (self), the
> delegate methods don't get called. I know they don't get called as
> I've put in NSLog() statements and these statements don't get
> displayed.
My guess would be that, due to some bug elsewhere in your code, your
object is getting dealloced immediately after it's created. That will
cause its -dealloc method to release the URLConnection, which will
stop it. To test this hypothesis, put a breakpoint or NSLog call in
your dealloc method.
(Speaking of refcounting — I noticed that both urlRequest and urlData
are over-retained: they're created with alloc/init, but then -retain
is called again, creating two references.)
—Jens -
So right of the bat a few things (just to get in the habit of)..
1.) Before you do any of your code you need the:
self = [super init]
if (self != nil)
...
2.) Why copy URL? Why not just retain if you are keeping it around?
3.) Copy will call alloc init.. NO need to reatain again.
4.) Your URLRequest is retained too many times. Do retain if using
alloc init.
Are you getting a valid URL connection back?
On Feb 8, 2008, at 9:19 PM, Matthew Delves wrote:
> Greetings and Salutations,
> I've setup a class as a delegate for NSURLConnection, though when I
> create the NSURLConnection and provide it a delegate (self), the
> delegate methods don't get called. I know they don't get called as
> I've put in NSLog() statements and these statements don't get
> displayed.
>
> Is there something I'm missing?
>
> Follows is the code from the class implementation file:
>
> Thanks,
> Matthew Delves
>
> ----------------
> // Instance methods
> - (id) initWithUrl:(NSURL *)aUrl
> {
> /*
> NSURLConnection why won't you work?
> I follow your documentation, why won't you work?
> I remove garbage collection, why won't you work?
> I change the thread you run on, why won't you work?
> NSURLConnection why won't you work?
> */
>
> url = [aUrl copy]; // copy the url
> [url retain];
> NSLog(@"%@", url);
> responseString = nil;
> responseCode = 0.0;
> document = nil;
> urlConnection = nil;
> urlRequest = nil;
> urlResponse = nil;
> urlData = nil;
>
> urlRequest = [[NSMutableURLRequest alloc] initWithURL:url
> cachePolicy:NSURLRequestReloadIgnoringLocalCacheData
> timeoutInterval:60.0];
>
> [urlRequest retain];
> [urlRequest setMainDocumentURL:url];
> [urlRequest setURL:url];
>
> if([NSURLConnection canHandleRequest:urlRequest])
> urlConnection = [NSURLConnection connectionWithRequest:urlRequest
> delegate:self];
>
> if(urlConnection) {
> [urlConnection retain];
> urlData = [[NSMutableData alloc] init];
> [urlConnection start];
> [urlData retain];
> } else {
> finishedDownload = YES;
> failedDownload = YES;
> NSLog(@"urlConnection has become a pointer to nil");
> }
>
> failedDownload = NO;
> finishedDownload = NO;
> downloading = NO;
> document = nil;
>
> NSLog(@"end of fetcher init");
>
> if(!urlConnection)
> NSLog(@"blah!");
>
> return self;
> }
>
> - (void) dealloc
> {
>
> [urlConnection release];
> urlConnection = nil;
>
> [urlRequest release];
> urlRequest = nil;
>
> [urlResponse release];
> urlResponse = nil;
>
> [responseString release];
> responseString = nil;
>
> [document release];
> document = nil;
>
> [urlData release];
> urlData = nil;
>
> [url release];
> url = nil;
>
> [super dealloc];
> }
>
>
> // NSURLConnection delegate methods
> - (void)connection:(NSURLConnection *)connection
> didCancelAuthenticationChallenge:(NSURLAuthenticationChallenge
> *)challenge
> {
> NSLog(@"cancel of authentication request");
> }
>
> - (void)connection:(NSURLConnection *)connection didFailWithError:
> (NSError *)error
> {
> NSLog(@"Connection failed! Error - %@ %@",
> [error localizedDescription],
> [[error userInfo] objectForKey:NSErrorFailingURLStringKey]);
> failedDownload = YES;
> downloading = NO;
> [urlRequest release];
> [urlResponse release];
> [urlConnection release];
> }
>
> - (void)connection:(NSURLConnection *)connection
> didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge
> *)challenge
> {
> NSLog(@"Authentication request received");
> }
>
> - (void)connection:(NSURLConnection *)connection didReceiveData:
> (NSData *)data
> {
> NSLog(@"received data");
> if(!urlData){
> urlData = [[NSMutableData alloc] init];
> [urlData setLength:0];
> }
>
> [urlData appendData:data];
> }
>
> - (void)connection:(NSURLConnection *)connection didReceiveResponse:
> (NSURLResponse *)response
> {
> NSLog(@"Response received");
> downloading = YES;
> [urlData setLength:0];
> }
>
> - (NSCachedURLResponse *)connection:(NSURLConnection *)connection
> willCacheResponse:(NSCachedURLResponse *)cachedResponse
> {
> NSCachedURLResponse *newCachedResponse=cachedResponse;
> NSDictionary *newUserInfo;
>
> newUserInfo=[NSDictionary dictionaryWithObject:[NSCalendarDate date]
> forKey:@"Cached Date"];
>
> newCachedResponse=[[[NSCachedURLResponse alloc] initWithResponse:
> [cachedResponse response]
> data:[cachedResponse data]
> userInfo:newUserInfo
> storagePolicy:[cachedResponse storagePolicy]]
> autorelease];
>
> return newCachedResponse;
> }
>
> - (NSURLRequest *)connection:(NSURLConnection *)connection
> willSendRequest:(NSURLRequest *)aRequest
> redirectResponse:(NSURLResponse *)redirectResponse
> {
> NSURLRequest *newRequest = aRequest;
>
> if (redirectResponse) {
> newRequest=nil;
> }
> return newRequest;
> }
>
> - (void)connectionDidFinishLoading:(NSURLConnection *)connection
> {
> finishedDownload = YES;
> downloading = NO;
> NSLog(@"Finished downloading file", url);
> NSError *err= [[NSError alloc] init];
> document = [[NSXMLDocument alloc] initWithData:urlData
> options:(NSXMLNodePreserveWhitespace|
> NSXMLNodePreserveCDATA)
> error:&err];
> [document retain];
> [urlConnection release];
> [urlRequest release];
> [urlResponse release];
> }
>
> ---------------



