9

I am writing a program in Objective-C and I need to make web requests to web server, but asynchronously and I am fairly new on mac, I am very good at windows technologies, but I need to know that if I use NSOperation (introduced in 10.5, i am assuming that it will not run in 10.4 MAC?), or if it was implemented such that it utilizes system threading which will be available on 10.4?

Or I should create a new thread and create a new runloop, also how to use cookies etc, if anyone can give me one small example, that will be of great help. I want this sample to run on mac 10.4 too if possible.

Akash Kava
  • 39,066
  • 20
  • 121
  • 167

3 Answers3

29

There's a good example of using NSURLRequest and NSHTTPCookies to do a full web application example of logging into a website, storing the SessionID cookie and resubmitting it in future requests.

NSURLConnection, NSHTTPCookie

By logix812:

    NSHTTPURLResponse   * response;
    NSError             * error;
    NSMutableURLRequest * request;
    request = [[[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:@"http://temp/gomh/authenticate.py?setCookie=1"]
                                            cachePolicy:NSURLRequestReloadIgnoringCacheData 
                                        timeoutInterval:60] autorelease];

    [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];  
    NSLog(@"RESPONSE HEADERS: \n%@", [response allHeaderFields]);

    // If you want to get all of the cookies:
    NSArray * all = [NSHTTPCookie cookiesWithResponseHeaderFields:[response allHeaderFields] forURL:[NSURL URLWithString:@"http://temp"]];
    NSLog(@"How many Cookies: %d", all.count);
    // Store the cookies:
    // NSHTTPCookieStorage is a Singleton.
    [[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookies:all forURL:[NSURL URLWithString:@"http://temp"] mainDocumentURL:nil];

    // Now we can print all of the cookies we have:
    for (NSHTTPCookie *cookie in all)
        NSLog(@"Name: %@ : Value: %@, Expires: %@", cookie.name, cookie.value, cookie.expiresDate); 


    // Now lets go back the other way.  We want the server to know we have some cookies available:
    // this availableCookies array is going to be the same as the 'all' array above.  We could 
    // have just used the 'all' array, but this shows you how to get the cookies back from the singleton.
    NSArray * availableCookies = [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookiesForURL:[NSURL URLWithString:@"http://temp"]];
    NSDictionary * headers = [NSHTTPCookie requestHeaderFieldsWithCookies:availableCookies];

    // we are just recycling the original request
    [request setAllHTTPHeaderFields:headers];

    request.URL = [NSURL URLWithString:@"http://temp/gomh/authenticate.py"];
    error       = nil;
    response    = nil;

    NSData * data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
    NSLog(@"The server saw:\n%@", [[[NSString alloc] initWithData:data encoding: NSASCIIStringEncoding] autorelease]);
Douglas
  • 36,802
  • 9
  • 76
  • 89
Dougnukem
  • 14,709
  • 24
  • 89
  • 130
  • 1
    Thank you for your answer, but I have a question, you specified different URLs for example for the first one you provided [this] (http://temp/gomh/authenticate.py?setCookie=1) URL and for the second one http://temp and so on. How do I know the URL of cookies, since the web service that I'm using in my app has not provided this information? – Hamid Sep 25 '12 at 02:23
18

For asynchronous requests, you need to use NSURLConnection.

For cookies, see NSHTTPCookie and NSHTTPCookieStorage.

UPDATE:

The code below is real, working code from one of my applications. responseData is defined as NSMutableData* in the class interface.

- (void)load {
    NSURL *myURL = [NSURL URLWithString:@"http://stackoverflow.com/"];
    NSURLRequest *request = [NSURLRequest requestWithURL:myURL
                                             cachePolicy:NSURLRequestReloadIgnoringLocalCacheData
                                         timeoutInterval:60];
    [[NSURLConnection alloc] initWithRequest:request delegate:self];
}

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
    responseData = [[NSMutableData alloc] init];
}

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
    [responseData appendData:data];
}

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
    [responseData release];
    [connection release];
    // Show error message
}

- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
    // Use responseData
    [responseData release];
    [connection release];
}
dbr
  • 165,801
  • 69
  • 278
  • 343
Can Berk Güder
  • 109,922
  • 25
  • 130
  • 137
  • 1
    @Akash: did you try NSURLConnection's connectionWithRequest:delegate: method? And I'm sorry but I see no mention of NSURLConnection or NSHTTPCookie in your question. Trust me, everything you need is in the links I have given. – Can Berk Güder Apr 01 '09 at 18:12
  • I already had used it, it didnt work so I thought there must be some other way to do asynchronous request as there isnt any sample code to do it. Here is the code I tried.. http://stackoverflow.com/questions/706355/whats-wrong-on-following-urlconnection – Akash Kava Apr 02 '09 at 15:33
  • @Akash: NSURLConnection is the easiest way. I'll post sample code. – Can Berk Güder Apr 02 '09 at 15:39
3

I am able to fetch cookie in such way:

NSArray* arr = [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookiesForURL:[NSURL URLWithString: @"http://google.com" ]];

This one works fine for asynchronous request as well.

sth
  • 222,467
  • 53
  • 283
  • 367
tdu
  • 31
  • 1