Skip to content

mirek/NSMutableDictionary-REST.framework

Repository files navigation

NSMutableDictionary+REST.framework

REST support for Objective-C NSMutableDictionary (libxml2 SAX2 based - yes it works with iPhone/iPad).

This project is a part of Safari Books Online Learn Something New Team Challenge. Feel free to contribute to become a team member, and who knows we may win an iPad for you.

Easy to use a/synchronous interface:

// Example usage:
NSString *stringUrl = @"http://github.com/api/v2/xml/user/search/chacon";
NSURL *url = [NSURL URLWithString: stringUrl];
NSLog(@"%@", [NSMutableDictionary dictionaryWithRESTContentsOfURL: url]);

// ...will output something like this:
{
  users = (
    {
      created = "2008-04-26T15:37:59Z";
      followers = 1;
      fullname = "Mirek Rusin";
      id = "user-8561";
      language = "C++";
      location = London;
      name = mirek;
      pushed = "2010-05-23T21:16:50.272Z";
      repos = 8;
      score = "15.604";
      type = user;
      username = mirek;
    },
    {
      created = "2009-10-16T16:38:48Z";
      followers = 0;
      fullname = "Mirek Rusin";
      id = "user-140734";
      language = Ruby;
      location = London;
      name = mirekrusin;
      pushed = "2010-05-24T02:16:19.737Z";
      repos = 1;
      score = "2.978005";
      type = user;
      username = mirekrusin;
    },
    {
      created = "2010-04-22T14:28:13Z";
      followers = 0;
      fullname = "Mirek Mencel";
      id = "user-249912";
      language = "";
      location = "Wroc\U0142aw";
      name = mirekm;
      pushed = "2010-05-25T02:20:23.464Z";
      repos = 0;
      score = "2.978005";
      type = user;
      username = mirekm;
    }
  );
}

Can you spot rails'ish conversion style? The XML looks like this:

<users type="array"> 
  <user> 
    <name>mirek</name> 
    <location>London</location> 
    <followers type="integer">1</followers> 
    <fullname>Mirek Rusin</fullname> 
    <language>C++</language> 
    <username>mirek</username> 
    <id>user-8561</id> 
    <repos type="integer">8</repos> 
    <type>user</type> 
    <pushed>2010-05-23T21:16:50.272Z</pushed> 
    <score type="float">15.603998</score> 
    <created>2008-04-26T15:37:59Z</created> 
  </user> 
  <user> 
    <name>mirekrusin</name> 
    <location>London</location> 
    <followers type="integer">0</followers> 
    <fullname>Mirek Rusin</fullname> 
    <language>Ruby</language> 
    <username>mirekrusin</username> 
    <id>user-140734</id> 
    <repos type="integer">1</repos> 
    <type>user</type> 
    <pushed>2010-05-24T02:16:19.737Z</pushed> 
    <score type="float">2.9780054</score> 
    <created>2009-10-16T16:38:48Z</created> 
  </user> 
  <user> 
    <name>mirekm</name> 
    <location>Wroc&#322;aw</location> 
    <followers type="integer">0</followers> 
    <fullname>Mirek Mencel</fullname> 
    <language></language> 
    <username>mirekm</username> 
    <id>user-249912</id> 
    <repos type="integer">0</repos> 
    <type>user</type> 
    <pushed>2010-05-25T02:20:23.464Z</pushed> 
    <score type="float">2.9780054</score> 
    <created>2010-04-22T14:28:13Z</created> 
  </user> 
</users>

Async and sync at the same time?

Yes, look at this code:

NSString *stringUrl = @"http://github.com/api/v2/xml/user/search/mirek";
NSURL *url = [NSURL URLWithString: stringUrl];

// Delegate gets objects asynchronously and constructor returns synchronously
NSDictionary *users = [NSMutableDictionary dictionaryWithRESTContentsOfURL: url
                                                                  delegate: [[UserPrinter alloc] init]];
                                                                  
// Above method returned synchronously
printf("Total users: %i\n", (int)[[users objectForKey: @"users"] count]);

...where a delegate object is defined as:

@interface UserPrinter : NSObject
@end

@implementation UserPrinter

- (void) didFinishElement: (id) element withPath: (NSString *) path {
  if ([path isEqualToString: @"/users/user"]) {
  
    // Yielding users asynchronously
    NSDictionary *user = (NSDictionary *)element;
    printf("- %s (%s)\n", [[user objectForKey: @"fullname"] UTF8String],
                          [[user objectForKey: @"username"] UTF8String]);
  }
}

@end

The method returns synchronously and delegate receives messages asynchronously.

POST support

To POST the first user you could write something like this:

id user = [[users objectForKey: @"users"] objectAtIndex: 0];
[user postRESTWithURL: @"http://localhost:3100/raw_post"];

localhost:3100 runs included restapp example/test application.

Default encoding type is multipart/form-data so you can send images etc (as NSData objects):

NSURL *url = [NSURL URLWithString: @"http://www.google.co.uk//intl/en_com/images/srpr/logo1w.png"];
NSData *image = [NSData dataWithContentsOfURL: url];
id post = [NSMutableDictionary dictionaryWithObject: image
                                             forKey: @"uploaded_data"];
[post postRESTWithURL: @"http://localhost:3100/raw_post"];

Refer to the source code on how to set application/x-www-form-urlencoded and multipart/form-data encoding types explicitly.

## License

© 2010 Mirek Rusin, Released under the Apache License, Version 2.0
http://www.apache.org/licenses/LICENSE-2.0

Authors

  • Mirek Rusin <mirek [at] me [dot] com>

About

REST category for NSMutableDictionary - the way it should be done.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published