views:

2617

answers:

2

I've had significant success with NSURL, NSURL[Mutable]Request, NSURLConnection with my iPhone applications. When trying to compile a stand alone Cocoa application, 10 line program to make a simple HTTP request, there are zero compiler errors or warnings. The program compiles fine, yet the HTTP Request is never made to my web server (I'm running a tcpdump and watching Apache logs in parallel). When I run very similar code in an iPhone app, essentially copy/pasted as evil as that is, all works golden.

I kept the code for the 'obj' declaration in the delegate to NSURLConnection out of this code snippet for the sake of simplicity. I'm also passing the following to gcc:

gcc -o foo foo.m -lobjc -framework cocoa

Thanks for any insight.

#import <Cocoa/Cocoa.h>

int main (int argc, char *argv[])
{    

NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
NSString * urlstr = @"http://tmp/test.php";
[NSApplication sharedApplication];
NSObject *obj = [[NSObject alloc] init];
NSURL *url = [NSURL URLWithString: urlstr];      
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url];

    if([request isKindOfClass:[NSMutableURLRequest class]])
 NSLog(@"request is of type NSMutableURLRequest");


[request setHTTPMethod:@"GET"];
[request setCachePolicy:NSURLRequestReloadIgnoringLocalAndRemoteCacheData];
NSURLConnection *connection = [[NSURLConnection alloc]
                          initWithRequest:request
            delegate:obj
     startImmediately:YES];

if(connection) 
 NSLog(@"We do have a connection.");

[pool release];
return 0;

}

+2  A: 

NSURLConnection is an asynchronous API that relies upon NSRunLoop. Your posted code never creates a run loop for the connection to run in. Therefore, I presume Cocoa is unable to create the connection and so returns nil. Things to look into:

1) Anything in the console? Is NSURLConnection throwing an exception or logging an error?

2) What happens if you use the synchronous API instead? +[NSURLConnection sendSynchronousRequest:returningResponse:error:]

3) What is the point of this code? Cocoa is not designed for running directly from a main() function yourself. Is there a particular reason why you are not using the Xcode-provided application templates that will take care of setting up run loop, autorelease pool etc.?

Mike Abdullah
+1  A: 

The other poster pretty much answered this for you, but I thought I would just add a few things.

First, you don't really need to link to Cocoa for this, just linking to the Foundation framework is okay. Also, since you don't need a connection to the Window Server, you can get rid of the [NSApplication sharedApplicaiton] call. If you want just a simple, console test application to start with, use what you have now and add this before your [pool realease] call:

[[NSRunLoop currentRunLoop] run];

Please note, however, that this will block and may actually never return. Before calling this, you can add a timer if you want your code to actually do something in the background :) See the documentation on NSRunLoop for more ways to use this.

Jason Coco