5 Reasons Why Silex Is King Of All PHP Micro-Frameworks

I want to be honest with you. PHP is not my favorite scripting language. Not at all. But every here and then, a new project comes around which keeps me in front of my computer for hours, rediscovering the joy (yes, joy) of writing PHP code. And one of those projects is Silex, a PHP 5.3 micro-framework, developed by Fabien Potencier and Igor Wiedler.

With Silex, you can build (smaller) web application with real minimal effort. It’s API is inspired by Sinatra’s DSL. Let’s kick off this article with a simple example taken from the Silex website:

require_once __DIR__.'/silex.phar'; 

$app = new Silex\Application(); 

$app->get('/hello/{name}', function($name) { 
  return "Hello $name"; 
}); 

$app->run();

Yep, that’s it! No fancy stuff, just a route, a “controller” and a simple “Hello World”-like response in just 6 lines of code.

Some of you might think: “Boooring! The idea of having a Sinatra inspired micro-framework isn’t new at all. There are plenty of others around. Why should I care for this stuff?”. You’re right. Besides Silex, there are projects like Limonade or Slim which offer a similar approach, but let me tell you what makes Silex the (micro-) king of all.

1. Quality codebase

If you’re looking for a PHP micro-framework with a sleek and modern codebase, look no further! Silex offers a sophisticated class library and makes heavy use of all those cool goodies that came with the release of PHP 5.3 like namespaces or lambda functions & closures. If you haven’t yet, you really should check out it’s code.

2. It’s based on the Symfony2 components

By the time I’m writing this article, we’re only one week away from the first public beta release of the Symfony2 web application framework, the successor of the famous symfony framework. While there’s still a lot to do before the first stable release, the big picture is already clear: Symfony2 isn’t just another MVC framework. Because if it’s flexible architecture, it’s more like some kind of meta-framemwork, a framework for building frameworks.

The Symfony2 core for example is based on several independent components for managing common tasks like request/response handling, routing or caching. The best thing about those components: They’re not tied to the framework itself. So, if you don’t want to reinvent the wheel, you could, or maybe should, clone them from Github and use them in your own PHP projects.

In fact, there are already a lot of open source PHP projects out there that were build using the Symfony2 components – and Silex is one of them. It’s probably the best foundation you could wish for a framework like this.

3. It’s got the coolest, tiniest DI container on the planet

(Hint: If you’re not familiar with dependency injection (DI), please refer to this article first)

If you take a look at the source code of the other micro-frameworks I mentioned above, you might notice one big problem: The use of global objects and even global functions, like in this example for Limonade:

// Example taken from the 'Limonade' docs
// http://www.limonade-php.net/README.htm

dispatch('/hello/:name', 'hello');
  function  hello()
  {
    $name = params('name');
    return 'Hello $name';
  }

That’s not only bad style, it’s death to testability.

Luckily, Silex offers a much better solution: A dependency injection (DI) container. The Silex application class extends from Pimple, a tiny DI container developed by Fabien Potencier. With only 125 lines of code (including comments!), it might be one of the smallest DI containers of all time, but, nevertheless, it does not need to hide from the other guys.

If you add services to the container, they’ll be stored for “lazy creation”, which means that they will only be created on demand. It goes even further by providing an API for shared services that will only be created once during a request.

Take the following example:

// inside bootstrap.php ...

// Add services to the DI container
$app['my_service'] = function() {
  return new MyService();
};

$app['my_shared_service'] = $app->share(function() {
  return new MySharedService();
});


// inside app.php ...

$app->get('/foo', function() use ($app) {

  // Requesting services
  $myService = $app['my_service']

  // Shared services are only created once so it doesn't matter
  // how often you request them - there will be only one shared instance
  $mySharedService = $app['my_shared_service'];
  $mySharedService = $app['my_shared_service'];
  $mySharedService = $app['my_shared_service'];
});

First, we register our two (imaginary) services my_service and my_shared_service are registered to the DI container. The Silex application class implements the \ArrayAccess interface, so we can treat it like an ordinary PHP array. By using to anonymous functions to “wrap” our services, we make sure that both will be created lazily, i.e. when we request our services from the container. As you can see, we made my_shared_service a shared service, so it will only be created once and then cached for later use.

It could be crucial for the performance of your web application to decide whether to have shared or non-shared service. Think of a more sophisticated service that is composed of many nested classes which might consume a lot of memory, or a remote service that has to establish a network connection on it’s creation. In both cases you should think about making it a shared service.

There are even more cool things about the DI container which would exceed the scope of this posting. The curious ones of you might want to check the corresponding section of the official Silex documentation.

4. The Extension API

If you use Silex out of the box, you’ll surely notice that it’s literally pretty much “naked”. No ORM, no templating engine, no session handling or anything else you know and love from your favorite full-stack web framework. After all it’s “just” a micro-framework, but it offers an API which makes extensibility ridiculously easy.

With the extension API, you can hook up your favorite PHP library in just a couple of minutes and make it available over the DI container. Take for example the Session extension from the official Silex extension repository:

namespace Silex\Extension;

use Silex\Application;
use Silex\ExtensionInterface;

use Symfony\Component\HttpFoundation\SessionStorage\NativeSessionStorage;
use Symfony\Component\HttpFoundation\Session;
use Symfony\Component\HttpKernel\Events as HttpKernelEvents;

class SessionExtension implements ExtensionInterface
{
    private $app;

    public function register(Application $app)
    {
        $this->app = $app;

        $app['session'] = $app->share(function () use ($app) {
            return new Session($app['session.storage']);
        });

        $app['session.storage'] = $app->share(function () use ($app) {
            return new NativeSessionStorage($app['session.storage.options']);
        });

        $app['dispatcher']->addListener(HttpKernelEvents::onCoreRequest, $this, -255);

        $app['session.storage.options'] = array();
    }

    public function onCoreRequest($event)
    {
        // ...
    }
}

And we’re done! Every Silex extension class has to implement the Silex\ExtensionInterface interface and provide a method named register where all the extension-magic happens. In the example above, the register method essentially bootstraps a session service and adds it to the DI container. Using this extension in your web application is pretty straight forward:

// inside bootstrap.php ...

// Register the session extension
$app->register(new SessionExtension());


// inside app.php ...

$app->get('/account', function() use ($app) {

  $user = $app['session']->get('user');

  // ... 
});

Speaking of the official Silex extension repository: Here are the 10 official extensions which are already available, and I’m pretty sure there are still a lot more great ones to follow.

  • DoctrineExtension
  • FormExtension
  • MonologExtension
  • SessionExtension
  • SwiftmailerExtension
  • SymfonyBridgesExtension
  • TranslationExtension
  • TwigExtension
  • UrlGeneratorExtension
  • ValidationExtension

5. And boy, is it testable!

Why is testing important? It’s because modern web applications are highly dynamic. You add features, you refactor, you get rid of old stuff – you really don’t want to do all of that without testing, unless you enjoy spending your weekends on searching and fixing bugs.

Within other frameworks, testing might quickly become a real pain in the ass. And if the whole process becomes annoying for the developer, he might tend to disregard testing at all. There are some common design flaws in the PHP world that quickly can become a major problem when it comes to testing software:

  • Global objects and/or functions
  • Static methods
  • Singleton classes

Take this (simplified) example using symfony 1.x:

// ... inside userActions.class.php

public function executeRequestPassword(sfWebRequest $request) 
{
  $email = $request->getParameter('email');
  $user  = DoctrineCore::getTable('User')->findByEmail($email);

  if ($user)
  {
    $newPassword = PasswordHelper::generatePassword();

    $user->setPassword(                     
      CryptHelper::encrpytWithSha1($newPassword.$email)
    );
    $user->save();

    mail(
      $email,
      "Password reset",
      "Here's your new password: ".$newPassword
    );
  }
}

Let’s say we have an awesome web application which provides a password reset function for users who might have forgotten their password. We display a form where they can enter their email and after submitting the action above will be called. The action basically searches the user by his email, generates a new password, encrypts it, updates the user object and triggers a password reset email.

This seems to be ok at first sight but, man, this code smells really bad! Inside the action, there are three calls to static methods and last but not least, a global PHP function. Those four dependencies have been hard coded into the action, so if one of them had a bug in it, the whole action would blow. Then how do we test the action? The symfony documentation suggests writing functional tests for your actions:

$browser = new sfTestFunctional(new sfBrowser());
$browser->
  post('/requestPassword')->
  with('request')->begin()->
    isParameter('email', 'johndoe@example.org')->
  end()->
  with('response')->begin()->
    isStatusCode(200)->
    checkElement('div#sucess', 'A new password is on its way to you!')
  end()
;

The only way to test our action is though the user interface. That’s pretty suboptimal to say at least. What if the mail function would be called with wrong parameters? We’ll never know. And what if there’s a tiny little change in our success template? It might cause our test to fail, even if our actions works perfectly fine. No, that’s not what we want!

With Silex, we can eliminate (almost) every hard-coded dependency in our code thanks to the DI container:

$app->post('/request_password', function() use ($app) {

  $email = $app['request']->get('email');
  $user  = $app['db']->findByEmail($email);

  if ($user) {
    $newPassword = $app['helper.pw_gen']->generatePassword();
    $user->setPassword(
      $app['helper.crypt']->encryptWithSha1($newPassword.$email)
    );
    $user->save();

    $app['mailer']->send(
      $email,
      "Password reset",
      "Here's your new password: ".$newPassword
    );
  }

  // render template ...
});

Now we’re talking! No hard-coded dependencies. We could now easily replace services with mock objects for testing purpose (see below). Although Silex provides a dedicated class for functional / integration testing, we’re now even able to test our “controllers” with PHPUnit:

use Symfony\Component\HttpFoundation\Request;

class AppTest extends PHPUnit_Framework_TestCase
{
  public function setUp() {

    // ...
    $this->app = $app;
  }

  public function teardown() {

    // ...
    \Mockery::close();
  }

  public function testRequestPassword() {

    // Testing fixtures
    $phMock = \Mockery::mock('PasswordHelper')
      ->shouldReceive('generatePassword')
      ->withNoArgs()
      ->andReturn('abc123');

    $cryptMock = \Mockery::mock('CryptHelper')
      ->shouldReceive('encryptWithSha1')
      ->with('abc123'.$email)
      ->andReturn('fake-sha1-hash');

    $mailerMock = \Mockery::mock('AwesomeMailer')
      ->shouldReceive('send')
      ->with($email, 'Password reset', 'Here\'s your new password: abc123');

    $this->app['helper.pw_gen'] = $phMock;
    $this->app['helper.crypt']  = $cryptMock;
    $this->app['mailer']        = $mailerMock;

    $email = 'johndoe@example.org';

    $request = Request::create('/request_password');
    $request->set('email', $email);

    // Here we go!
    $response = $this->app->handle($request);

    $this->assertEquals(200, $request->getStatusCode());
  }
}

In case you’re wondering: Mockery is a sleek new PHP library for creating mock objects from existing classes. If you find the PHPUnit mocking API too clumsy and verbose, I recommend you to check out Mockery. It’s really good.

(By the way: Instead of writing functional tests, there’s now a much cooler way to test. Konstantin Kudryashov wrote an excellent BDD testing framework for PHP called Behat which was inspired by Cucumber. Together with Mink, it’s a really cool and easy way to test your web applications. And, of course, it plays nicely with Silex.)

Conclusion

I really could go on and on writing about how cool Silex is, but I don’t really want to bore you anymore for now ;) If my article finally convinced you, do yourselves a favor, hop over to the Silex website and try it out for yourselves. You will definitely not regret it. I’m planning to start a series of mini-tutorials for writing a full-blown web application with Silex in the near future. So, watch out for more very soon.

Filed under  //   frameworks   micro-framework   php   symfony   testing  

Building multiple JOIN conditions with Propel's new query API

Or: How Propel got its love back ;)

I recently updated a software project I started in autumn 2008. It was developed using symfony 1.1 with Propel 1.2 as ORM. Back then, we were stucked with PHP 5.1.6 (blame RHEL for that) and I didn’t really had the chance to update to symfony 1.2 when the development cycle for 1.1 ended in summer 2009. This year we eventually had the chance to update to PHP 5.3 which broke my project due to a conflict with mysqlnd and Creole, Propel’s former database abstraction layer. So, I had no more excuses for not updating to a more recent version of symfony.

I also thought about trashing Propel in favor of Doctrine, because Propel 1.2 was slow, buggy and the Criteria API for building database queries was a real PIA. The downside of switching was that it would have taken me weeks to replace every piece of Propel code with Doctrine, so I tried to postpone this decision as good as I could ;)

Meanwhile, François Zaninotto took the lead for the (almost dead) Propel project and brought it back to life. He recently released version 1.5, which feels like a christmas present for all developers that have to deal with Propel legacy code. It features a whole new API for building queries. It can’t be denied that this API resembles Doctrine’s DQL, but it’s really well done, elegant (maybe a bit more elegant than DQL) and blazingly fast. But the best aspect, for my part, is that version 1.5 is fully backward compatible to older versions of Propel. The new query API was build on top of the old Criteria API so it’s up to you to use the old style, the new one, or a mix of both.

After playing around for a while, I was really getting into the new query API. But there was one thing I couldn’t figure out. With Doctrine, it’s really easy to build a query with a complex join condition like this:

$q = Doctrine_Query::create()       
  ->from('Book b')       
  ->leftJoin('b.Author a WITH a.name = ?', 'Douglas Adams')       
  ->where('b.title LIKE ?', '%Hitchhiker%');            

$bookList = $q->find();

which produces the following (or a similar) raw MySQL query:

SELECT b.*     
FROM books b     
LEFT JOIN authors a ON a.id = b.author_id AND a.name = 'Douglas Adams'     
WHERE b.title LIKE '%Hitchhiker%'

How can this be archieved with Propel’s new query API?

$q = BookQuery::create()       
  ->leftJoin( /* what goes here?!? */ )       
  ->where('Book.Title LIKE ?', '%Hitchhiker%');            

$bookList = $q->find();

There’s no such thing as the WITH keyword in DQL. Since the relation itself is resolved automatically by Propel, there’s no chance to add a condition inside the leftJoin method. So, here’s what you will end up with:

$q = BookQuery::create()       
  ->leftJoin('Book.Author')       
  ->where('Book.Title LIKE ?', '%Hitchhiker%');            

$bookList = $q->find();

But that’s not what we want. After spending hours with reading through the documentation (but not finding a single clue), I gave a shout to the official Propel Google user group and kindly received a response by François himself.

Guess what: Model Query classes extend Criteria, so you can use
addMultipleJoin() on a query object exactly the same way as you do it with
Criteria. The same goes for every Criteria method.

Cheers,
François

Of course, since Propel 1.4 there was a way to add complex / multiple join conditions within a Criteria object

$c = new Criteria();      
$c->addMultipleJoin(array(          
    array(BookPeer::AUTHOR_ID, AuthorPeer::ID),          
    array(AuthorPeer::NAME, 'Douglas Adams'))        
  Criteria::LEFT_JOIN);

and since a query object is a Criteria, both “syntaxes” can be mixed. But, sadly, that’s only half the truth when it comes to more complex queries. Consider the following situation: You’re writing a bulletin board software, where you have a users table and a postings table. When a user accesses a posting, it should be marked as read, but, obviously, it should be only marked as read for the specific user and not for everyone else. So we need a third table, called read_statuses where we will store a posting id, a user id and (maybe) a timestamp everytime a user accesses a new posting. What if we now wanted to display a list of unread postings for a certain user id? Our raw SQL query could look something like this:

SELECT p.*     
FROM postings p     
LEFT JOIN read_statuses rs ON rs.posting_id = p.id AND rs.user_id = 123    
WHERE rs.posting_id IS NULL

I tried the following approach first:

$q = PostingQuery::create()       
  ->addMultipleJoin(array(            
      array(ReadStatusPeer::POSTING_ID, PostingPeer::ID),           
      array(ReadStatusPeer::USER_ID, 123))          
    Criteria::LEFT_JOIN)       
  ->where('ReadStatus.PostingId IS NULL');

Although this query looks good, it won’t work because the Query object does not know about the ReadStatus alias used in the where condition. The downside in mixing both “syntaxes” is that you might be forced to stick with the old Criteria syntax even if you want to use the new API. Here’s the fix for the approach above

$q = PostingQuery::create()       
  ->addMultipleJoin(array(            
      array(ReadStatusPeer::POSTING_ID, PostingPeer::ID),           
      array(ReadStatusPeer::USER_ID, 123))          
    Criteria::LEFT_JOIN)       
  ->add(ReadStatusPeer::POSTING_ID);

It works fine but now it’s almost entirely solved with the old, verbose and hard to read Criteria API. It might not be a big deal for relatively simply queries like the one above, but, in my project, there were rather complex ones with lots of joins and where conditions. Eventually, I ended up writing almost pure Criteria code again. Bummer! So I got back to the “blackboard” and dug back into Propel’s and my code. And suddenly I found a solution that eventually made me a happy camper again. After adding a join condition to the query object, you can retrieve a corresponding join object from the query object and extend it for additional conditions. Here’s how:

$q = PostingQuery::create()       
  ->leftJoin('Posting.ReadStatus')       
  ->where('ReadStatus.PostingId IS NULL');           

$join = $q->getJoin('Posting.ReadStatus');   
$join->addCondition(ReadStatusPeer::USER_ID, 123, Criteria::LEFT_JOIN);

I really don’t know if François wanted those method calls to be exposed to the Propel users, cause it feels a little bit hacky, but it works fine for me, tidies up my code, makes it more readable and reduces the amount of Criteria code to an absolut minimum.

I hope this will help anyone seeking for a solution to a similar problem :)

Filed under  //   development   doctrine   orm   php   propel   symfony   tutorial  

iPad Web Apps hidden at Apples website

Today’s iPhone web apps are more than just iPhone-optimized websites. They almost look and feel like native 3rd party apps: You can “install” them and they’ll appear right along your other “regular” iPhone apps. After launching, they hide the browser’s address bar and other controls. They can be even used in offline mode, thanks to HTML5’s local storage.

It seems like a perfect “illusion”. Well… it’s an almost perfect illusion. The main difference between a native iPhone app and an iPhone web app is performance. 

In december 2009, John Gruber posted an article on his Daring Fireball blog about Apple’s mysterious PastryKit Javascript Framework. It has never been officially released and you won’t find any information about it in Apple’s developer docs, but it’s already in heavy use.

Grab your iPhone and navigate to http://help.apple.com/iphone/3/mobile/ where you will find the official iPhone user manual as a web app that is build on top of PastryKit. The overall performance is impressive. On a 3GS device it’s hard to distinguish from a native iPhone app.

Here’s what Gruber wrote about it:

From WebKit’s perspective, everything in this iPhone User Guide is in a view that is exactly the size of the viewport, so there’s nothing to scroll. PastryKit handles all of what the user sees as scrollable content. This is how on the iPhone it provides for lower-friction scrolling than provided by MobileWebKit itself — PastryKit does its own scrolling math.

[…]

After installing the User Guide app to your home screen and launching it from there, there’s really very little to suggest that it isn’t a native iPhone application. No MobileSafari address bar at the top, no MobileSafari toolbar at the bottom. Scrolling is fast and has momentum. It even works perfectly offline, because the contents of the user guide are stored locally in a database using HTML5.

[…]

Here’s to hoping we haven’t heard the last of PastryKit, and that Apple continues work on making mobile WebKit an open alternative to the App Store.

You bet your ass, John.

When I played around with the iPad simulator in iPhone SDK 3.2 today, I logged into Apple’s developer portal. After trying to access the iPhone reference library docs, I was redirected to something that looks like this:

Tumblr_kzuwyczpze1qav15d
Tumblr_kzuwxurqok1qav15d

That’s right - the reference library as iPad web app.

It’s really amazing. This is as close to a native app as anything else I have seen yet, and way better than the iPhone user manual. And guess what it’s using under the hood:

Tumblr_kzuxy8edmj1qav15d

It seems like iPad.js exends PastryKit by adding iPad specific features and classes like the SplitViewController or the DocumentViewController.

The big question remains: Will Apple ever give PastryKit in the hands of iPhone and iPad web developer or will they continue to keep it as “open secret”?

Filed under  //   frameworks   html5   ipad  

iPhone App of the the moment: Here, File File!

With Here, File File! you gain remote access to one or more of your Macs even if you’re not in your local network: Just download the companion OS X App from the official website, install, and spawn a server which will talk to the iPhone App. You can bind it to your Mac’s local IP address or, even better, use it in combination with a dynamic DNS hosting service like DynDNS.com.

What really kicks ass is that you can stream music and movies from your Mac right to your iPhone without having to sync your content via iTunes. Besides, it has great support for all kind of document file types, Spotlight search, and - it’s a real beauty.

 

Pricing: $9.99 / 7.99€ - Buy at the App Store.

Filed under  //   appreview   iphone  

PHP best practices - Unit tests (pt. I)

It took me a long time to get used to unit tests in PHP. I never really liked them cause they’re time consuming and, that was my main problem, you barely find any useful real word examples in even advanced PHP books. Most of those examples are about testing custom string functions, like the ever-popular sluggify() method, or plain and simple objects. No wonder it was pretty hard for me to figure out why unit tests were so popular among the agile community.

Today, I can’t even image how I could survive without them. Not only it’s a great method for giving you confidence that your apps run stable (even while you’re sleeping), but it will also help you to produce much better code. When you write a new class or method you’ll always keep in mind to write it in a way that’ll keep it being testable. It’ll help you to avoid dependencies inside your code, or to rethink certain strategies.

Let me show you some best practices that I use when writing unit tests.

Isolate hard-coded dependecies

Consider the following situation:

class Foo
 {
   public function doAwesomeStuff()
   {
     // ...
     $bar = new Bar($someVar);
     // ...
   }
 }

 class Bar 
 {
   protected $v;

   public function __construct($v)
   {
     $this->v = $v
   }
 }

The doAwesomeStuff() method of the Foo class is nearly untestable cause it depends on another class, in this case: Bar. It might be trivial for this example, but try to think of a more complex class Bar hat might behave unpredictable for certain values of $someVar How are we able to solve this? It seems impossible.

Well, think of the following approach:

class Foo
 {
   public function doAwesomeStuff()
   {
     // ...
     $bar = $this->createBarObject($someVar);
     // ...
   }

   protected function createBarObject($someVar)
   {
     return new Bar($someVar);
   }
 }

 class Bar 
 {
   protected $v;

   public function __construct($v)
   {
     $this->v = $v
   }
 }

We have isolated the hard-coded dependency by refactoring the $bar object’s creation into its own factory method. But wait, we still have to deal with this (unpredictable) Bar class, – isn’t that whole unit testing thing about mocking and stubbing objects?

Yes it is. We will use a mock $bar object to make sure that we’ll always have the same behavior within the doAwesomeStuff() method. But how can we use the mock object for our test? After all, the $bar object is created in a protected factory method, so there’s no change of reaching it.

Time for some OOP magic (to be honest – it’s no magic, though, it’s pretty slick):

// Assuming $barMock == mocked bar object

class FooTestHelper extends Foo
{
  protected $barMockObject = null;

  public function setBarMockObject($barMock)
  {
    $this->barMockObject = $barMock;
  }

  protected function createBarObject()
  {
    return $this->barMockObject;
  }
}

The FooTestHelper class extends the Foo class and adds an instance variable to hold the mocked object and a method setMockBarObject() to actually inject the mocked object (it’s basically following the dependency injection pattern). In addition to that it overrides the createBarObject() by returning the formerly injected mocked object. Now it fits perfectly for our testing needs:

(This example shows how to use this best practice with the great Lime2 testing framework by Bernhard Schussek and Fabien Potencier)

$t = new LimeTest();

//@BeforeAll

class FooTestHelper extends Foo
{
  protected $barMockObject = null;

  public function setBarMockObject($barMock)
  {
    $this->barMockObject = $barMock;
  }

  protected function createBarObject()
  {
    return $this->barMockObject;
  }
}

//@Before

$barMock = $t->mock('Bar');
$foo = new FooTestHelper();
$foo->setMockBarObject($barMock);

//@After

unset($barMock);
unset($foo);

//@Test: ->doAwesomeStuff()

// Define expected behavior, e.g.
$barMock->any(/* ... */);
// ...
// replay it
$barMock->replay();

// Call the method
$foo->doAwesomeStuff();

// Verify the expected bahavior
$barMock->verify();

It’s pretty straight forward, so I guess that fans of the popular PHPUnit testing framework will understand it as well, even if they’re not familiar with Lime2.

(to be continued …)

Filed under  //   bestpractice   development   php   testing  

OMG, it has no multitasking!

I have one advice for all those people that are complaining about the iPad’s lack of multitasking though I can’t really tell anything precise due to the confidential status of Apples new beta release of the iPhose OS 3.2, but, if you can: take a look at the developer resources, especially the “iPad Programming Guide”, page 28.

Not only that it introduces a whole new exciting feature to the iPhone OS, but it also has the word ‘Multitasking’ written all over it.

Seriously, do you really think the iPad with it’s “blazing” new 1GHz Apple A4 chip (probably made out of Steve Jobs’ blood and the tears of 100 unicorns) wasn’t technically capable of executing two or more Apps at once? C’mon!

Multitasking isn’t just a simple feature, if you consider it to be engineered really good, both on the iPad AND the iPhone. It’s not just about throwing some task manager in, it’s about having an “intelligent” and sophisiticating multitasking architecture combined with a great user experience.
Take for example the Android plattform. They have a bunch of task-killing apps (like this one), but do you really call this a great user experience, to launch an app in order to kill some other apps? I don’t think so.

It’s like the iPhone’s “Cut, Copy & Paste” feature, which was part of the latest major update of the iPhone OS. It was not just about having some fancy UI for copying text and pictures. I think it required a lot more work “under the hood” that simply couldn’t be shipped as part of a minor 2.x update.

So, my prediction is that multitasking will be part of the next major update of the iPhone OS that will be introduced at WWDC 2010 or maybe even earlier. Try to relax in the meantime ;)

Filed under  //   ipad   iphone   stevenote  

The need of iPhone background apps.

Yesterday I tried some new apps from the iPhone jailbreak community on my iPod touch 2G (codename: sandbox). Some days ago, Leo from fscklog posted some quite interesting stuff at his blog (englisch translation). One of those apps was ProSwitcher by @rpetrich and @chpwn.

They’ve implemented a way to switch between different active apps by using the same approach of Palm’s webOS: You can flick through your running applications via activity cards. Of course, non of the apps you bought at the AppStore are able to run in background per default. That’s why ProSwitcher uses Backgrounder (another jailbreak utility) for sending apps into background mode. Even though I’m not a big fan of this whole jailbreak stuff, I must admit that ProSwitcher is very well implemented and runs smoothly on my device. It’s actually pretty fun to play with.

See the following demo on YouTube to get the idea.

One of the first apps I tried was the latest and greatest version of the Last.FM app. Now I could listen to my stations while browsing, reading etc. - awesome!

But after that I couldn’t really imagine any other apps that really need to run in background. So I gave I shout at the Twitter universe and received some feedback, even from one of ProSwitcher’s developers.

Sure it’s a nice thing to have your favorite IM app or your favorite game running in the background so it can be easily interrupted for some other action like sending an SMS, making a call, writing a note etc. but, like I said, those apps don’t need to necessarily run in background. For IM apps you got the Push Notification service that was introduced in iPhone OS 3.0. Apple may introduced it as some kind of workaround for the missing background apps but I think it actually worked out pretty well.

On the other hand you have a lot of great apps that are developed almost as if they were capable of running in the background. Tweetie2 is a good example. If you’re interrupted (e.g. by a phone call) and return back afterwards, it really feels like the app never quit. Loren Brichter really did an awesome job on that. With the iPhone 3G[S] and the new iPod touches I feels even more naturally because of the faster processors and the reduced startup time of almost every app.

But anyway, it’s a fact that iPhone apps are able to run in the background. Safari does, Mail does, the iPod app does, so why is Apple holding this feature back to its developers? My personal opinion: They just want to do it right.

It’s kinda like the introduction of the official iPhone SDK no more than one year after releasing the original iPhone. Just until today, many people think that Apple didn’t want to give away their APIs and only did so because of the pressure of the developer community. Bullshit! It was in the pipe for quite a long time but they just want to do it right before releasing it.

Background apps are coming (maybe in iPhone OS 4.0) but…

  • Will the feature be made available for really every app that will be submitted to the AppStore? And if not, who will make the distinction?
  • What about memory and battery consumption? Does it require a new / improved memory and energy management?
  • What about the design of the UI for the end-user?

I think to get a satisfying answer to all those questions Apple has to dig deep under the hood of the iPhone OS. But until then, I’ll regard ProSwitcher more like an (awesome) experiment than a real solution.

For those who are curious: You can browse ProSwitcher’s code at github.

Filed under  //   iphone   jailbreak  

Pitfalls of Objective-C, Part I - Properties

I personally think that properties in Objective-C 2.0 are some pretty nice improvement for the language. It helps you creating less code by using a more “natural” dot-syntax instead of the good ol' getter and setter methods:

Person *person = [[Person alloc] init];

// Without Objective-C 2.0 properties
[person setName:@"John Appleseed"];
NSLog(@"The person's name is: %@", [person name]);

// With Objective-C 2.0 properties
person.name = @"John Appleseed";
NSLog(@"The person's name is: %@", person.name)

To create a property, simply use the @property directive that was introduced in Objective-C 2.0 in your Person.h file.

@interface Person : NSObject {

 NSString *name;
}

@property (nonatomic, retain) NSString *name;

@end

Take a look at the retain keyword right behind the @property directive. It means that every new value that will be assigned by using properties will be retained while the old value will be released. This is very important for the iPhone’s memory managment (as you will see in a few moments). After you defined your property in your Person.h file, head over to the Person.m file and “synthesize” the actual getter and setter methods by using the @synthesize directive

@implementation Person

@synthesize name;

//...

(void) dealloc {

 [name release];
 [super dealloc]
}

@end

Now, I’m actually working on an iPhone project where I’m having a UIViewController called rootViewController that has another UIViewController, let’s call it otherViewController, as a property. otherViewController is a sublassed UIViewController that controls a simple UIView with an UIButton to trigger an arbitrary action. When rootViewController is created, I’m using the controller’s viewDidLoad: method to create and initialize otherViewController. Here’s the (wrong) code I used first:

- (void)viewDidLoad {

 [super viewDidLoad];

 OtherViewController *oc = [[OtherViewController alloc] initWithNibName:@"OtherViewController" bundle:nil];
 otherViewController = oc;
 [self.view addSubview:oc.view];
 [oc release];
}

The result was that my app kept on crashing everytime I tried to trigger the button in the UIView controlled by otherViewController. It took me about two (very frustrating) hours to figure out where I made the mistake. It turned out that it was right in viewDidLoad:. After I changed

otherViewController = oc;

into

self.otherViewController = oc;

everything went well.

Before I started developing in Objective-C, I spent some years on Java. So if you’re a Java developer you might say, “I don’t see the point. Those two statements look equal.” – Yeah, you’re right – from a Java perspective. In Java the two statments

foo = someValue;

and

this.foo = someValue;

are equal if foo is a member variable of some arbitrary class, but for Objective-C you’re screwed with that.

Take a look at the second statment: self.otherViewController indicates that you’re using Objective-C 2.0 properties. When you’re assigning oc to otherViewController, it uses the retain and release: The old value for otherViewController is released and the new value (oc) is retained. By retaining variables in Objective-C you make sure that the corresponding objects will stay in memory until you tell them to leave. Internally, all Objective-C objects use a retain count. By sending a release message to that object, you’re telling it, “Goodbye, I don’t need you anymore.” and the retain count is decreased by 1. After the retain count reaches 0, the corresponding object will be de-allocated from memory.

Now take a look at the first stament. As I said before, It pretty looks the same except for “self.” but it isn’t. This is just a simple assignment without using retain and release. If you’re not using retain, the concerning object will never know that you need it. The trouble comes right at the last line

[oc release];

oc is sent a release method and the object will eventually be de-allocated from memory. But what about otherViewController? Where is he pointing to after oc is de-allocated? – You can never tell. The app itself decides how to use those new freed blocks of memory. If you try to access those blocks (like me by triggering the button), your app will crash with some very weird error messages like

2009-07-17 15:49:35.929 SomeApp[19176:20b] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[UITextEffectsWindow triggerButton:]: unrecognized selector sent to instance 0xd1a270'

So, do yourself a favour and think about the differences of self.foo = ... and foo = ... – It might save you from some very frustrating hours ;)

Filed under  //   development   objective-c  

How to embed a navigation controller inside a tab bar controller (Part 2)

There was a tremendous feedback for my original article about embedding a navigation controller inside a tab bar controller. Thank you guys :) I really appreciate that. I’m really sorry I’m a bit late with that but I had a ton of work in the last weeks. By far the most requests were about using a table view controller instead a normal subclassed view controller. I’ll show you a little update of my code where I’ve put a table view controller in the second tab that is displaying some dummy data. Actually it’s really pretty simple.

So fire up your Xcode IDE, load in “Tabs” project and let’s get started ;)

First of all, create a subclass of UITableViewController and name it “MyTableViewController”. After that create a property for the data that will be shown inside the table view. Here I chose a simple NSArray and named it “tableData”.

#import 


@interface MyTableViewController : UITableViewController {
  NSArray *tableData;
}

@property (nonatomic, retain) NSArray *tableData;

@end

Head over to the MyTableViewController.m file and change some of the methods that were generated for us. In order to create and initialize our tableData object with some dummy data, we’ll add the following line to the viewDidLoad: method

- (void)viewDidLoad {

  [super viewDidLoad];
  tableData = [[NSArray alloc] initWithObjects:@"foo", @"bar", @"baz", nil];
}

In tableView:numberOfRowsInSection: return the actual number of elements of tableData.

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {

  return [tableData count];
}

Finally, in tableView:cellForRowAtIndexPath: configure the fetched cell by setting cell.text to the corresponding object (that happens to be a NSString) of the tableData array

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

  static NSString *CellIdentifier = @"Cell";

  UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
  if (cell == nil) {
    cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
  }

  // Set up the cell...
  cell.text = [tableData objectAtIndex:indexPath.row];

  return cell;
}

After you have accomplished that, create a new XIB file called “ThirdView.xib”, open it in Interface Builder (IB) and simply drop a UITableView onto the empty view. Set File’s Owner to MyTableViewController and also make it the table views delegate and data source by control-dragging from the table view to File’s Owners and connecting the appropriate outlets.

Screen01

After you saved your ThirdView.xib, open your MainWindow.xib in IB. In the little window titled “MainWindow.xib” expand the Tab Bar Controller entry by clicking the little triangle left to it (if you don’t see it, make sure you chose the list style display) and also expand the My Navigation Controller entry that lives inside the Tab Bar Controller entry. Here you should see three entries: Navigation Bar, Second View Controller and Tab Bar Item.

Screen02

A UINavigationController holds a reference to a view controller that he actually takes care of. In this case it’s our SecondViewController, a simple subclass of UIViewController that manages a view that is prompting the words “Can I haz navigation?” (I assume you remember that from the original article). In order to have our navigation controller take care of our freshly created MyTableViewController, we have to change the Second View Controller entry. Select it, press +4 to head over to the identity inspector where you should see the Class entry set to “SecondViewController”. Change that to “MyTableViewController”.

Screen03

In addition to that, change the NIB Name in the attributes inspector (+1) from “SecondView” to “ThirdView” (to ensure that our MyTableViewController fires up our ThirdView.xib). If everything went well, the whole MainWindow.xib setup should look like this

Screen04

Well… that’s it ;) Save all your unsaved files, return to Xcode and choose build and run:

Screen05

I hope this little update answers most of your questions. If you still have problems or questions, please drop me a line. I’ll try to answer as quickly as possible ;)

Filed under  //   development   iphone   tutorial  

Customizing table view cells for fancy user interfaces

Table views are not only about displaying arbitary data in form of a list. Today, I will show you some little tweaks to create some nice user interfaces with the help of table views and their cells. I’ll present some tactics I’ve learned from the CocoaCast podcast made by Boris Klaydman. If you don’t know it yet, I recommend you to take a look. Those guys do an amazingly good job ;)

Some theory about table views

In order to use table views in your iPhone app, you take adventage of the UITableView class in combination with a subclass of UITableViewController. The controller helps you to bring the table view to life by acting as it’s data source. The table view will ask it’s data source, “What should I display at row xyz?”, and the data source will give him the answer. A UITableView consists of cells, instances of UITableViewCell or it’s subclasses. You’ll use the subclasses if you want to present cells with custom behaviour to the user.

Okay, enough theory – let’s fire up Xcode for some table view fun ;)

Here’s a picture of the complete user interface that we are about to build:

Screen01

Pretty neat, huh?

Start a new project

In Xcode click File > New Project, choose the Navigation-based Application as template for our project and name it “TableViewFun”. This will create a working application with a table view that lives inside a navigation controller. We won’t develop it from scratch this time since we want to concentrate about the customization of our table view cells. But if this is the first time for you working with UITableView I’ll briefly scan through the code and explain what has been done for us.

The most important part is the UITableViewController subclass that is named “RootViewController” in this template. When you open RootViewController.m, you’ll see a whole bunch of code that has been generated for us. The interesting part of that is the section marked as #pragma mark Table view methods. The following four methods are the data source methods that are used to set up our table and fill it with content:

numberOfSectionsInTableView:

Here we’ll tell the table view how many sections we want to display in our table.

tableView:numberOfRowsInSection:

This one will tell the table view how many rows live in each section. This can be some static value(s) or, considering you’ll want to show the contents of an NSArray in the table view, it could be the return value of a method call, e.g. [myArray count]

tableView:cellForRowAtIndexPath:

The actual table view cell for a given index path. An NSIndexPath is a C-struct that helps you navigate through a table view by indicating where you are, e.g. section 1, row 5. Because memory is limited on a mobile device like the iPhone, we’ll try to reuse cells in this method instead of always creating new ones. We will come to that in a minute ;)

tableView:didSelectRowAtIndexPath:

This will trigger some custom action for selecting a table view row. In most cases this would be pushing a new view controller onto the navigation stack for drilling down a table view, but we will use it for some other purpose.

There are some more (optional) data source methods defined in the UITableViewDataSourceProtocol but we won’t need them at this time. Feel free to browse the Apple docs if you want to know more about the remaining methods.

Some interface work

Open RootViewController.xib for some minor changes concerning the table view. It should open a view with an embedded table view. Click the table view to select it. In the Attributes section of the Inspector (+1) choose the “Grouped” style instead of the plain one. Save and return to Xcode.

Since this is all about customized cells, we’ll have to create them too. You could do this programatically, but I’ll present the way you would do it with the help of Interface Builder (IB). Control-click the Classes folder in “Groups & Files”, choose “New File” from the context menu and select “UITableViewCell subclass” from the “Cocoa Touch Class” section. Name that class TextFieldCell (this will be the cell holding a UITextField) and create the .h and .m files.

Now we’ll have to create the correspondig NIB (XIB) file. Right-click on the “Resources” folder, choose “New File”, create an empty XIB from the “User Interfaces” section of the iPhone OS group and name it “TextFieldCell.xib”. Open the file by double-clicking which will take you back to IB. Open the Library and drag a UITableViewCell onto the little window with both the “File’s Owner” and “First Responder” in it. Double click it and up pops another window which represents the table view cell. We’ll customize it by dragging a UITextLabel and a UITextField on it. Play around with their attributes until you have something like this:

Screen02

Set File’s Owner’s class to “RootViewController” and the UITableViewCell’s to “TextFieldCell”. In the Identity section (+4) for the table view cell create an outlet named textField for the UITextField instance you dropped onto our custom cell. Connect the outlet with the actual text field and define the outlet in TextFieldCell.h (e.g. by dragging it from IB to Xcode). Create and synthesize a corresponding property as well and don’t forget to release textField in the dealloc method. After that, create an outlet for our TextFieldCell named “textFieldCell” in RootViewController, connect it, create poperties, synthesize them and edit the RootViewController’s dealloc method.

TextfieldCell.h

#import 


@interface TextFieldCell : UITableViewCell {
 IBOutlet UITextField *textField;
}

@property (nonatomic, retain) IBOutlet UITextField *textField;

@end

RootViewController.h

#import "TextFieldCell.h"
#import "SwitchCell.h"


@interface RootViewController : UITableViewController {
 IBOutlet TextFieldCell *textFieldCell;
}

@property (nonatomic, retain) TextFieldCell *textFieldCell;

@end

After that we’ll create another custom cell, the one with an UISwitch in it. It’s pretty straight forward if you completed our first custom cell. So I assume you can do it on you own ;) Please name the UITableViewCell subclass “SwitchCell” and the corresponding XIB file “SwitchCell.xib”. The result should look like this

Screen03

SwitchCell.h

#import 


@interface SwitchCell : UITableViewCell {
 IBOutlet UISwitch *turnOnSwitch;
}

@property (nonatomic, retain) IBOutlet UISwitch *turnOnSwitch;

@end

RootViewController.h

#import "TextFieldCell.h"
#import "SwitchCell.h"


@interface RootViewController : UITableViewController {
 IBOutlet TextFieldCell *textFieldCell;
 IBOutlet SwitchCell *switchCell;
}

@property (nonatomic, retain) TextFieldCell *textFieldCell;
@property (nonatomic, retain) SwitchCell *switchCell;

@end

Adding the glue

Now that we have our customized cells it’s time to glue them to our table view. But first we have to do some more basic stuff. That is, to tell our table view the number of sections and rows for each section. For this example, we’ll have three sections (0, 1, 2). The first two sections (0, 1) will have one row each and the third section (2) will have three rows. The following snippet shows you how to do it:

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {

  switch (section) {
    case 0:
      return 1;
    case 1:
      return 1;
    case 2:
      return 3;
    default:
      // We'll never reach that case, but just to 
      // make sure that something will be returned
      return 0;
  }
}

Build an run our application and see what happens:

Screen04

Hmm, just what we wanted but it looks kinda naked, doesn’t it? What about adding some headers by implementing the tableView:titleForHeaderInSection: method:

- (NSInteger)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {

  switch (section) {
    case 0:
      return @"Your name";
    case 1:
      return @"Turn me on";
    case 2:
      return @"Choose your destiny";
    default:
      // We'll never reach that case, but just to 
      // make sure that something will be returned
      return nil;
  }
}

Build and run… okay, that looks a lot better ;)

Screen05

But it’s quite obvious, that no of our custom cells were used. Instead, we’re presented the standard table view cells. In order to change that, we have to edit the tableView:cellForRowAtIndexPath: method. The default implementation is the following:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

 static NSString *CellIdentifier = @"Cell";

 UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
 if (cell == nil) {
  cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
 }

 // Configure the cell.
 return cell;
}

As I mentioned before, it’s a good practice to reuse table cells instead of always creating new ones, cause this is always very expensive and it will create no good user experience. The default implementation uses a static identifier called “Cell” (or some other arbitary string) to reuse the table view cells. If no reusable cell could be dequeued, we have to create a new one. Here, an instance of the standard UITableViewCell class is used to create a new cell.

We have to decide which kind of cell has to be created for each section. In the first section of our table view we’ll need the TextFieldCell, in the second section we’ll need the SwitchCell and in the third and last section we will use the standard cells. We will load our two custom cells from their XIB files. In order to do that, we’ll call the loadNibNamed:owner:options: method from the mainBundle object:

[[NSBundle mainBundle] loadNibNamed:@"TextFieldCell" owner:self options:nil];

When doing like this our member variables textFieldCell and switchCell of the RootViewController class should be set to the right instances.

Take the snipped below for our implementation of tableView:cellForRowAtIndexPath: That’ll do exactly what we want.

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

 UITableViewCell *cell;

 switch (indexPath.section) {
  case 0:
   cell = (TextFieldCell *)[tableView dequeueReusableCellWithIdentifier:@"TextFieldCell"];
   if (cell == nil) {
    [[NSBundle mainBundle] loadNibNamed:@"TextFieldCell" owner:self options:nil];
     cell = textFieldCell;
   }
   break;
  case 1:
   cell = (SwitchCell *)[tableView dequeueReusableCellWithIdentifier:@"SwitchCell"];
   if (cell == nil) {
    [[NSBundle mainBundle] loadNibNamed:@"SwitchCell" owner:self options:nil];
     cell = switchCell;
   }
   break;
  default:
   cell = [tableView dequeueReusableCellWithIdentifier:@"OtherCell"];
   if (cell == nil) {
    cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"OtherCell"] autorelease];
     cell.accessoryType = UITableViewCellAccessoryNone;
   }
   break;
 }

 return cell;
}

Build and run and hopefully you’ll see the following:

Screen06

If your app crashes, check if you connected all your outlets properly. In most cases it has something to do with that ;)

So far, so good. Let’s take care of the remaining section. Here we want to implement a multiple selection view, kinda like the HTML checkboxes. First of all, create some selection items in the tableView:cellForRowAtIndexPath: method:

//...

 default:
  cell = [tableView dequeueReusableCellWithIdentifier:@"OtherCell"];
  if (cell == nil) {
   cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"OtherCell"] autorelease];
    cell.accessoryType = UITableViewCellAccessoryNone;
   switch (indexPath.row) {
    case 0:
     cell.text = @"Foo";
     break;
    case 1:
     cell.text = @"Bar";
     break;
    case 2:
     cell.text = @"Baz";
     break;
    default:
     break;
   }
  }
  break;

//...

Now, when the user taps one of these three cells, we want to represent a checkmark on the selected cell. That has to be done in the tableView:didSelectRowAtIndexPath: method:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

 // Retrieve the cell ...
 UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];

 // For now we just take care of events
 // for the third section of the table view
 if (indexPath.section == 2) {
  if (cell.accessoryType == UITableViewCellAccessoryNone) {
   cell.accessoryType = UITableViewCellAccessoryCheckmark;
  }
  else {
   cell.accessoryType = UITableViewCellAccessoryNone;
  }
 }

 [tableView deselectRowAtIndexPath:indexPath animated:YES];
}

Build, run and try “tap” one or more cells in the table view’s third section. You’ll notice a checkmark appearing at the right side, followed by a nice animation that indication that your selection has been completed.

Screen07

We’re done!

Uhm… actually we’re not really done yet ;) What about our text field? We had to implement the text fields delegate methods to complete it. Otherwise we could never dismiss the keyboard that appear when we tap onto the text field. But I’ll leave that as a little practice for you ;)

I hope you enjoyed my little tutorial about table view cells. I’m not quite sure if my way is to be considered as the best possible practice, but it works fine for me ;)

Filed under  //   development   iphone   tutorial  

About

Addicted to shiny apples, beautiful pixels, awesome code and electronic music.

TwitterFacebookFlickr