views:

1740

answers:

3

See also:

Objective-C Asynchronous Web Request with Cookies

I spent a day writing this code and can anyone tell me what is wrong here?

WSHelper is inherited from NSObject, I even tried NSDocument and NSObjectController and everything..

-(void) loadUrl: (NSString*) urlStr{
    url = [[NSURL alloc] initWithString:urlStr];
    request = [NSURLRequest requestWithURL:url cachePolicy: NSURLRequestReloadIgnoringCacheData timeoutInterval: 60.0];
    connection = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:YES];
    if(connection)
    {
     receivedData = [[NSMutableData data] retain];
            //[connection start];
    }
    else
    {       display error etc...   }
    NSApplication * app = [NSApplication sharedApplication];
    [app runModalForWindow: waitWindow];// <-- this is the problem...
}

-(void)connection: (NSURLConnection*)connection didReceiveData:(NSData*)data{
    progressText = @"Receiving Data...";
    [receivedData appendData:data];
}

-(void)connection: (NSURLConnection *)connection didFailWithError:(NSError *)error{
    progressText = @"Error...";
    NSAlert * alert = [[NSAlert alloc] init];
    [alert setMessageText:[error localizedDescription]];
    [alert runModal];
}


- (void)connectionDidFinishLoading:(NSURLConnection *)connection{
    progressText = @"Done...";
    pData = [[NSData alloc] initWithData:receivedData];
    [self hideWindow];
}

The code just wont do anything, it doesnt progress at all. I even tried it with/without startImmediately:YES but no luck !!!, this is executed in main window so even the thread and its run loop is running successfully.

I tried calling synchronous request, and it is working correctly !! But I need async solution.

I have added CoreServices.Framework in project, is there anything more I should be adding to the project? any compiler settings? Or do i have to initialize anything before I can use NSURLConnection?

Any solution to run NSURLConnection on different thread on its own NSRunLoop, Objective-C and MAC Development has no sample code anywhere in documentation that makes everything so difficult to code.

+1  A: 

How do you know it isn't doing anything? Are there any error or warning messages during the compile? Are any error messages showing up on console when the program is running?

Have you tries setting breakpoints in your code and following through what you expect to be happening?

Abizern
Ofcourse it compiles, we cant debug NSURLConnection because none of delegates get ever called, I tried putting breakpoints and no delegates were called, i saw that loadUrl did run through successfully, in log there is no error either !!, i dont know whether it started or not
Akash Kava
+2  A: 

Firstly you're making starting the connection too complicated. Change to:

connection = [[NSURLConnection alloc] initWithRequest:request delegate:self]

Remove [connection start]. Now:

  • Is your app definitely running the run loop normally? NSURLConnection requires this to work.
  • Are you able to perform a synchronous load of the URL request?
  • In the debugger, can you see that url is what you expect it to be? What is it?
  • Is it possible that you're deallocating WSHelper before any delegate messages are received? NSURLConnection is asynchoronous after all.

One does not need to do anything special to use NSURLConnection, it's a straightforward part of the Foundation framework. No special compiler settings required. No initialization before use. Nothing. Please don't start blindly trying stuff like bringing in CoreServices.Framework.

As sending the request synchronously works, there must be something wrong with your handling of the asynchronous aspect. It could be:

  • The runloop is not running in NSDefaultRunLoopMode so the connection is unable to schedule itself.
  • Some other part of your code is calling -cancel on the connection before it has a chance to load.
  • You are managing to deallocate the connection before it has a chance to load.

Real problem

Ah, in fact I've just realised what's going on. You are calling:

-[NSApp runModalForWindow:]

Read the description of what this method does. It's not running the run loop like NSURLConnection expects. I'd say that really, you don't want to be presenting a window quite like this while running a URL connection for it.

I'd also suggest that you implement the -connection:didReceiveResponse: delegate method too. You want to check here that the server is returning the expected status code.

Mike Abdullah
No I am not deallocating anything.For synchronous request I am getting this error.. [NSURLConnection sendSynchronousRequest:returningResponse:error:]: unrecognized selector sent to instance.I have my doubt on any compiler settings or any thing i have to add to project to make it work?
Akash Kava
Also, if you're running this on a separate thread, it won't work because threads don't have a run loop unless you give them one.
Alex
[NSURLConnection sendSynchronousRequest:returningResponse:error:] is a class method. I suspect you're trying to send it to an instance of NSURLConnection.
Mike Abdullah
Thanks I tried Sync method now and it did work but i am looking for async solution.
Akash Kava
I found the problem that NSURLConnection does not work on modal dialog, I have to make a new thread and call NSURLConnection on it, I guess that goes as another question..
Akash Kava
You could make a new thread. But please READ the documentation. -runModalForWindow: is intended to hand complete control over to the modal window. This is at odds with wanting to load a URL. Are you SURE your users really want a modal panel?
Mike Abdullah
+1  A: 

You say that you're using this in a modal dialog? A modal dialog puts the run loop into a different mode. You should be able to get this to work by scheduling it to run in the modal dialog run loop mode, in addition to the normal run loop mode. Try adding this line of code after you allocate connection in loadURL:

[connection scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSModalPanelRunLoopMode];

Hope that helps.

Alex
No it didn't work, I am tired... I dont get any sample anywhere which gives correct solution, now I read somewhere that you have to run a modal session, but worst part is apple has no sample code anywhere in documentation about how to get things working !!
Akash Kava