Skip to main content

Objective-C: server requests in a thread (like AsyncTask in Android)


I would like to start a server request, you can cancel.



My idea is to start the request in a thread so that the user interface does not freeze. So you can kill the whole thread including the request with a click on a "Cancel"-button.



With Android it works: the server request gets started in a "AsyncTask" and in the "onReturn()"-method I can react as soon as the server request finish.



How can I implement this using Objective-C on iOS? My first attempt was a "NSInvocationOperation". You can cancel the operation, but it's difficult to handle when a request is completed and results are available. I think NSInvocationOperation is not the solution for my issue.



The would you recommend to me? Is NSThread the right choice for me?



Thank you very much!


Source: Tips4allCCNA FINAL EXAM

Comments

  1. It is unbelievably simple to do this with ASIHttpRequest.

    (Asynchronous is so simple, there is no reason you would ever do it not-asynchronously.)

    Here are some rough extracts that might get you started.

    ...
    ASIFormDataRequest *request;
    ...
    NSURL *url = [NSURL URLWithString:@"https://blah.blah/blah.cgi?blah"];
    request = [ASIFormDataRequest requestWithURL:url];

    [request setPostValue:@"fred" forKey:@"username"];
    [request setPostValue:@"flint" forKey:@"passie"];
    [request setPostValue:@"stone" forKey:@"town"];

    // send up data...
    [request setData:[NSData dataWithBytes:blah length:blah] forKey:@"thefile"];

    // or perhaps something like...
    [request setData:imageData withFileName:@"blah.png"
    andContentType:@"image/jpeg" forKey:@"photoimage"];

    [request setDelegate:self];
    [request setDidFinishSelector:@selector(postingDone:)];
    [request setDidFailSelector:@selector(postingDoneProblem:)];
    [request startAsynchronous];
    ...

    -(void) postingDone:(ASIHTTPRequest *)request
    {
    // it worked
    }
    -(void) postingDoneProblem:(ASIHTTPRequest *)request
    {
    // failed
    }


    Couldn't really be any easier. You're basically just typing out the fields and values.

    Per your question, here is how you cancel an "in-flight" request... just set the delegate to nil and then "cancel" it.

    [myRequest setDelegate:nil];
    [myRequest cancel];
    [myRequest release];


    ASIHttpRequest is the "miracle library". If you are new to iOS, ASIHttpRequest is simply THE most used 3rd party library. Essentially, every single iPhone app of the 300,000 iPhone apps uses it.

    If at all possible BE SURE to donate a few bucks to the guy -- if he stops supporting that library, 100,000 iPhone programmers are buggered!

    the documentation is trivial, a child can follow it:
    http://allseeing-i.com/ASIHTTPRequest/How-to-use
    "Creating an asynchronous request"

    it is probably - almost certainly - the most amazingly simple networking library on any platform. It is trivial to do what you describe, happily. Enjoy.

    ReplyDelete
  2. NSURLConnection is async by default and supports cancelation as well as delegate methods when connection has been established, data has been received or whole request has been completed.

    Also data transfer takes place in background so that UI stays responsive.

    ReplyDelete
  3. Cocoa's built-in async networking code is not thread-based but works with run loop events, but the result (asynchronous connections) is the same.

    Create an NSURLConnection with +[NSURLConnection connectionWithRequest:delegate:]. The delegate you set will be informed about the progress of the connection and can cancel it anytime with -[NSURLConnection cancel].

    ReplyDelete
  4. Check out ASIHTTPRequest, specifically, the ASINetworkQueue subclass, which is described as:


    ASINetworkQueue

    A subclass of NSOperationQueue that
    may be used to track progress across
    multiple requests.


    I've only used ASIHTTPRequest for a single synchronous request to download directly to disk, which was easy to implement, but I've heard good reports of using queues to manage multiple asynchronous server requests at once.

    ReplyDelete

Post a Comment

Popular posts from this blog

Why is this Javascript much *slower* than its jQuery equivalent?

I have a HTML list of about 500 items and a "filter" box above it. I started by using jQuery to filter the list when I typed a letter (timing code added later): $('#filter').keyup( function() { var jqStart = (new Date).getTime(); var search = $(this).val().toLowerCase(); var $list = $('ul.ablist > li'); $list.each( function() { if ( $(this).text().toLowerCase().indexOf(search) === -1 ) $(this).hide(); else $(this).show(); } ); console.log('Time: ' + ((new Date).getTime() - jqStart)); } ); However, there was a couple of seconds delay after typing each letter (particularly the first letter). So I thought it may be slightly quicker if I used plain Javascript (I read recently that jQuery's each function is particularly slow). Here's my JS equivalent: document.getElementById('filter').addEventListener( 'keyup', function () { var jsStart = (new Date).getTime()...

Is it possible to have IF statement in an Echo statement in PHP

Thanks in advance. I did look at the other questions/answers that were similar and didn't find exactly what I was looking for. I'm trying to do this, am I on the right path? echo " <div id='tabs-".$match."'> <textarea id='".$match."' name='".$match."'>". if ($COLUMN_NAME === $match) { echo $FIELD_WITH_COLUMN_NAME; } else { } ."</textarea> <script type='text/javascript'> CKEDITOR.replace( '".$match."' ); </script> </div>"; I am getting the following error message in the browser: Parse error: syntax error, unexpected T_IF Please let me know if this is the right way to go about nesting an IF statement inside an echo. Thank you.