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ł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>
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.
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
- Mirek Rusin <mirek [at] me [dot] com>