Thursday, May 14, 2015

I ripped out RestKit and replaced it NSURLSession and Mantle

When I started at my current job I knew I would be doing a lot of REST interaction with the server. I decided to use RestKit as I had seen it mentioned a number of times in various developer forums.

It worked for some time but I finally hit the breaking point and ripped it all out changing 265 to convert them to NSURLSession and Mantle. Was I insane? Pretty much as in the end it did not solve the problem I was originally attempting to address but I am happy with the change.

First off Mantle makes it much easier and cleaner to handle JSON. It is not as easy as GSON on the Android side but it is not too bad. That was a lot of my file conversions and I do find it easier to add a new JSON object due to a new REST call to the server. The one downfall is each of your JSON receiving objects has to be derived from a Mantle class. Objective C does not support multiple inheritance which could make this a very limiting factor for you.

The other area I am not too happy about with Mantle is it handles converting NSDictionary and NSArray to JSON. That means I get a big JSON string from REST and then I use NSJSONSerialization to convert it into a NSDictionary and then convert that via Mantle to Objective C objects. Waste of memory and processing to double convert things. Good thing the JSON data is reasonably small.

The other side was getting rid of RestKit calls. This helped the code a lot. I had one REST call manager class that tried to handle all the server calls with delegate callbacks. Now all the calls are inline where they are called in the code and that code has block processing to handle the results. This lets you see what is going on easier. Plus if it is a PUT call I only have to reference PUT in one line of code whereas I had to do that in three places when using RestKit. Setting up each call in RestKit took a boatload of error prone boilerplate code. I sure as heck don't miss that.

So why not go with AFNetworking? Seems to also be popular but in the end even AFNetworking is using NSURLSession in the end. Apple seems to put together a decent networking package learning from others. One less pod to include in my build and hopefully using the official Apple networking that appeared in iOS 7 will keep me in the safe zone.

On the Android side I am using Volley and GSON, both from Google but not part of the base Android SDK. Volley is very similar to NSURLSession which is good. GSON is easier to work with than Mantle in there is less boilerplate code. If your variable names match the property names in the JSON you get from the server there really is no boilerplate at all. If they don't match a simple annotation gets them to sync up.

So what was the original issue I was attempting to fix? I want to have two type of NSURLSessions going in the code, one to do the normal user interaction processing - they tap something, I make a server request, I get server result and I show new data in the current view or in a new view. The second was to be a background session for uploading video via Amazon Web Services.

I am using AWS but I am using the straight API from them. Yes, there is sample upload in the background code out there and it works when you don't have the other NSURLSession doing other work which really stinks. I want the user to be able to start a video upload and have it run in the background until complete even if they leave my app or turn off the phone screen. Works like a champ on the Android side where I set up a very basic service.

I realize Apple really does not want you do to anything in the background. They trust no one. They do have a new thing that lets you get maybe 10 minutes of time to do some background work. That is one of the things NSURLSession is set to allow. But I just can't get it to work. It will start, send up some % of the video then restart at 0% and do that over and over again. On the simulator, which does not run like a real device, it can get the whole video uploaded never triggering the restart you see on the iPhone or iPad. I have posted a message on Stack Overflow describing this issue but no answers.

I really wish Amazon would handle this for you in their API. Seems like background uploading would be a really common thing for a programmer to want to do with them. Maybe Apple could handle it in their API as well but I doubt that as they are anti-background as it is.