cesario's blog

Software Craftman, Journey Man, Open Source Enthusiast

What Is the Best Way to Pass NSManagedObjectContext Around in iOS Applications?

| Comments

TL;DR Passing an NSManagedObjectContext in each and every NSViewController that needs CoreData can be done by different means, but some are frowned upon. In doubt, inject it.

While pair-reviewing some code with my colleague Vincent Tourraine, we realized we wrote this kind of code into each viewDidLoad: method of each NSViewController subclasses we created:

Please don’t use this snippet in your project - bad.m
1
managedObjectContext = [[[UIApplication sharedApplication] delegate] managedObjectContext];

Doing so is more or less the same as using a global variable, as calling sharedApplication on UIApplication returns the singleton application instance. I kind of felt this was a code smell so I investigated.

After a couple of minute of browsing Apple’s documentation, here’s what we can read

A view controller typically **shouldn’t retrieve** the context from a global object
such as the application delegate. This tends to make the application
architecture rigid. […]
[…]
When you create a view controller, you pass it a context. […]

If you use the good old nib|xibs (I’m acting as if I was confident with them) and instantiate your controllers programmatically, this sounds dead easy, but what if you use the brand new shiny Storyboards?

The only solution I came up with, that will comply with Apple’s recommendation, is to use prepareForSegue, like this:

If you trust me enough, use this code :) - better.m
1
2
3
4
5
6
7
8
9
10
#import "MyMainController.h"
#import "MyOtherController.h"
@implementation MyMainController
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    if([[segue identifier] isEqualToString:@"SegueToMyOtherController"]) {
        MyOtherController *controller = [segue destinationViewController];
        controller.managedObjectContext = managedObjectContext;
    }
}
@end

If your main controller doesn’t have any NSManagedObjectContext, you might want to inject it from within the method application:didFinishLaunchingWithOptions: of your AppDelegate, as you can see if you create a new CoreData project from the templates.

So next time, no more abuse of the sharedApplication !

Find Out Where a Rake Task Is Defined

| Comments

TL;DR Rake > 0.8.7 has a handy Rake::Task#locations method that makes it damn easy to know where a task is defined or enhanced.

During the last LyonRb meetup we read a quite large portion of Rake’s source code. The idea was to find an easy way to determine what file was defining/enhancing what task.

Richard and I just opened Rake 0.8.7’s source code (from our local machine’s RVM directory) and started hacking a bit to have that feature…

LyonRb Bilan De L’apéro Ruby Lyon Du 19 Février 2011

| Comments

Que de monde pour ce nouvel apéro Ruby à Lyon. L’élément encourageant étant que le groupe ne descend plus en dessous de la douzaine!

Quatre nouvelles têtes: Marion, Michel, Vincent et Richard. Bienvenue à vous!

Les discussions se sont rapidement orientées sur le StartUp Weekend Lyon, où Vincent, JM, Pierre-Alexandre et Frédéric ont eu pour mission de faire un peu se prosélytisme :)

Côté technique, nous avons eu un peu de temps pour:

  • Disséquer Rake afin de trouver un moyen simple pour retrouver où une tâche est définie
  • Discuter RESTful API et l’utilisation de l’entête Accept pour effectuer le versioning.
  • Philosopher sur les frameworks MVC comme ASP.NET MVC (beaucoup de respect pour Scott Guthrie et le travail de son équipe), Symfony.

Je n’ai pas réussi à parler de Seaside (Smalltalk)… je ne désespère pas!

Le livre “The Rails 3 Way” a été gagné par Camille par tirage au sort.