Thursday, June 6, 2013

Hackergarten on Mars

Yesterday Marseille JUG hosted a hackengarten. Broad variety of topics:

It was actually the first hackengarten I was attending. I've done workshop before, where you prepared a demo with steps. Hackengarten are cool stuff. They required less preparation work, it's more on the fly event. It's also a good opportunity to meet and talk to open source developers. Small group, pair programming and interacting is for sure fun.

For AeroGear, we prepared some markdown doc where you put together quick start instructions.  we had two proposals: work on scaffolding geolocation or do some cool Spock test.

Two brave hackers: Victor and Axel volunteer to do Spock testing on the new AeroGear feature Unified Push.


We endup doing our first PR on AeroGear integration test branch!

Another PR was pushed to CRaSH git repo. The lucky contributors went back home with AngularJS t-shirt - ask Julien why Angular :)

Keep up the nice work, more contrib welcome ;-)
See you on next JUG guys!

Monday, June 3, 2013

Blocks vs Delegate

How can you simplify your code using blocks. 

All iOS developers are familiar with the Delegate pattern. It is an object oriented pattern widely used in Cocoa Touch frameworks. Most of time  the delegate pattern is used to express callback code. Code that will be handled once a button is clicked or once datasource is initialized.

Since iOS4 and with the introduction of Blocks, it opens a new style of callback programming. If you're coming from functional language like Lisp, Clojure or like me, from Groovy, you know what a closure is. Simply put, Blocks (iOS term for Closures) encapsulate a piece of code, enclosing with it, variable that are in scope at the time the block is declared. Blocks can greatly simplify code. They can help you reduce code and more importantly they allow you to declare what going to happen at the same time than defining your code. Let's take a common use case and compare with Delegate approach versus with Block approach. For the Block code sample our example is base on ARGenericTableViewController reusable component.
Our use case is taken from AeroGear TODO app for server side and for the client, let's look at iOS client source code. I extracted from this sample app, the display of two tables: I'd like to focus on the implementation of two kinds of list: one is a dynamic list with standard cell, the next one is detailled view with section and custom cell.


TODO task list + task detail screens 
Using our cloud hosted backend for TODO, you can add tasks with the web interface. Let's write an iOS client app to visualize the tasks list. Source code could be find on github.

Delegate version

When implementing a UITableViewController, you need to define datasource delegate function tableView:cellForRowAtIndexPath: This method is called for each row. It's the developer duty to customize the cell depending for each section depending on the row index.

In the case of a list of tasks (using one type of cell -besides standard one), our method tableView:cellForRowAtIndexPath: is not doing much. But when defining detailed task table which has sections and inside section different types of cell, we end up with:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSUInteger section = [indexPath section];
    NSUInteger row = [indexPath row];
    
    UITableViewCell *cell;
    
    switch (section) {
        case AGTableSectionTitle: {
            EditCell *titleCell = [EditCell cellForTableView:tableView withClassName:@"EditCell"];
            titleCell.txtField.text = [self.task objectForKey:@"title"];
            cell = titleCell;
            break;
        }
        default:
        {
           ...
        }
        case AGTableSectionDescr:
        {
            ...
            break;
        }
        case AGTableSectionDueProjTag:
        {
            switch (row) {
                case AGTableSecDueProjTagRowDue:
                {    
                    ...
                    break;
                }
                case AGTableSecDueProjTagRowProj:
                {
                    ...
                    break;
                }
                case AGTableSecDueProjTagRowTag:
                {
                    ...
                    break;
                }

            }
            
            break;
        }
        
    }
    
    return cell;
}
With the usage of switch your McCabe cyclomatic complexity increases :(
You will see how ARGenericTableView helps the cause.

Notice that for accessing property we chosen to subclass UITableViewCell (EditCell), at least we can keep the initialization of the cell shorter. Always in a worry to keep it short, we define a method cellForTableView:withClassName: for each custom cell. The method is using dequeueReusableCellWithIdentifier: internally allowing reuse of cell.

Blocks version

Let's revisit our TODO app using UITableViewController to use Blocks.

1. Add pod dependency

2. Inherit from ARGenericTableViewController instead of UITableViewController

@interface AGTaskViewController : ARGenericTableViewController
@property (strong, nonatomic) id task;
@end

3. Initialise your callback blocks:
- (void)viewDidLoad
{
    [super viewDidLoad];
    ARTableViewData *tableViewData = [[ARTableViewData alloc] init];

    [tableViewData addSectionData:[self sectionTitle]];
    [tableViewData addSectionData:[self sectionDescription]];
    [tableViewData addSectionData:[self sectionDueDateProjectTag]];
    
    self.tableViewData = tableViewData;  
}

- (ARSectionData *)sectionTitle {
    NSString *name = NSStringFromClass([EditCell class]);
    ARSectionData *sectionData = [[ARSectionData alloc] init];
    [self.tableView registerClass:[EditCell class] forCellReuseIdentifier:name];
    
    ARCellData *cellData = [[ARCellData alloc] initWithIdentifier:name];
    [cellData setCellConfigurationBlock:^(EditCell *cell) {
        cell.txtField.text = self.task[@"title"];
    }];                
    [sectionData addCellData:cellData];    
    return sectionData;
}

All you code definition goes in the init method (viewDidLoad). You don't have to implement the delegate method tableView:cellForRowAtIndexPath:, ARGenericTableViewController is doing it for you behind the scene.

ARGenericTable is a acting like a map of blocks that you register at init time. ARGenericTableViewController implements tableView:cellForRowAtIndexPath:. For each cell, we retrieve cell configuration and call its associated block.

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    ARCellData *cellData = [self.tableViewData cellDataAtIndexPath:indexPath];
    
    NSString *CellIdentifier = cellData.identifier;
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (!cell) {
        Class TableViewClass = self.tableViewCellClassDict[CellIdentifier];
        cell = [[TableViewClass alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
    }

    // Configure the cell...
    if (cellData.cellConfigurationBlock) {
        cellData.cellConfigurationBlock(cell);
    }
    
    return cell;
}

As you can see with the block approach, we have achieved much leaner code: no imbricated switch statement anymore. Notice the usage of registerClass:forCellReuseIdentifier: which works with dequeueReusableCellWithIdentifier: (iOS6 new pattern). Slight note on feature improvement for ARGenericTableViewController in order to be more flexible: everything is fine as long as your working with custom cell or standard cell using default style. However if you want to init with style of UITableViewCellStyleValue1, with the current implementation you can't.