Author Archives: josh

Quips: Hackathon #2 Recap

It’s been a while since our last hackathon, so we were excited to do another to end the year 2011 at Miso. In the 6 months since our last hackathon, the team at Miso has grown significantly and that has allowed us the option to split into two different teams to work out on separate ideas. I got placed on the Quips team, so that’s what I’ll be talking about today.

What is Quips?

Have you ever hung out with friends, and someone said something so hilarious you wanted to quote them on your social network of choice? That’s the moment we wanted to capture. Drawing inspiration from quote cards from Miso sideshows, we came up with an idea for an iPhone app that let’s you take a picture, slap a quote over it and share it over Twitter! Of course, what’s a photo sharing app without filters a la Instagram? We got that covered too. Our tag line? Appropriately: “Because your friends are hilarious”.

The Journey

The app took 5 of us just 3 days to complete. The team consisted of 2 shared designers (we had two teams), two engineers on iOS and one more on the backend server. Although a relatively simple app, from design and planning to execution, the whole process reminded me of those sleepless nights finishing senior design projects. The difference was that I had a lot of fun doing it, and the only thing that was on the line was my pride in being to do this in the short amount of time we had. At the end, we finished everything within 3 days, and submitted to the app store the day after. Overall it was a success and everyone in the office loved playing with the app.

Lessons Learned

Since it was the second hackathon I’ve participated in, a few mistakes were learned in the past and some news ones were made this time around. I thought it’d be helpful to share a few tips for those attempting a hackathon themselves.

Small and focused – Google wasn’t built in a day, so don’t expect that of yourselves. Avoid ideas where it involves hundreds and thousands of users for it to be worthwhile. Focus on a small idea, and make it awesome. The result will likely be more compelling.

Plan for the worst - I think it’s fair to say that most software engineers are terrible at estimating. Being one, I’m absolutely in love with the idea of building anything in the most ideal time frame. In reality, everything that can go wrong will go wrong when it comes to coding. Though we did a better job this time when it came to coming up with a reasonable design, we still ended up stripping out some parts to cross the finish line.

The devil’s in the details - It took us the first two days to have something somewhat functional, but another whole day to polish and make everything look good and work solid.

Have fun – It will be intense, but don’t let that stop you from exploring new ideas and learning new tools. We liked the Facebook/Path menu, but we didn’t know how it worked so we invested time into building it just for this. Sure it would have been faster going with UI elements we’re familiar with, but what’s the fun in that?

Quip it!

Funny story, we had to resubmit Quips to the app store due to a screenshot having the word “badass” on it. Apple likes to keep everything PG-13 apparently. The app is available in the app store. Go grab it and let us know how you like it!

Hybrid (Native + Web) Mobile App Development • Part 3: JavascriptCore and UIWebview optimizations

Part 3 is here! Yes, I’m back to writing more about hybrid framework goodness. Today I want to talk a bit about performance optimizations using a hybrid framework.

At Miso, we hold EJS templates on the device and combine it with JSON responses from the server to produce html rendered by a UIWebview. What we learned at F8 is that Facebook delivers the entire html from the server to the device directly. There’s some pros and cons to both approaches.

Miso’s EJS + JSON approach minimizes the payload coming back from the server by just asking for the JSON data. As long as you’re not freely including anything and everything in your JSON response, it should be a fairly small package. The downside however, is that your device would have to handle the process of combining the JSON data with the EJS template. This, in our benchmarks have shown to be fairly costly. Depending on the complexity, in the hundreds of milliseconds.

Facebook’s approach on the other hand leaves the processing all to the server so the device just needs to render the HTML response. This is beneficial especially for slower devices, but the payload coming back from the server is also much larger in comparison.

Both approaches are fine, I just wanted to point out the differences in them. Picking one over the other, like many other engineering decisions, depends on your use case.

Backgrounding EJS Processing

Everyone loves UIWebviews except for one thing. It’s SLOW. Rendering HTML blocks the foreground thread, and there’s simply nothing you can do about it. It was even worse for Miso because we did EJS processing on the foreground as well. Why not just background it? Well, long story short you can’t. The iOS javascript library is invoked from UIWebview (eg. [_webview stringByEvaluatingJavaScriptFromString:@"..."]). Even if you don’t perform any code that affects UI, iOS doesn’t allow you to background that process. To give you a taste of the distribution of processing time involved from start to finish:

EJS Processing – 50%
InnerHTML rendering – 40%
JSON data parsing – 10%

As you can see, backgrounding EJS processing would be a big big win for us. After a few hours of googling around for solutions, it became apparent that in order to accomplish this we will have to import our own javascript library to run in parallel with what iOS provides us. Fortunately, someone has already compiled a JavascriptCore library for iOS for their own purposes here. After successfully importing the library into the project, I wrote a lightweight singleton wrapper in combination with another interfacing class written by this fine gentlemen for you to background javascript by passing it a string.

I’ve open sourced the relevant code on github.

I was able to successfully background EJS processing this way, and boy was it worth it. The pause from foreground thread blocking became a lot more bearable for the cost of adding ~2MB to your binary size.

Making your UIWebviews faster

One of the biggest advantages of using UIWebviews is that you can use all the javascript/css goodness to make your views look tasty. However, as you may soon find out, the more css styling you add, performance starts to slow to a crawl. The most common symptom is that scrolling starts to feel very clunky and jerky. This is especially apparent on older iPhones such as the 3G. To figure out what is the biggest offender here, I went through and removed CSS stylings here and there to get a feel for performance impacts. What I found is that removing corner-radius and box-shadows makes the scrolling much smoother. This is not new as other sources have pointed out similar performance issues related to these new CSS3 features. Until they are addressed, use these sparingly and always try to benchmark with an older device.

If you’ve already stripped down your CSS and it’s still clunky, another factor to consider is sizing down image assets you are using on your page. During my performance tuning journey, to my embarrassment, I observed that Miso image assets were anywhere between 100% to a staggering 2000% larger than Facebook counterparts. We used a tool called Smusher and sized down all of our PNG images significantly. This was the last optimization I did that pushed performance across the finish line.

What I’ve learned through all this is that every bit of processing power should not be taken for granted on a mobile device. The motivation for making the app perform better came from trying to use it on my older iPhone 3G. Any mobile developer should have a base benchmark device to keep them honest. Until next time. Happy coding! :)

PS: If you have suggestions for topics that you want me to cover please feel free to share them in the comments section.

Objective-C Conventions

Writing code without conforming to some form of convention lends itself to a lot of confusion; Both for the code writer, and for someone else trying to understand your code. The pain worsens as the code base starts to increase in size, especially for a non-GC programming languages like Objective-C where memory management has to be cared for meticulously. Following a set of naming conventions for your instance variables, class names…etc. will help maintain a certain level of sanity. Here at Miso, we conform to a set of conventions that are partly derived from Apple standards, and partly from common best practices we’ve seen from other developers.

Class and Variable names

For variable names, Apple recommends starting with a lowercase letter (eg. UILabel *titleLabel). For class names, starting with a uppercase letter (eg. MyClass). Notice in the examples we also like to camel case the rest of the name.

iVars and local variables

One of the most common issues with a large class or viewController containing more than several instance variables is distinguishing them from a local variable within a function. What I like to do is prefix iVars with an underscore to distinguish them. (eg. _titleLabel)

- (void)createViews {
    // some bunch of code above
    UIImageView *imageView = [[[UIImageView alloc] initWithImage:[UIImage imageNamed:@"somepic.png"]] autorelease];

    [_containerView addSubview:imageView];
    [_containerView addSubview:titleLabel];
    // some more code below
}

In this example you can see that I don’t have to look at the header file to immediately tell that imageView and titleLabel are a locally defined variables, and that _containerView is an iVar simply looking at the name of the variables.

Starting with the Header File

When I approach designing a new class I like to start with the header file first. This is where you wireframe your code design without actually writing any implementation. Reason for this is because I like to start with what someone using this class would need. This means defining public class/instance methods, properties (public accessors), and instance variables. Let’s try this approach with an example. I love cats, so let’s go with that:

//
//  VirtualCat.h
//  Miso
//
//  Created by Joshua Wu on 8/12/11.
//  Copyright 2011 Miso. All rights reserved.
//

#import <Foundation/Foundation.h>

@interface VirtualCat : NSObject {
    BOOL _hungry;
    NSMutableArray *_foodHistory;
    NSString *_furColor;
    float _weight;
}

@property (nonatomic, readonly) float weight;
@property (nonatomic, retain) NSString *furColor;

- (id)initWithColor:(NSString *)furColor weight:(float)weight;
- (void)feed:(NSString *)food;

@end

Ok great! Here you can see that certain properties of this class is can be modified after instantiating. (furColor and weight) We also see that certain properties can’t be modified because public accessors were not defined. (hungry and foodHistory). I’ve also defined a constructor, and a instance method “feed”. For someone using this class, what they can do with this class is all nicely defined in the header file.

Private Interfaces

Using properties is great because you can use the accessors you get from it to assign new values to them without worrying about memory management. This is great for public properties, but what if I want to define private accessors to leverage the same convenience in my implementation file? This is what we can do:

//
// VirtualCat.m
// Miso
//
// Created by Joshua Wu on 8/12/11.
// Copyright 2011 Miso. All rights reserved.
//

#import "VirtualCat.h"

@interface Cat()

@property (nonatomic, retain) NSMutableArray *foodHistory;

- (void)askForFood;
- (void)sleepInBathTub;
- (void)meow;

@end

@implementation VirtualCat
@synthesize weight=_weight;
@synthesize furColor=_furColor;
@synthesize foodHistory=_foodHistory;

@end

By declaring an interface within the implementation file, you can assign private properties. I’ve also sneaked in some additional code in the private interface to demonstrate defining private instance methods. So far, we’ve done enough to define the blueprint of this class quite sufficiently without having written any implementation code! Yet, it is already clear what someone instantiating this class would be able to do with it, and what I need to implement. This gives me a good picture of what functions and variables I’ve defined when I come back to this code in the future. If you were in XCode looking at this class, it’d also conveniently give you a compiler warning saying that your implementation file is incomplete (Incomplete implementation of class). This is a good guideline for me to make sure I’ve implemented all the functions I intended to as I work through the implementation.

When it all comes together…

Alright, great! Let’s have some fun and finish off the implementation using the conventions I’ve defined earlier. Enjoy!

//
//  VirtualCat.m
//  Miso
//
//  Created by Joshua Wu on 8/12/11.
//  Copyright 2011 Miso. All rights reserved.
//

#import "VirtualCat.h"

@interface VirtualCat()

@property (nonatomic, retain) NSMutableArray *foodHistory;

- (void)askForFood;
- (void)sleepInBathTub;
- (void)meow;

@end

@implementation VirtualCat
@synthesize weight=_weight;
@synthesize furColor=_furColor;
@synthesize foodHistory=_foodHistory;

- (id)initWithColor:(NSString *)furColor weight:(float)weight {
    if((self = [super init])) {
        // Primitive iVars so I don't bother defining properties for them
        _weight = weight;
        _hungry = YES;
        
        // Using self. accessors to maintain memory santiy.
        // Less sane alternative would be eg. _foodHistory = [[NSMutableArray array] retain]
        self.furColor = furColor;
        self.foodHistory = [NSMutableArray array];
    }
    
    return self;
}

- (void)dealloc {
    [_foodHistory release];
    [_furColor release];
    [super dealloc];
}

#pragma mark - public methods

- (void)feed:(NSString *)food {
    if ([food isEqualToString:@"Can Food"]) {
        NSLog(@"Om nom nom nom");
    } else if ([food isEqualToString:@"Dry Food"]) {
        NSLog(@"Om nom");
    } else {
        NSLog(@"Not eating this");
    }
    
    [_foodHistory addObject:food];
    _hungry = NO;
    _weight += 1;
    
    [self sleepInBathTub];
}

#pragma mark - private methods

- (void)askForFood {
    _hungry = YES;
    [self meow];
}
          
- (void)meow {
    _weight -= 0.1;
    
    if (_hungry && _weight > 0) {
        NSLog(@"MEOW!");
        [self performSelector:@selector(meow) withObject:nil afterDelay:2];
    } else if (!_hungry && weight > 0) {
        NSLog(@"Purrr~");
    }
        NSLog(@"You allowed me to die damn it! (╯‵Д′)╯彡┻━┻");
    }
}

- (void)sleepInBathTub {
    NSLog(@"zzzzzz");
    [self performSelector:@selector(askForFood) withObject:nil afterDelay:1000];
}

@end

Pragma Marking

One more thing I’d like to suggest is use pragma marks to section off method types in your code. (eg. #pragma mark – private methods) This allows xcode to nicely section off methods in their quick access menus.

Suggestions!

By now, it should be evident how following conventions when coding can be very beneficial. This is by no means THE standard to follow, but one that I feel has helped me stay sane as I develop. If you have your own conventions that you feel would add value, I’d love to hear from you and exchange ideas on this topic.

Hybrid (Native + Web) Mobile App Development • Part 2: Maintaining EJS templates, and Bridging Interactions

Welcome to part 2 of this multi-part series of blog posts where we venture into the world of hybrid frameworks. This is where we get into the juicy stuff, if you are new to this, I suggest reading part 1 to understand the motivation behind this approach.

Big Picture Stuff

In a nutshell, what we’re trying to do here is mash a JSON response from a RESTful API call with a ejs (similar to rail’s erb) template to form the html to be rendered by a UIWebview. Simple, until you start asking questions such as how to an element to transition to a different state? How do you AJAX style interactions? How is template/asset syncing managed? These are all critical questions to ask of a hybrid framework. So before we dive into it, let’s make a short list of what a hybrid framework should be capable of before diving deeper into each feature separately.

A hybrid framework should:

* Maintain template syncing from a third party resource

* Handle bridging interactions between the web and native views

* Manage a RESTful API SDK

Maintain Template Syncing

At Miso, our mobile web templates are served off an Amazon S3 server. The basic strategy we employed is to download the web templates and cache it on disk, and when you open up the app in the future it would update it’s local templates with the latest and greatest by poking S3.

To accomplish this we used ASIHTTPRequest, a popular web request wrapper, to maintain web requests we send to the S3 server. This means asynchronous requests, cache responses, and a ASINetworkQueue that lets you handle multiple web requests.

There were a few nuggets we threw in worth mentioning here that made this strategy more efficient and scalable. We maintain a mainfest file on the server that has the list of assets the mobile device needs to download. The file would look something like this:

homepage.ejs?12398789
javascript/application.js?9437392
images/logo.png?1283740

We keep a versioning number by appending ?<some numbers> after each file. This is generated automatically every time we make updates to the web templates. Having this file allows us to scale well when we add more files, because all we have to download is the manifest file on startup.We then leverage ASIHTTPRequest’s cachedResponse flag and iterate through each file and check with s3 to ensure that this file hasn’t changed since we last fetched it.

To give a more concrete view of how exactly we maintain template syncing from a web request stand point, here’s a code snippet of an implementation of the delegate method where a ASIHTTPRequest completes showing the logic explained earlier:

- (void)requestFinished:(ASIHTTPRequest *)request {
    NSString *responseString = [[[NSString alloc] initWithData:[request responseData] encoding:NSUTF8StringEncoding] autorelease];

    // If the returned file is the manifest file, iterate through it and send web requests for each asset
    if ([[[request url] description] hasSuffix:@"manifest.mf"]) {
        // Separate assets and shove them into an array
        NSArray *assets = [responseString componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet]];

        for (NSString *asset in assets) {
            // Get rid of trailing white spaces in assets list
            if ([[asset stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]] isEqualToString:@""])
                continue;

            // Add each asset in ASINetworkQueue
            [self addUrl:asset queue:_queue];
        }
    } else {
        // If it's asset file, templates on all views need to reload unless the response is from cache
        _needsReload = _needsReload || ![request didUseCachedResponse];
    }

    NSString *file = [[request url] relativePath];
    NSString *fqFilePath = [_localBaseUrl stringByAppendingPathComponent:file];

    // If the file doesn't exist on disk, or the response is not from cache, then it's a updated file and we should save it
    if (![request didUseCachedResponse] || ![[NSFileManager defaultManager] fileExistsAtPath:fqFilePath]) {
        [self saveLayoutFile:[[request url] relativePath] data:[request responseData]];
        _needsReload = YES;
    }
}

I want to mention one last thing before I wrap up this section, and that is how we handle updating templates across different version of our app. Let’s consider the situation where you intend to release a new version of your app complete with the latest web templates. You realize that there are backwards compatibility issues of the new templates with an older version of the app. If you were to update the current web templates it’d break everyone on an older version of the app. Ooops! How we work around that is to maintain separate buckets of web templates for different versions of our app. It’s not always necessary, but something good to keep in mind.

Bridging Interactions between Web and Native views

Let’s elaborate on what this means via examples:

* User clicks on a link in a webview, and it pushes another UIViewController onto the navigation stack

* User posts a comment via a native controller, and we want that to fire off an AJAX request and render on to the web view

How Miso achieves this is by defining certain protocols to conform to when generating links within our EJS templates. That way, when a load request is captured by the UIWebView we can then route these requests to different parts of the app.

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request
 navigationType:(UIWebViewNavigationType)navigationType {
    NSString *url = [[request URL] description];

    // Check for protocol type and determine routing
    if (navigationType == UIWebViewNavigationTypeOther) {
        return YES;
    } else if ([url hasPrefix:@"miso://ajax"]) {
        [_ajaxController fireAjaxRequest:url];
        return NO;
    } else {
        // RoutesController delegates native app actions given a miso://<controller>/<action>?<params>
        [[RoutesController instance] processRoute:url viewController:_vc webview:self];
        return NO;
    }
}

The code snippet above is a stripped down version of what we use currently, but the basic concept is the same. We delegate routing by implementing the shouldStartLoadWithRequest delegate method for UIWebViews. So in the case where we capture a miso:// protocol we pass it along to other classes to process.

In the next part, we will start venturing further down the rabbit hole and look into the concepts behind RoutesController and AjaxController. Stay tuned!

Hybrid (Native + Web) Mobile App Development • Part 1: The Motivation.

In the Beginning

Miso’s most popular platform, the iPhone, was initially conceived through the use of iOS’s native framework. Aside from occasional REST API calls to the web server for data, the entire user experience was delivered through native UI elements provided to us by the iOS SDK. Everything was great! Native apps are fast, performant, and did its job. As the iPhone app gained popularity and traction with the community, the natural next move was to bring the Miso experience to other mobile platforms. Thus, the android, iPad versions of Miso were born driving even more users to our service.

And then?

While native apps certainly have their advantages, launching features across multiple platforms was terribly time consuming. Eventually, we found that unless the size of our engineering team increased significantly, the native app approach just isn’t going to scale well in the long run.

At the time of writing this article, there are 3 popular approaches to mobile app development. Native, web, and hybrid. In this article, we will briefly discuss the pros and cons of each method, and what Miso eventually chose and the motivation behind it. (We chose hybrid!)

Native

Despite the complaints over the maintenance costs and scalability issues mentioned earlier, there are definitely use cases where you should strongly consider using the native SDK. Angry Birds would not have worked if they didn’t leverage hardware accelerated graphics. So any app that needs mobile device hardware, performance centric, and a very rich UI with bouncing and flashing buttons and labels should stick with the native approach.

For Miso, those strengths weren’t high in our list of priorities. We wanted multi-platform feature releases to be iterative, fast and scalable.

Web

The web approach touts strengths that seem to be what Miso needed. No need to submit to an app store, just deploy it on the web at any time and any mobile device with a web browser would be able to get the latest and greatest! Not to mention, you get all the Javascript/CSS goodies all for free!

We liked that. It was the opposite of the native approach. We can get away from painstakingly getting our pretty designs to work across multiple platforms, and release features and bug fixes with a push of a button almost instantly.

However, with web apps that means going anywhere in the app requires firing off a HTTP request and getting a response before you can render anything. It’s slow, clunky, and simply unsuitable for the user experience we wanted to deliver. We couldn’t leverage local caching of pages or data. Zero access to the iOS framework for nifty push notifications, gestures, or even the occasional use of native UI elements.

Hybrid

Miso engineers are a greedy bunch. We wanted the best of both worlds; The fast, snappy feel of a native apps coupled with the ease of styling and quick releases of web apps. So we embarked on a long journey of slowly porting native views of Miso’s iPhone app to web views.

It took us months to build a framework we are satisfied with, and we learned a ton on the way to achieving that goal. The Miso app you see now (3.0.x) has web views supporting a majority of our layouts by combining JSON responses from REST API requests with EJS templates. In this latest release (3.0.3), we’ve also introduced the leveraging of local disk caching of javascript/css and web templates to optimize performance; and added support for AJAX requests to make web views even prettier and user friendly.

At this time, we are happy with our solution as it gives us the ability to tweak the look and feel of our app without submitting a release to the app store. It also opens up the path to eventually integrating these web views into Miso apps across other mobile platforms. Ultimately allowing us to release the latest Miso features to all of our users in a timely fashion.

Next Time

While many other articles talk about the hybrid approach, few have attempted to educate in building a solid framework to support this idea.

In the subsequent articles, I will cover the concepts and designs of our web view framework and things we’ve learned along the way that may help should you choose this hybrid approach. Feel free to leave any comments and suggestions on topics you’d like me to cover!

Part 2