restkit

RestKit is an Objective-C framework for iOS that aims to make interacting with RESTful web services simple, fast and fun. It combines a clean, simple HTTP request/response API with a powerful object mapping system that reduces the amount of code you need to write to get stuff done.
—  RestKit
Integrating RestKit, CoreData and CDQ with a RESTful Rails back-end

Over the Xmas break I’ve had some time to work on a gem that I hope can help RubyMotion (iOS) devs more easily integrate their front-end with a RESTful Rails back-end. 

The result is Restikle. On the surface it’s simple (or at least I hope it is) in that it allows you to create a CDQ schema file by parsing a Rails schema.rb along with the output of rake routes. From there, you can automatically configure RestKit at runtime to creating request and response mappings for all of the specified resources. It’s designed to save a whole lot of time and boilerplate code.

This is a really, really early 0.0.1 release of the gem to get the ideas out there. Please let me know if this is of interest to anyone, or if you think it can be improved.

SIX! How CoreData Works with RestKit

Yesterday, we worked all day as usual on our personal projects, and during the last hour, we all demo’d our apps to one another to get a glimpse at what the rest of the class was working on and to give us the experience of having to answer questions. Everyone seemed to have a really cool and interesting project going on, which was wonderfully exciting but also somewhat worrying - I didn’t feel like my project was really up to snuff during the presentations, largely because instead of implementing sparkly features, I spent long hours over the past two days struggling (successfully) to get a better understanding of some tricky concepts, namely authentication and data stores. I’ll share my painstakingly newfound knowledge here in its simplest form.

There is no concept of a session in iOS, but there is authentication. With RestKit, you will basically send your credentials to the server every single time you make a request, and the server will validate you for the request. If the backend uses AuthLogic, as mine did, it by default finds the current_user (which it uses to validate) through the user_session, which doesn’t get created by the iOS app, so after hours of trying various things, it became clear that this was where a change had to be made, and I had to redefine “current_user.”

I also spent a very long time switching my data pattern over form RestKit-based dataStores to internal CoreData files, so that the app will fetch all the current data from the web when it has internet connection, but it will also cache everything it brings down so that you can  still see all the records when you are not connected. The reason that it took a long time and a lot of headaches for me was that I was unable to find the basic data-flow explained before I dove in, and a lack of the big picture when it comes to intricate processes like data flow can lead to a lot of inefficient design decisions and bugs. I drew the picture above in order to perhaps save someone else the heartache.

Well, six days left and then it’s all over for this batch of App Academyists. I’m so excited and scared that I won’t have anything to show! But I’m really happy for all of my classmates and the amazing things we have made as a group, so I can’t wait to see how the endgame plays out. All right, time to get back to work!

Day 57 - Down to the Wire

With only 3 days left before interview day, every minute counts.  That’s why it was particularly painful to find myself stuck on the same problem for the first 4 hours of the day.  I had thought it would only take half an hour to set it up so that when users submit new questions they’d first be saved to core data and then the objects would be posted server side.  Unfortunately, this is simply the way things go sometimes. You think something will be simple and it just isn’t. Or, it is, in the end, but figuring out the simple way isn’t simple.

What took me so long was correctly mapping my objects with restkit when posting them to the rails backend. The difficulty is that the questions and answers are related to one another via the question’s object id which is assigned to it on the backend. Thus, when the objects are initially created on the frontend, that question’s object id doesn’t exist yet. To fix that, restkit provides some nifty methods to post the object to the backend, then update the same object with the response that is given from the post request. Of course, it does not provide equally nice documentation for discovering this. In fact, restkit’s documentation is a bit of a train wreck.  It’s also only on version 0.1, which suggests the creator considers it to be in a very early stage of development and as such, developers should be a bit wary using it.  

After I finally got all of that taken care of, I spent a little time sprucing up the overall look and user interface of the app.  I think it looks ok right now which is about as good as I can hope for by Friday.  In addition to the appearance, I added a few small features, such as preventing the user from saving a form with blank fields and now the user is displayed an alert view whenever they submit a question.

For the last 5 or so hours, I’ve been working on setting it up so users can answer questions, and those answers are recorded both in core data and on the backend.  I got it working, which is pleasing, although right now users can answer the same question more than once and instead of updating their previous response it adds a new one.  Fixing that should be easy enough and will be my first task tomorrow. 

Using RestKit to connect an iOS+RubyMotion+CoreData+CDQ app to a RESTful back-end

I’m in the process of moving a reasonably large iOS code base (across three apps) from a set of hand-crafted POROs that are converted to and from the REST back-end by bespoke code, over to use CoreData and CDQ (in RubyMotion). For the uninitiated, RestKit has some rather complex bits and pieces of setup, that to be perfectly honest, I’m struggling to get right.

In the process of understanding what’s going on, I’ve collected a bunch of references to blog posts and tutorials that I am ploughing through. On the off chance that some of this research might be useful to someone else, I’ve attached a set of links here:

Introduction to RestKit 0.20

RestKit Tutorial Code For Version 0.20

RestKit Wiki

RestKit Object Mapping

Getting Acquainted with RestKit

Developing RESTful iOS Apps with RestKit

iOS SDK: Advanced RestKit Development

I’ll update this list as I find more. In the meantime, I’ve also posted my current problem over on the RubyMotion Google Group here.

UPDATE1: Aha! Fixed it! The problem was using addAttributeMappingsFromArray for all fields in the class, instead of making sure to use addAttributeMappingsFromArray for simple types, and addPropertyMapping for complex types. Ok, next battle …

UPDATE2: This cost me about 24 hours of random, unpredictable crashing. Apparently, there’s some exception thrown deep in the bowels of the Google Analytics iOS SDK that ends up throwing things into total chaos, which usually results in the app dying a cold, slow death after the UI hangs and becomes unresponsive. The solution, is to make sure that when you add an observer for NSManagedObjectContextDidSaveNotification, that you limit the scope to the entity context you are interested in, and not just use nil like I did, which gives you global notifications. 

Getting RKLogConfigureByName working in RubyMotion

Just a quick note, I was getting an undefined constant error for RKLogConfigureByName, the standard way of setting up logging in RestKit. It seems that the #define statements in the /vendor/Pods/RestKit/Code/Support/RKLog.h file are not getting picked up. I am using the pod and loading with RubyMotion pod support, so Iåm not sure what the issue is. I will need to investigate further but this quick workaround works, just call the lower-level method mapped via the #define. For example instead of RKLogConfigureByName use RKlcl_configure_by_name. I also list all the RKlcl_v constants to use instead of the RKLogLevel constants. I also included an example of how they are used, in this case I have put the setup in a method, and it gets called from the the standard didFinishLaunchingWithOption application block.

https://gist.github.com/4733618
How to tell if a RestKit request failed due to a timeout
- (BOOL)isRestKitTimeoutError:(NSError *)error
{
    return [error.domain isEqualToString:RKErrorDomain] &&
        error.code == RKRequestConnectionTimeoutError;
}

A place you might use this is in request:didFailLoadWithError: when adopting the RKRequestDelegate protocol.

How I use (and abuse) RestKit.

What is RestKit?

RestKit is an open source framework designed to make consuming RESTful API’s easy. Which thankfully it does fairly well. Just point it at a URL, do some simple JSON to object mapping, send off an asynchronous request and sit back as your response is turned into a tidy object. However the examples provided, much like Apple’s, leave something to be desired. The examples assume you know MVC and will use it instead of slapping everything in the App Delegate. But even if you keep your classes loosely coupled it still takes a moment to figure out how to divide responsibility when using RestKit.

I don’t have all the answers because the best parts of my RestKit setup I picked up from Taras Kalapun. If you follow his example though I would advise you to not use dependency injection because well not only does Objective-C have late binding, it has dynamic binding. Also Taras’ podfile in his blog post is outdated as I’m using RestKit 0.10.1 in this post.

Setting Up RestKit

First add RestKit to your project by adding it to your Podfile using CocoaPods. Run pod install, open the workspace file and not the project file then add <RestKit/RestKit.h> to your App Delegate and run. If everything installed correctly then you shouldn’t see any errors.

platform :ios pod

‘RestKit’, ‘0.10.1’

Object Mapping

Next configure the Object Manager by setting a base url and MIME types. Now this is where we diverge from the example. Instead of throwing all the details of our object mapping into the App Delegate we will increase our data model classes’ cohesion by making the mappings a class method. This could probably be cleaned up a little more but it is already much better than the example because we now have one less file to change when we need to change our object’s properties.

We also added the serialization mapping and the routes so that with these few lines we only have to tell our object loader if we want to GET, PUT, or POST.

Error handling

Now RestKit used to handle both ‘error’ and ‘errors’ messages but after 0.10.0 was introduced they improved object mappings by giving errors their own context however it is difficult to map two top level key paths with the new code. Check out my StackOverflow post about this if you want to learn to support Rail’s pluralization of both errors and error.

[[objectManager.mappingProvidererrorMapping] setRootKeyPath:@"errors"];

Object Loading

I’m going to skip user authentication right now because it is more dependent on your setup and honestly I don’t like the way I’m handling it myself right now.

Usually the next step is to setup a basic UITableViewController and send a request to populate the table view on viewDidAppear but first we will setup up an intermediate object to handle fetching and storing our objects. This is important because once we separate this functionality we will be able to share this intermediate object between classes such as a table view and a map view. If you have more questions about this you can check out Matthijs Hollemans excellent post about how to make your classes talk to each other.

There are a couple of things going on here. First we are hiding the actual data structure that is holding the articles. Who knows we might use a set to store articles later. Next we are recieving parsed objects from RestKit and making a mutable copy so we can easily change it later. Then since in this case we are able to check the previous existence of an article we only have to make one public method for saving an article. Since we specified our routes before we just have to tell the object manager if we want to put or post our article. You will also notice that with the block notation I’m creating a weak reference to self and checking it to make sure it exists for use in our blocks to prevent retain cycles.

Object Interfacing

This last part isn’t too interesting but I’ll show it anyways. First you can refresh your data controller or data source with this method. You’ll notice that the since our data controller takes a block argument it is easy to do things like showing an activity indicator, refresh your view on completion or show an alert on error. Then you can simply access the data controller from your view controller or turn it into your view controller’s data source and move this last method into your data source. Lastly you could bind your views to your model using Reactive Cocoa but thats another blog post.

OAuth support in iOS
One of the hardest things to find in iOS is support for authentication methods like OAuth. While there are many solutions one of the best in my opinion is the RestKit framework. Why? For three reasons:
  1. The ability to call restful webservices using a client which parsers JSON and XML answers directly, through SSL or HTTP Auth.
  2. Core Data support, which means you can locally persist the data received.
  3. Domain Data Object support is another killer feature. In other words, you can map JSON or XML answers to domain objects.
While this sounds like the perfect solution, is more often see API using OAuth as an authentication method and this framework unfortunately did not have support. … until now! The solution? I’m not about to complain about the lack fo support so worked on a fix which then I was able to contribute the code back to the project. I forked their repository and added the support. While I am waiting the patch’s acceptance, you can use the code available in my personal repository.
  1. Grab the framework from my fork, and configure everything according the installation instructions.
  2. Use it in your controllers or delegates, next there is an example.
    1. OAuth 1 support:[c language=”++”]
      RKObjectManager* objectManager = [RKObjectManager sharedManager];
      objectManager.client.baseURL = @”https://api.twitter.com”;
      objectManager.client.consumerKey = @”YOUR CONSUMER KEY HERE”;
      objectManager.client.consumerSecret = @”YOUR CONSUMER SECRET HERE”;
      objectManager.client.accessToken = @”YOUR ACCESS TOKEN HERE”;
      objectManager.client.accessTokenSecret = @”YOUR ACCESS TOKEN SECRET HERE”;
      objectManager.client.forceOAuthUse = YES;
      [/c]
    2. OAuth 2 support:
      [c language=”++”]
      RKObjectManager* objectManager = [RKObjectManager sharedManager];
      objectManager.client.baseURL = @”YOUR API URL”;
      objectManager.client.oAuth2AccessToken = @”YOUR ACCESS TOKEN”;
      objectManager.client.forceOAuth2Use = YES;
      [/c]

As you see, I still need to develop the code for the handshaking process, but in the meantime you can start to consume webservices and enjoy the domain data support of this framework. Comments and improvements to the code are always welcome!

iOS Development - Adding Flurry 4.0 to your project

Recently I have started on the development of AppPlayground, an iPad application that I’m working on for my startup. (stayed tuned)

Anyways to start it off I added several frameworks that we will be using for the app. 

1. Parse (for storing user data)

2. Flurry (for analytics)

3. RestKit (for server communication)

4. SDWebImage (for asynchronous image downloading)

Out of these frameworks I didn’t have trouble with integrating any of them except for Flurry 4.0. The documentations for Flurry 4.0 is not updated and I had to look around for quite a bit to get it working. For this post I’ll explain how to add Flurry 4.0 into your project and hopefully that will save some of your time.

So in terms of how to get Flurry working just follow the following steps:

 1. Drag the liFlurry.a and Flurry.h into your project (I put it under the Frameworks folder).

 2. Then you must click on the libFlurry.a file and open up the file inspector.

 3. Under identity and type change the File Type to Mach-O object code.

 4. Make sure that under Target Membership you checked your project, not your Test project (I made this mistake). 

 5. After that you will also need to add the CoreLocation.framework in the Link Binary With Libraries section in your application’s Build Phrases.

NOTE: Also for SDWebImage and RestKit remember to add them to your project using submodules (also any other git frameworks)! I never knew about it before but submodules are very useful for adding frameworks into your existing project.

Restkit: Kit for Pythonic HTTP

Restkit[http://benoitc.github.com/restkit/]

Restkit is an HTTP resource kit for Python. It allows you to easily access to HTTP resource and build objects around it. It’s the base of couchdbkit a Python CouchDB framework.
You can simply use request function to do any HTTP requests.

Features

  • Full compatible HTTP client for HTTP 1.0 and 1.1
  • Threadsafe
  • Use pure socket calls and its own HTTP parser (It’s not based on httplib or urllib2)
  • Map HTTP resources to Python objects
  • Read and Send on the fly
  • Reuses connections
  • Eventlet and Gevent support
  • Support Chunked transfer encoding in both ways.
  • Support Basic Authentification and OAuth.
  • Multipart forms and url-encoded forms
  • Proxy handling
  • HTTP Filters, you can hook requests in responses with your own callback
  • Compatible with Python 2.x (>= 2.5)
RestKit RKClient -[NSURL queryPamaeters]: error in iOS5 ARC enabled code.

Following this tutorial we first went through this implementation of RestKit Framework for our many REST enabled web-services. The implementation was straight forward for many cases and it was working with ease until we encountered a specific error.

it was for iOS5 ARC enabled project that was the Rest Kit protocol the error was

-[NSURL queryParameters]: unrecognized selector sent to instance 0xa812580

and the app crashed. After searching the internet for several hours and then working our way through the application we just had to edit a few parameter in the Targets-> build Settings —> other Linker Flags

As specified in the Rest Kit Tutorial we changed added a flag called “-ObjC-all_load” now edit that to just display “-ObjC” and then the application works like a charm. 

Hope this helps those people who are facing this issue in the future.

Configure RestKit internal logging

For my test cases I needed to disable all internal logging from RestKit. Put these lines early in your code:

RKLogConfigureByName("RestKit/Network", RKLogLevelCritical); RKLogConfigureByName("RestKit/Network/Reachability", RKLogLevelCritical); RKLogConfigureByName("RestKit/Network/Cache", RKLogLevelCritical); RKLogConfigureByName("RestKit/Network/Queue", RKLogLevelCritical); RKLogConfigureByName("RestKit/CoreData", RKLogLevelCritical); RKLogConfigureByName("RestKit/ObjectMapper", RKLogLevelCritical); RKLogConfigureByName("RestKit", RKLogLevelCritical);