Objective-C REST Client Update

Date Arrow  January 19, 2009

I’ve uploaded (yet another) update to the Objective-C REST client I’ve blogged about previously. This time I’ve scanned the code with the excellent LLVM/Clang Static Analyzer and fixed a couple of memory leaks here and there. I strongly recommend to scan your own projects with this tool, it’s extremely simple to use:

  1. Install it somewhere in your PATH;
  2. Set your projects to use the Debug configuration when building from the command line (you can do that in the inspector for the project, in the “Configurations” tab); (see Sebastien’s comment below ;)
  3. Open Terminal.app and fire
    scan-build -k -V xcodebuild

    on the root of the Xcode project folder;

  4. If there are any problems with your code, you’ll have your web browser pop up with the list of problems, their description in annotated code format, and even a link to open the file right away.


I have also fixed another problem with the code, which was preventing POST data to be properly sent to the server with the previous version. You might have encountered this problem, and here is the solution: instead of using NSString’s stringByAddingPercentEscapesUsingEncoding: method, use CoreFoundation’s CFURLCreateStringByAddingPercentEscapes() function. This means that this code:

became this:

Now any text sequence, including any “legal” URL character (as explained in the RFC), will be encoded properly and sent to the server as required.

Cocoa only provides a thin layer over many of CoreFoundation functions and types; it does not expose completely all the functionality “below”, and that’s why sometimes you must dig a bit deeper and call CoreFoundation code to certain operations, like using the Address Book data, or playing sounds in your iPhone applications. The good thing, as always, is that CoreFoundation types are “toll free” bridged, which means that you can safely cast a CFStringRef into an NSString pointer without any overhead.

Chris Adamson explained this as an “Opt-in Complexity” pattern, in an article in the Inside iPhone blog last week:

Need time zone awareness? NSTimeZone is your friend. Need to know every time zone that the device supports? Get to know CFTimeZoneCopyKnownNames(). Again, a niche-ier feature lives down at the Core Foundation level, and isn’t wrapped by an equivalent call in Foundation, though it’s easy enough to switch to procedural C and make the one-off lower-level call.

Similar Posts:

Tagged   Cocoa · iPhone

7 Comments

  • #1.   Sebastien Hugues
    01.19.2009

    If you want, you can directly set the Debug configuration like this :

    scan-build -k -V xcodebuild -configuration Debug

  • #2.   Eduardo Oliveros
    01.31.2009

    First of all, thank you very much for this library.

    I have found a little mistake in -startConnection:(NSURLRequest *), in the synchronous side of the if. As you pass the references to the pointers calling sendSynchronousRequest, you don’t need to initialize “response” and “error” (the pointers itself are changed and the later releases cause a memory exception).
    {
    NSURLResponse* response;
    NSError* error;
    NSData* data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
    [receivedData setData:data];
    }

    hope it helps… (and is right :))

    –edu

  • #3.   Adrian
    01.31.2009

    Gracias Eduardo! :)

  • #4.   Edouard
    03.23.2009

    Hi Adrian.
    I have been trying to use your REST client to upload a binary NSData type parameter, but i can not figure out how it is supposed to work.
    I am unable to parse any “$_FILES” array element after a POST call….
    Is your wrapper supposed to work with binary parameters, or i is not ?

    I have found the nice sample that does the posting of files,
    http://www.cocoadev.com/index.pl?HTTPFileUploadSample
    but Your wrapper seems to be more flexible and can be reused for other purposes. Could you confirm that you have never supposed to pass binary fields trough your wrapper ?

    Best Regards
    Ed

  • #5.   Adrian
    03.24.2009

    Hi Edouard,
    I’m using the wrapper as is for HTTP uploads (images, hence binary files) from iPhone apps, so I guess it should work :) However I haven’t tested it with backend PHP scripts (I use a Python / Django server application), so I cannot tell if there is something special about these languages handling uploads differently.
    In any case, the latest versions are in Github,
    http://github.com/akosma/iphonerestwrapper/ and
    http://github.com/akosma/cocoarestwrapper/
    Feel free to tell me if you find any bugs!
    Cheers,

  • #6.   Edouard
    03.25.2009

    Thank You for your confirmation.
    I have found my mistake, i have overlooked hardcoded file type parameter

    name=\”image\”;

    in the uploadData method of the wrapper.

    Finally it works perfect with php server implementation like this:

  • #7.   Adrian
    03.25.2009

    Good! Excellent. Indeed the file upload is in a named variable; here’s the PHP code snippet you tried to add to the comment (hope it works):


    $target = "/Users/edouard/Sites/upload/";
    $target = $target . basename( $_FILES['image']['name']) ;

    error_log('$target:'.$target.':');

    $ok=1;
    if(move_uploaded_file($_FILES['image']['tmp_name'], $target))
    {
    echo "YES";
    }
    else {
    echo "NO";
    }

Commenting