We talk about mobile, Chicago tech and our latest adventures.

Functional and Asynchronous Programming in iOS

“Functional programming is a programming paradigm that treats computation as the evaluation of mathematical functions and avoids state and mutable data.” — Wikipedia

A couple of months ago I started working on a simple project using node.js and I wanted to write a post about the similarities and differences in functional programming between JavaScript and Objective-C. However, while I was writing that post I realized I did not truly understand functional programming. I could write blocks in Objective-C and I could write functions in JavaScript but the theory behind it was lost to me. That being said, I decided to dig deeper to understand not just what the code was accomplishing but why.

Functional Programming

Considering my background as an iOS developer, I’ll start with blocks. “A block is a section of code which is grouped together” – Wikipedia. In Objective-C, blocks are used to package up code allowing it to be called in any function on any thread. This is made possible using closures, which saves the state of the variables contained within the block for proper execution elsewhere. “Blocks are particular useful as a callback because the block carries both the code to be executed on callback and the data needed during that execution” – Apple. One example of this would be the new way of animating UIView transitions:

[UIView animateWithDuration:0.5
        animations:^{
            self.view.transform =
                CGAffineTransformMakeTranslation(132.0, 0.0);
        }
        completion:^(BOOL finished) {
            self.view.backgoundColor = [UIColor blackColor];
        }];

In this method, two blocks are passed in as parameters to execute at specific times. Doing it this way is much cleaner than the previous way of animating:

- (void)performAnimations {
    [UIView beginAnimations:@"animation" context:NULL];
    [UIView setAnimationDuration:0.5];

    self.view.transform = CGAffineTransformMakeTranslation(132.0, 0.0);

    [UIView commitAnimations];

    [self performSelector:@selector(performCompletion)
        withObject:nil
        afterDelay:0.5];
}

- (void)performCompletion {
    self.view.backgoundColor = [UIColor blackColor];
}

As you can see, it is much cleaner now using blocks as opposed to needing to set two methods and a delay to accomplish the same thing. Apple made it simple to pass the animation method: a function for the animations to perform, and a function for what to change upon completion. Blocks also do quite a bit for asynchronous programming in Objective-C as well, but we’ll get into that later.

Now moving on to functional programming in JavaScript. “JavaScript is a prototype-based scripting language that is dynamic, weakly typed and has first-class functions.” – Wikipedia It is a language used primarily for web development, both server side and client side. The three key functional components that JavaScript makes use of are first-class functions, nested functions, and closures. First-class functions are treated like variables, they can be passed as arguments, altered, and executed elsewhere in the code. Nested functions are defined inside of a function and are able to retain and use variables from the parent function. Closures, much like in Objective-C, saves the data located within a function so that it can be executed elsewhere while containing the current values of the variables.

var getValue1 = function (callback) {
    var value1 = 20;
    callback(value1);
};

var getValue2 = function (callback) {
    var value2 = 30;
    callback(value2);
};

var displayTotal = function () {
    var total;
    getValue1(function(value1) {
        getValue2(function(value2) {
            function getTotal() {
                total = function() {
                    return (value1 + value2);
                };
            };

            getTotal();
            console.log(total);
        });
    });
};

In this example, the displayTotal function makes use of first-class functions and nested functions, and closures. Within that function, it calls getValue1 uses getValue2 as a callback, which in turn uses getTotal as a closure. This string of functions trickles the necessary information down to the final function that simply displays the total in the console. Nested functions play a big role when doing more complicated work where you need to make a comparison between two objects where you need to first pull down the two objects based on a unique id that is sent to the method.

While both Objective-C and JavaScript use closures and functions as callbacks, they are very different in how they do it. Thanks to first-call functions, JavaScript is able to easily pass a function around from function to function as a variable and execute it at any time. Objective-C, on the other hand, can pass a block to a selector and use that as a callback but is unable to pass a block to a block as a variable.

Asynchronous Programming

As of iOS4, blocks were released into the iPhone world opening up a much cleaner and more efficient way of asynchronously programming. Previously, you needed to use both NSThread and NSOperationQueue in order to queue up and run methods in a background thread:

- (void)callSelectorInBackgroundQueue:(SEL)selector {
    NSOperationQueue *queue = [NSOperationQueue new];
    NSInvocationOperation *operation =
        [[NSInvocationOperation alloc] initWithTarget:self
            selector:@selector(getObjects)
              object:nil];
   
    [queue addOperation:operation];
    [operation release];
    [queue release];
}

- (void)getObjects {
    [NSThread detachNewThreadSelector:@selector(launchExecution) toTarget:self withObject:nil];
}

- (void)getObjectsFromServer {
    // make a call to get objects from the server
}

So making an asynchronous call in a queue would require allocating memory to three different objects to be accomplished pre-iOS4. With the introduction of Grand Central Dispatch (GCD) alongside of blocks, Apple brought a better way to manage background threads while queueing up operations:

+ (void)makeCallInBackgroundForBlock:(void (^)(void))block {
    dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        block();
    });
}

Simply put, it is much cleaner code and requires very few explicit memory allocations. The use of blocks in Objective-C has added to the codes readability and efficiency. It is clear that blocks primarily for closures. Being an object oriented language, there are limits to what functionality Objective-C can implement from a functional language standpoint. That being said,
it takes advantage of what it can and does a good job of making it work for the developer.

Humanoid Wrap-Up

It always rewarding when you get to wrap up a project. It is even better when the project you are wrapping up is for Humanoid, and their way of saying thank you is to send over a brand new Humanoid Wakeboard!!

Even without the parting gifts, working with Humanoid was great. Thank you to everyone who put in such hard work on this project. And, if you feel like improving your wakeboarding chops download the Super Shred Bros. in the app store now!

Automated Testing in iOS

“I’ve got a fever and the only cure is more testing.”

When we send an app out into the world we want to be sure it’s bulletproof. I’m sure you write excellent code and you unit-test like a mad man, but how can you be sure? Wouldn’t it be great to plug in a device and have Instruments run an exhaustive UI test while checking for leaks and logging total memory and cpu usage? Yes it would.

For the last week iOS UI Automation has consumed my days. UI Automation uses JavaScript to navigate through your iOS app. Take a look at Apple’s documentation (scroll to the UI Automation section), if you haven’t already. Elements objects return arrays of everything on your screen. You interact with your UI by referencing an Accessibility label or array index. The best and easiest way to script interactions is to leverage Accessibility labels in your project (BONUS: this will also make your app more accessible). Be sure to use a short label, like “Favorites” or “Add”. VoiceOver will read these as “Favorites list” or “Add button”.

Here are two short simple examples:

This line will tap a cell labeled “Favorites” in the first tableview in your mainWindow:

UIATarget.localTarget().frontMostApp().mainWindow().tableview[0].cells["Favorites"].tap();

The following will randomly tap 1000 times all over your app. Think of it like buckshot testing.

var target = UIATarget.localTarget();
//random between x320 and y460
for (i=0;i<=1000;i++) {
    xPoint = Math.floor(Math.random()*319+1)
    yPoint = Math.floor(Math.random()*479+1)
    target.tap( { x:xPoint, y:yPoint } );
}

Alex Vollmer has a great introduction to UI Automation on his site. He explains how to set Accessibility labels in Xcode and he covers all the basics of scripting UI Automation. He also created some excellent JavaScript to make scripting much easier. Kind users on StackOverflow collected more introductory resources here: Best Resources for UI Automation Testing for iOS Applications.

This is very exciting, but it gets even better: iOS 5 added the ability to record interaction straight to JavaScript. Armed with the record button you can write more accurate scripts faster. You’ll have a flexible script ready in no time. The screenshot below shows the output. Every element is returned with every possible way to reference it. A forward-thinking scripter could use predicates to ensure the script works even as your interface is reorganized in the future.

UIAutomation MAGIC

Record lacks just two important features: delay timing and text entry. Since scripts often run faster than the iPhone Simulator’s UI you’ll need to set a long timeout or insert a few target.delay() to ensure your UI can catch up. In practice your test writing workflow will probably go like:

    1. Plan the UI flow for the test
    2. Record the activity
    3. Add timing/delays, text entry, and assertions
    4. Run the test
    5. Repeat

The future of UI Automation testing is bright. My next step will be integrating UI testing in to our build server’s existing tests so every new build will be automatically tested for functionality, memory leaks, and crashes.

In parting, I’ll leave you with a short example using tuneup.js

#import "/path/to/tuneup/tuneup.js"
test("Log In", function(target, app) {
    app.mainWindow().activityIndicators()["In progress"].waitForInvalid();
    target.delay(1);
    app.navigationBar().elements()["Settings"].tapAndWaitForInvalid();   
    app.navigationBar().elements()["Login"].tapAndWaitForInvalid();
    // expect failure - User Does Not Enter Username or Password     
    app.mainWindow().scrollViews()[0].secureTextFields()["Password"].setValue("notcorrect");
    target.delay(1);
    app.keyboard().buttons()["Done"].tap();
    target.delay(1);
    UIATarget.onAlert = function onAlert(alert) {
        UIALogger.logMessage("expect alert occured");
        alert.buttons()["OK"].tap();
        return true;
    }
}

Memory Optimizations in iOS

In a recent client iPad app we learned ways to significantly reduce memory usage and improve speed by converting views to images and reusing frequently used view controllers.

The app required a scrollable grid composed of rectangles of various sizes containing text and images taken from articles from a number of RSS feeds. The grid can be refreshed with new content and redrawn in any orientation.

In the original implementation each grid item was set up using its own instance of the same view controller class with one of twelve different NIBs depending on the size of the grid item. After populating the UILabels and UIImageViews the view controller’s main view was added to a UIScrollView as a subview. Loading the grid, scrolling, and orientation changes were quite slow with this implementation. I ran the app through the Activity Monitor tool in Instruments and found that memory usage was very large:

Memory usage after one grid load:

Memory usage after one grid load

The grid configuration and drawing process is repeated on an orientation change and the previous subviews are persisted so that future orientation changes with the same set of articles can occur faster.

Memory usage after first orientation change:

Memory usage after first orientation change

Changing sets of articles a few times increased memory usage dramatically. After about 5 category changes the memory usually plateaued and the OS often killed the app due to this extremely high memory usage:

Memory usage after 5 category changes:

Memory usage after 5 category changes

To cut down on memory usage I decided to

    1. Reuse the grid item view controllers and views instead of allocating view controllers for each grid item
    2. Convert the views to images before drawing them onto the scroll view.

In order to reuse the grid items, a single view controller for each grid item type is allocated:

articleLandscapeSquareNoImage =
    [[ArticleViewController alloc] initWithNibName:@"Article1x1TextLandscape" bundle:nil];
articleLandscapeVerticalNoImage =
    [[ArticleViewController alloc] initWithNibName:@"Article1x2TextLandscape" bundle:nil];
articleLandscapeHorizontalImage =
    [[ArticleViewController alloc] initWithNibName:@"Article2x1ImageLandscape" bundle:nil];
articleLandscapeTwoByOneNoImage =
    [[ArticleViewController alloc] initWithNibName:@"Article2x1TextLandscape" bundle:nil];
articleLandscapeSquareImage =
    [[ArticleViewController alloc] ...

After a grid item view controller is configured with new article data, the main view is converted to an image using the QuartzCore framework:

UIGraphicsBeginImageContext(viewController.view.bounds.size);
[viewController.view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

The resulting image is then set as the background of the grid item (a UIButton). After configuring it and adding its image representation to a button on the UIScrollView, the same view controller can be reused and reconfigured for the next article of its NIB style.

This approach reduces memory usage and improves speed significantly as only twelve view controllers need to be allocated (as opposed to 50+ in the initial implementation) and the resulting grid items are drawn to the UIScrollView as individual images and not multiple views (UIViews, UIImageViews, UILabels, etc.). Below are memory usage statistics from the same scenarios as the statistics that were gathered from the original implementation:

Memory usage after one grid load:

Memory usage after one grid load

Memory usage after one orientation change:

Memory usage after one orientation change

Memory usage after five category changes:

Memory usage after five category changes

It became clear while working on this app that commonly used view objects should be reconfigured and reused whenever possible to reduce memory usage and improve stability and performance. Furthermore, if the views’ subviews are not altered often or involve much user interaction, converting them to images will also reduce memory usage and increase drawing speed. I expect us to frequently use these techniques in future apps that rely heavily on custom views.

Mobile Moment: How to Approach Testing Mobile Software

For this weeks Mobile Moment, we are joined by Nick Ross, Vokal’s Project Manager and mobile testing Guru. Nick gives a high level overview of how testing should be approached when it comes to mobile development. Mobile software development comes with it’s own interesting hurdles—you don’t typically have to worry about losing your network connection when you are visiting a website on your PC, however this is the expectation on a mobile device. We pride ourselves on our testing strategies and extreme diligence for creating high quality mobile software.

Also, enjoy the awesome iPhone 4S video quality (we were previously using a Flip)!

Have any other questions? Follow up with us on Twitter at @VOKALMobile or on our Facebook page.

Enjoy!

Brandon, @brandonpassley