Consuming RESTful API with RESTframework

As explained in previous post, we’re going to demonstrate how RESTframework handles REST web services. I’ll be consuming a simple Django demo web service created in previous post, so either grab the sources or read the post and build it yourself. Assuming you have this service running on localhost, port 8000, we can continue.

First, download RESTframework from GitHub. With git client, simply type in terminal:

$ git clone git@github.com:ivasic/RESTframework.git

The quickest way to get RESTframework into your project is just including all the files from RFClasses  folder. RF does not have any external dependencies so building shouldn’t be a problem.

RFClasses

RFClasses

Now, we’ll also need JSONKit to parse API response and MBProgressHUD to show some progress. Grab both from GitHub and add to your project.

Fetching objects list

We’ll have 2 view controllers in our demo app. One will be a simple object list and the other one will be, even more simple, view controller for creating a new object. First, we’re going to show how to fetch the object list. We’ll need a GET request to /objects/ URL and we’ll need to parse the JSON array we get in response and show in the table view.

RFRequest* r = [RFRequest requestWithURL:[NSURL URLWithString:@"http://localhost:8000/"] type:RFRequestMethodGet resourcePathComponents:@"objects", nil];
[MBProgressHUD showHUDAddedTo:self.view animated:YES].labelText = NSLocalizedString(@"Loading...", @"");
[RFService execRequest:r completion:^(RFResponse* response) {
	[MBProgressHUD hideHUDForView:self.view animated:YES];
 
	if (response.error) {
		UIAlertView* aiv = [[[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Error", @"") message:response.error.localizedDescription delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil] autorelease];
		[aiv show];
		return;
	}
 
	self.dataSource = [response.dataValue objectFromJSONData];
	[self.tableView reloadData];
}];

So, what we’re doing in this code snippet is:

  • Creating a GET RFRequest with appropriate URL and resource path
  • Attaching MBProgressHUD to our view to show spinner progress
  • Executing RFRequest and defining the block to execute after RFResponse is received
  • Inside this block, we simply check for errors, parse the response, add to our tableView dataSource and reloading the table
You can see all this in action in the project sample attached to this blog post (at the bottom).

Creating new objects

Our view controller for creating new objects is responsible for creating POST requests to /objects/ URL. Again, very simple, you just need to do this:

RFRequest* r = [RFRequest requestWithURL:[NSURL URLWithString:@"http://localhost:8000/"] type:RFRequestMethodPost resourcePathComponents:@"objects", @"", nil];
 
[r addParam:self.txtName.text forKey:@"name"];
[r addParam:self.lblDate.text forKey:@"date"];
 
[MBProgressHUD showHUDAddedTo:self.view animated:YES].labelText = NSLocalizedString(@"Submitting...", @"");
[RFService execRequest:r completion:^(RFResponse* response) {
	[MBProgressHUD hideHUDForView:self.view animated:YES];
 
	if (response.error) {
		UIAlertView* aiv = [[[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Error", @"") message:response.error.localizedDescription delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil] autorelease];
		[aiv show];
		return;
	}
 
	UIAlertView* aiv = [[[UIAlertView alloc] initWithTitle:@"Success" message:@"Success" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil] autorelease];
	[aiv show];
 
	[self.navigationController popViewControllerAnimated:YES];
}];

Similar to our previous snippet, but this time we also add some parameters to the request – name and date strings.

This is a brief overview with sample Xcode project of how RESTframework consumes RESTful web APIs. Questions welcomed via comments as usual.

 

Download project: RESTframework demo Xcode project download

REST framework for iOS is now Open Source

I have (finally) open sourced my RESTframework project on GitHub. It aims for simplicity of usage primarily. Querying RESTful web services is really easy now. Supported are iOS versions 4.0 and above and Mac OS 10.6 and above.

Feel free to fork & contribute!

RESTframework on GitHub

XCode 4 themes

I was searching for some cool XCode 4 themes I could use cause the default ones are pretty boring so I thought I’d share what I found with my readers.

My favorite (for now) is the Spacedust theme by m5h

Some other really interesting themes:

If you have an ‘old’ XCode 3 theme you’d like to use with XCode 4, I’m sure this will help.

Cleaning up XCode 4 user data from VCS (git)

If you use a version control system for your XCode 4 projects (and if you don’t I suggest you start) you’d probably want to keep your VCS state clean and omit committing user specific settings/files that XCode automatically creates. With XCode 3 you were probably adding *.mode1v3 and *.pbxuser files and now the .xcodeproj structure has changed so you need to modify your source control ignore files to include these new files. This simple how-to will use Git as an example but the logic applies to almost any other version control system.
XCode 4 project file now stores a special folder called “xcuserdata” amongst other folders (“xcshareddata” to name one). While xcuserdata contains user specific files that you probably want to ignore, xcshareddata contains project settings that are project specific and does not relate to users so it’s a good idea to keep that one. If you decide to delete that one, the worst thing that will happen is that you will need to recreate your project schemes. So, to keep your current build schemes pay attention to the order of the things I’m going to do.

Make your schemes “shared”

If you don’t want to lose your schemes, first you need to make them shared so you can safely ignore/delete your personal settings. To do this, go to Editor->Edit Schemes… and from the opened dialog choose “Manage Schemes”. >

XCode Edit schemes

Edit Schemes

 

Shared Scheme

Shared Scheme

Add user specific filename patterns to ignore files

Now you can ignore all those files. To do this, you simply add patterns to the .gitignore file (or your vcs of choice alternative). With Git we can do this:

echo *.mode1v3 > .gitignore
echo *.pbxuser >> .gitignore
echo *.xcuserdata >> .gitignore
echo .DS_store >> .gitignore

The first two are XCode 3 specific so if you don’t plan on using it – you can ignore these 2. The next file is XCode 4 specific and lastly I added OSX noise files as well. And that’s about it for this simple post, hope someone finds it useful.

Some XCode 4 tips

Apple kind of surprised me with releasing the XCode 4 along with the iOS 4.3. Honestly, I wasn’t expecting it until later this year or at least until iOS 5 was announced. But I’m glad it’s out, of course, and I already switched to using it vs XCode 3. I held back from trying out the beta versions so the experience was really exciting to me when I first tried it. Completely different experience compared to version 3.x and finally a single, fullscreen window. Pretty cool.

Anyway, I’m not going to review it as there are lots of reviews, I’m just going to point out a few things that I ran into while testing the last few days.

How to enable LLVM in XCode 4

By default, XCode uses a GCC kind of wrapper for LLVM so you’ll probably want to enable LLVM compiler and you can do that easily enough in build settings like so.

Now that you enabled that naturally you want to enable LLDB too. LLDB is a debugger, it’s to LLVM what GDB is to GCC. To enable LLDB you need to choose “Edit Scheme” from the “Product” menu and for the “Run” phase you’ll see a debugger chooser dropdown. However, at this point for iOS projects you’re stuck with GDB as the LLDB is only available for Mac apps and not available for iOS, yet.

How do I add existing frameworks to the XCode 4 projects?

“Add the existing framework…” right click menu option is gone. So how do you add existing frameworks?! The option is there of course, it’s just a bit hidden. The trick is to open target settings and navigate to the “Build Phases” tab. There’s a section that says “Link binary with Libraries” and that’s our X. See below.

Add existing frameworks

Add existing frameworks

So, should I switch to XCode 4?

Yup. I was in doubt and thought it might be a good idea to hold off of it for a while, at least until the next version but I tried it and found nothing that stops me from using it. In fact, I’m so pleased I’m having a hard time coding some legacy projects in XCode 3. I would suggest, though, to keep the version 3.x and install XCode 4 in a separate directory just in case…

UPDATE:

Where do I set NSZombieEnabled?

Got another tip here, it’s moved to a different place now. You need to choose “Edit Scheme” from the “Product” menu and you’ll find it there.

Edit Scheme Xcode 4

Edit Scheme Xcode 4

Simple UIView transitions animation using blocks in iOS 4

UIView’s sweet animation capabilities we were used to in pre-iOS 4 are now deprecated and Apple suggests we start using blocks which is far more convenient and simpler way of achieving the same thing. I’ll demonstrate how to make a simple UIView transition using new blocks based API vs using the old non-blocks way.

Our Goal

is to make an UIView curl up & down when adding and removing to a superview like shown below.

UIView page transition

UIView page transition

The Old Way – using +beginAnimations:context:

The old way code, using UIView’s class methods +beginAnimations:context: was simple enough and the code looks like below.

[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.5];
[UIView setAnimationTransition:UIViewAnimationTransitionCurlDown 
                                      forView:containerView cache:YES];
 
[containerView addSubview:subview];
 
[UIView commitAnimations];

Using blocks based API

Recommended usage of blocks API would change this code snippet to something like this.

[UIView transitionWithView:containerView duration:0.5
		options:UIViewAnimationOptionTransitionCurlDown
		animations:^ { [containerView addSubview:subview]; }
		completion:nil];

Now, this is all quite simple, nice & cute yet problems are likely to arise and you end up without animations. I’ve run into this myself, the problem is that one can easily make a mistake of passing options argument of the wrong type. The old way required UIViewAnimationTransition for transition argument while the blocks based API requires UIViewAnimationOptions for options argument. These are, obviously, completely different types but because they are both enum’s (int’s) you won’t get a compiler warning from XCode and if you mix them up you can spent quite some time trying to figure out why your animation doesn’t appear. Moreover, XCode’s autocomplete doesn’t even offer UIViewAnimationOptions when auto-completing. It tricked me and I was bumping my head why a perfectly good piece of code wouldn’t work.

All in all, make sure you don’t mix UIViewAnimationOptions with UIViewAnimationTransition when using transitionWithView:duration:options:animations:completion: method! I hope you enjoyed this mini tutorial for beginners, the XCode demonstration project is below.

UIView transitions animation XCode demo project.

Duplicate symbols when linking ObjectiveC static libraries

When you link a static library that’s using ObjectiveC categories, you usually have instructions from the developers to add -ObjC and -all_load linker flags which solve linking problems and prevent crashes. Now, if you happen to have the same categories or other objc symbols in your project that uses this static library you’ll get linker errors for duplicate symbols. The most common example for this is using touch JSON framework. I have this static library that uses it, and I also use it in my own code. I’m running into this linking problem every once in a while so I’m going to explain it here and provide a solution for fixing/avoiding it.

The Problem

Command /Developer/Platforms/iPhoneSimulator.platform/Developer/usr/bin/gcc-4.2 failed with exit code 1

ld: duplicate symbol _OBJC_METACLASS_$_SBJSON in /Users/ivan/Projects/MyApp/sources/Trunk/MyApp/libtest-simulator.a(SBJSON.o) and /Users/ivan/Projects/MyApp/sources/Trunk/MyApp/build/MyApp.build/Debug-iphonesimulator/MyApp.build/Objects-normal/i386/SBJSON.o

WARNING: I’ll be talking about problems with touch JSON library because this is the common problem. Solutions may not apply to other libraries although the principle is more-less the same. Be warned.

Scenario #1

“My project uses 1 static library and both this library and my project need JSON framework”.

Simplest solution that might work is to remove -ObjC and -all_load linker flags. When I say ‘might’, I mean that you need to be extra careful with this. If you do this, the static library you link will depend on JSON code from your project so if there’s, for example, a version mismatch you’ll run into serious problems.

LInker Flags in Xcode

Linker Flags

Scenario #2

“My project uses a static library which depends on JSON framework but this library also links other ObjectiveC static libraries. Both my project and this static library need JSON framework”

OR

“I cannot remove -ObjC and -all_load because I need to properly link categories inside a static library, but I also need to add JSON framework to my own project”

Now this is a specific scenario I ran into earlier. I wanted to use Three20 library which links several different ObjC libraries of its own so I definitely need -ObjC and -all_load flags otherwise my app crashes. On the other hand, I had another static library which uses JSON framework and adding this framework to my project causes duplicate symbols linker error.

The solution is simple again but you also need to be extremely careful. You leave those linker flags to properly link ObjC libraries but you don’t add JSON framework in your project. Instead you depend on JSON library linked with the static library you are using. You will, however, need to add header files in order to avoid compilation errors in your own code. Possible problem here is header files vs. compiled code in the static library mismatch. So you need to make sure that the JSON header files you’re using match the JSON code version linked with the static library. If you already imported JSON framework, just remove .m files in XCode from your target.

JSON framework xcode

JSON framework files

Bottomline

Obviously, these are some rare cases of linking problems however, JSON touch framework is a very popular framework and it’s not uncommon that some 3rd party libraries you want to use are built on top of it. My final advice is to understand the problem and why it happens, then you will be able to solve it one way or the other. Good luck!

6 Useful Objective C & Cocoa macros

Here are a few useful cocoa & cocoa touch macros that I’ve come across and thought I share here. Some of those I use regularly and some I just know about but you may find them useful.

Hex (HTML) color to UIColor macro

I found this macro a long time ago somewhere and I’m not sure what’s the original source, yet the Google search returned this blog so I’m going to give him the credit.

#define HEXCOLOR(c) [UIColor colorWithRed:((c>>24)&0xFF)/255.0
                                  green:((c>>16)&0xFF)/255.0
                                     blue:((c>>8)&0xFF)/255.0 \
                                    alpha:((c)&0xFF)/255.0]
//usage
UIColor* color = HEXCOLOR(0xff00ff00);

Enumerating collections macros

The following macro helps you with fast enumeration over collections, credit goes to Wincent.

#define WOEnumerate(collection, object)                                     \
for (id enumerator = [collection objectEnumerator],                         \
     selector = (id)@selector(nextObject),                                  \
     method = (id)[enumerator methodForSelector:(SEL)selector],             \
     object = enumerator ? ((IMP)method)(enumerator, (SEL)selector) : nil;  \
     object != nil;                                                         \
     object = ((IMP)method)(enumerator, (SEL)selector))
 
#define WOKeyEnumerate(collection, object)                                  \
for (id enumerator = [collection keyEnumerator],                            \
     selector = (id)@selector(nextObject),                                  \
     method = (id)[enumerator methodForSelector:(SEL)selector],             \
     object = enumerator ? ((IMP)method)(enumerator, (SEL)selector) : nil;  \
     object != nil;                                                         \
     object = ((IMP)method)(enumerator, (SEL)selector))

Logging macros

CMLog - use to extend NSLog functionality.

#define CMLog(format, ...) NSLog(@"%s:%@", __PRETTY_FUNCTION__,[NSString stringWithFormat:format, ## __VA_ARGS__]);
 
//usage
CMLog(@"My iPhone is an %@, v %@", [[UIDevice currentDevice] model], [[UIDevice currentDevice] systemVersion]);

MARK - method stamp macro, use to output class and method name.

#define MARK	CMLog(@"%s", __PRETTY_FUNCTION__);

Benchmarking macros

Use START_TIMER and END_TIMER to get the timing between these two calls.

#define START_TIMER NSTimeInterval start = [NSDate timeIntervalSinceReferenceDate];
#define END_TIMER(msg) 	NSTimeInterval stop = [NSDate timeIntervalSinceReferenceDate]; CMLog([NSString stringWithFormat:@"%@ Time = %f", msg, stop-start]);
 
//usage example
- (NSData *)loadDataFromURL:(NSString *)dataURL
{
  START_TIMER;
  NSData *data = [self doSomeStuff:dataURL];
  END_TIMER(@"loadDataFromURL");
  return data;
}

Logging and benchmarking macros, courtesy of Stephan Burlot.

UIView frame (CGRect) macros

And for the end, here’s my own modest addition to the list. When developing an iPhone or iPad apps, you probably found yourself lots of times working with UIView frames, changing them etc… Often times I just change the UIView size or I just need to move it around the screen, reposition the view and each time I need to do CGRectMake etc… The following macros have helped me and saved me some typing.

#define width(a) a.frame.size.width
#define height(a) a.frame.size.height
#define top(a) a.frame.origin.y
#define left(a) a.frame.origin.x
#define FrameReposition(a,x,y) a.frame = CGRectMake(x, y, width(a), height(a))
#define FrameResize(a,w,h) a.frame = CGRectMake(left(a), top(a), w, h)

Obviously you can do the same for UIView ‘bounds’ instead of ‘frame’.

Reusing code with Snippets for Mac

I was never a fan of any snippets tools for development, it may be because I never came across any descent app and maybe I didn’t even need one. One thing is sure, while coding, I always have several projects opened and I’m copy/pasting code like crazy all over them. So I guess I do need one after all. Recently I stumbled upon a very nice app called Snippets for Mac and I decided to give it a try.

What I need from this kind of app is:

  1. to integrate nicely with my Mac OSX desktop
  2. have a clean and nice GUI
  3. provide the best user experience

These are 3 most important features I need and the last one is crucial. Snippets app manages to get good ratings here. Snippets app does everything you’d expect from this kind of app: searching, syncing, easy access etc..

Snippets app has a very slick interface as you would expect from a modern Mac OSX app. Main window has a library tree view, along with the highlights and groups on the left and code editor on the right. GUI is pretty much straight-forward and you can easily add new snippets or select existing ones.

Snippets Main Window

Snippets app main window

Editing snippets is just as easy and what I like about it is that you can use different editors launching from within the app. From toolbar, you can choose whether you want to edit the snippet in XCode, Coda, TextEdit or other editors of your choice.

Choose editor for a snippet

Choose editor for a snippet

Now, ‘integration’ with the actual editors/IDEs where one does coding is the most important part. This is where snippets bought me. While it doesn’t integrate with IDEs per se (you can easily copy code from its main window), it’s much easier and quicker to do it from the tray icon either by clicking on it or using a global shortcut which is quicker and you can insert a snippet without loosing focus in your code editor. Either by clicking the tray icon or using a global shortcut,  you quickly get a list of search results and you can add the code momentarily.

Adding snippets

Inserting snippets

Another great feature is that highlighting a search result shows a tooltip with the code that snippet holds. This is very useful because sometimes I name snippets similarly or even forget what it has.

The app does satisfy my needs as a simple snippet manager and provides me simpler way of reusing my code than to browse around my old projects and copy/pasting code. I’m still in my trial period and deciding whether or not this software is worth the money ($39,95 at the moment, comes with 30 day trial) but it is being useful no doubt about it. I suggest you take it for a spin and see if it fits you.

Snippets website / download

Snippets for Mac

Consuming ASP.NET web services in iOS part 2

In previous blog post I’ve explained how to create iOS friendly ASP .NET web service with JSON RPC so now we’re going to take it further by creating an iPhone app that will consume this web service. Since iOS natively does not support JSON, we’ll be using this nice JSON framework available on Google Code here. This framework provides NSObject categories which allow simple JSON parsing and and it’s really convenient to use with iOS SDK. Other than that, we’ll be using native iOS SDK APIs only to create HTTP connection and query our JSON RPC service. Calling this web service is done by creating NSURLRequest with HTTP POST method and passing method name, method parameters (arguments) and identificator. NSURLConnection uses this request and does the magic we need. Let’s see the code.

First, we need to create JSON string which we’re going to POST to our RPC service. We do this by simply creating a dictionary and breaking it down to JSON representation.

 
//RPC
 
NSMutableDictionary* reqDict = [NSMutableDictionary dictionary];
 
[reqDict setObject:methodName forKey:@"method"];
 
[reqDict setObject:parameters forKey:@"params"];
 
[reqDict setObject:identificator forKey:@"id"];
 
//RPC JSON
 
NSString* reqString = [NSString stringWithString:[reqDict JSONRepresentation]];

We should note 3 arguments we’re posting to the service – method, params and id. Method is RPC method name as declared in JSON RPC web service. Params are arguments this method requires and ‘id’ is the call identifier which RPC call returns when sending back response and it’s used to link the response to the request in case you’re sending out multiple requests. In our case, the method name is ‘HelloWorld’ without arguments and as the identifier we’ll just put 1.

So now we create NSURLRequest and NSURLConnection using this reqString. This is the main part of code so pay attention.

 
//Request
 
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url];
 
NSData* requestData = [NSData dataWithBytes:[reqString UTF8String] length:[reqString length]];
 
//prepare http body
 
[request setHTTPMethod: @"POST"];
 
[request setValue:[NSString stringWithFormat:@"%d", [requestData length]] forHTTPHeaderField:@"Content-Length"];
 
[request setValue:@"application/json" forHTTPHeaderField:@"Accept"];
 
[request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
 
[request setHTTPBody: requestData];

First we create a mutable url request, set it’s HTTP method to “POST” and fill out other HTTP specific header fields. Finally we set our JSON request string as HTTP body.

Now we simply create NSURLConnection, assign a delegate to it and wait for our data.

 
urlConnection = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:YES];
 
[request release];

The delegate part of the calling object has these methods defined.

#pragma mark -
#pragma mark NSURLConnection delegate
 
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
	NSLog(@"Did receive response: %@", response);
 
	[webData release];
	webData = [[NSMutableData alloc] init];
}
 
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
	assert(webData != nil);
	[webData appendData:data];
}
 
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
	[webData release];
	webData = nil;
	[urlConnection release];
	urlConnection = nil;
 
	UIApplication* app = [UIApplication sharedApplication];
	app.networkActivityIndicatorVisible = NO;
 
	//notify
	[delegate loadingFailed:[error localizedDescription]];
}
 
-(void)connectionDidFinishLoading:(NSURLConnection *)connection {
	[urlConnection release];
	urlConnection = nil;
 
	UIApplication* app = [UIApplication sharedApplication];
	app.networkActivityIndicatorVisible = NO;
 
	//DO something with webData
	[delegate dataLoaded:webData];
 
	[webData release];
	webData = nil;
}

Once the connection gets a response we create NSData (webData) and we append bytes to it in didReceiveData callback. In the end we either get didFailWithError or didFinishLoading and take actions accordingly.

Finally, the app would return something like this when launched.

iPhone calling JSON RPC web service

iPhone JSON RPC

For your convenience, I have attached XCode project for download. Please note that this is an example only and should be treated as such, I don’t provide guarantee of any kind for this code.

JSON RPC iOS example project