codenugget.org http://codenugget.org b00gizm's digital overdose posterous.com Sat, 11 Feb 2012 09:19:07 -0800 KnpUniversity - The PeepCode for the rest of us! http://codenugget.org/knpuniversity-the-peepcode-for-the-rest-of-us http://codenugget.org/knpuniversity-the-peepcode-for-the-rest-of-us

I’ve always been a fan of development screencasts. Not that I’m too lazy to read books or articles about development and related topics, but I enjoy watching people code and see how they would get things done. Sometimes you get introduced to new techniques and workflows you haven’t even thought of and which might become an essential part of your daily life as a programmer.

As a web developer, I’ve been a fan of the Peepcode Screencasts by Goeffrey Grosenbach of TopFunky Corp. For $12 each, you’ll get a high quality and professional made one hour screencast about all kinds of topics related to web development. The problem – at least for someone who earns most of his living with PHP development – is, though, most of them are Ruby/Rails-centric. You can still go for the excellent screencasts about frontend development with several Javascript libraries and frameworks like jQuery, Raphael.js, Backbone.js and so on, but if you perform a PeepCode search for PHP related screencasts, there are exactly 0 screencasts to be found.

This sucks, right..?

Introducing KnpUniversity

Some weeks ago, the awesome girls and boys of KnpLabs launched a new project called KnpUniversity which at least I personally see as PeepCode for the “rest” of us. Let me explain why:

First, there’s KnpLabs, a company which features some of the greatest and bravest talents in today’s PHP/Symfony community. Founded in 2009 by Matthieu Bontemps and Laetitia Wagner in the lovely city of Nantes (France), KnpLabs today has over 20 developers and staff members in France, Tokyo and the USA. Two of them, leading the KnpLabs US branch in Nashville, TN, are Ryan Weaver and Leanna Pelham.

If you’re a PHP developer working with Symfony and ever got stuck with some serious problem that could be solved after reading the great docs at the Symfony website, I’m almost 100% sure, you owe Ryan at least 1 or 2 beers for that. Recently voted to “Best Contributor” of the year 2011 by the Symfony community, Ryan is mostly responsible for writing and maintaining the Symfony documentation. He really understands how to explain some of Symfony’s most complex parts even to beginners.

Ryan is also head of KnpUniversity which has a goal of featuring some of the best professional grade PHP tutorial screencasts of the world wide web. I recently watched KnpUniversity’s first “feature length” screencast called “Starting in Symfony2” for folks who wants to get serious about Symfony2 development. Here are my thoughts on this:

The Review

The first thing to notice is the contents of the download package. Besides the actual screencast, you’ll find a zipped folder with all the source code and the screencast’s script as PDF file.

Download package

The screencast itself has a resolution of 1024x600 pixels which is enough to easily read all the text produced on the screen. Although it’s a H.264 video with an AAC audio codec, I had to convert it in order to watch it on my AppleTV, but I think that’s not a big issue for most interested developers ;)

The voiceover is, by the way, done by Leanna rather than Ryan itself. Isn’t it awesome to hear an actual gal talking about all the nerdy parts..? Do yo know any other screencast to have that? Thumbs up for that! :)

The screencast’s project is basically just your standard CRUD example (but with some pretty entertaining Star Wars references). Nothing too fancy, but it fits well as foundation for an introduction to a new framework like Symfony.

Screencast screenshot

A lot of topics are covered in just 60 minutes. It goes from the basic setup to configuration, routing, controllers, templating with Twig, the Doctrine ORM, the dependency injection container (DIC), bundle management and other essential parts for getting started with Symfony2.

IMHO the balance between going over the easier parts and explaining some of the more advanced sections wasn’t that perfect yet. I’m more like a visual kind of person, so my advice is: Use some basic illustrations, diagrams or animations for more advanced concepts and components like Symfony’s DIC. Viewers will remember those little mnemonics later more easily when it comes to real development challenges.

Although the screencast is more targeted towards Symfony beginners, there are also some nice little tricks to discover for more advanced developers. One example is where Ryan shows how easy it is to call your Symfony application from the CLI with just one or two little tweaks in the front controller. Pretty neat!

Screencast screenshot

Conclusion

So, would I recommend the “Starting in Symfony2” screencast by KnpUniversity to beginners? Yes. Definitely!

For just $12, you’ll get a great and entertaining dive head-first into Symfony development, taught by one of its core members and main contributors. If you’re looking for a way to start, do it here!

For future productions, as an experienced and more advanced Symfony developer, I’d wish for screencasts which focus on just one topic, component and/or bundle. Provide tips, tricks and best practices to solve real-world problems the Symfony way and KnpUniversity is going to be a really big deal for all PHP/Symfony developers out there.

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/574342/photo-4685.jpg http://posterous.com/users/5AGhiDWOzAcx Pascal Cremer b00gizm Pascal Cremer
Fri, 22 Apr 2011 07:13:00 -0700 5 Reasons Why Silex Is King Of All PHP Micro-Frameworks http://codenugget.org/5-reasons-why-silex-is-king-of-all-php-micro http://codenugget.org/5-reasons-why-silex-is-king-of-all-php-micro

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.

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/574342/photo-4685.jpg http://posterous.com/users/5AGhiDWOzAcx Pascal Cremer b00gizm Pascal Cremer
Sat, 17 Jul 2010 03:28:00 -0700 Building multiple JOIN conditions with Propel's new query API http://codenugget.org/building-multiple-join-conditions-with-propel http://codenugget.org/building-multiple-join-conditions-with-propel

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 :)

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/574342/photo-4685.jpg http://posterous.com/users/5AGhiDWOzAcx Pascal Cremer b00gizm Pascal Cremer
Thu, 25 Mar 2010 23:11:00 -0700 iPad Web Apps hidden at Apples website http://codenugget.org/ipad-web-apps-hidden-at-apples-website http://codenugget.org/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”?

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/574342/photo-4685.jpg http://posterous.com/users/5AGhiDWOzAcx Pascal Cremer b00gizm Pascal Cremer
Thu, 25 Mar 2010 00:04:00 -0700 iPhone App of the the moment: Here, File File! http://codenugget.org/iphone-app-of-the-week-here-file-file http://codenugget.org/iphone-app-of-the-week-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.

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/574342/photo-4685.jpg http://posterous.com/users/5AGhiDWOzAcx Pascal Cremer b00gizm Pascal Cremer
Wed, 24 Feb 2010 00:24:00 -0800 PHP best practices - Unit tests (pt. I) http://codenugget.org/php-best-practices-unit-tests-pt-i http://codenugget.org/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 …)

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/574342/photo-4685.jpg http://posterous.com/users/5AGhiDWOzAcx Pascal Cremer b00gizm Pascal Cremer
Thu, 28 Jan 2010 14:18:00 -0800 OMG, it has no multitasking! http://codenugget.org/omg-it-has-no-multitasking http://codenugget.org/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 ;)

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/574342/photo-4685.jpg http://posterous.com/users/5AGhiDWOzAcx Pascal Cremer b00gizm Pascal Cremer
Sun, 27 Dec 2009 13:28:00 -0800 The need of iPhone background apps. http://codenugget.org/the-need-of-iphone-background-apps http://codenugget.org/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.

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/574342/photo-4685.jpg http://posterous.com/users/5AGhiDWOzAcx Pascal Cremer b00gizm Pascal Cremer
Fri, 17 Jul 2009 12:43:00 -0700 Pitfalls of Objective-C, Part I - Properties http://codenugget.org/pitfalls-of-objective-c-part-i-properties http://codenugget.org/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 ;)

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/574342/photo-4685.jpg http://posterous.com/users/5AGhiDWOzAcx Pascal Cremer b00gizm Pascal Cremer
Sat, 16 May 2009 09:14:00 -0700 How to embed a navigation controller inside a tab bar controller (Part 2) http://codenugget.org/how-to-embed-a-navigation-controller-inside-a-0 http://codenugget.org/how-to-embed-a-navigation-controller-inside-a-0

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 ;)

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/574342/photo-4685.jpg http://posterous.com/users/5AGhiDWOzAcx Pascal Cremer b00gizm Pascal Cremer
Sun, 19 Apr 2009 13:52:00 -0700 Customizing table view cells for fancy user interfaces http://codenugget.org/customizing-table-view-cells-for-fancy-user-i http://codenugget.org/customizing-table-view-cells-for-fancy-user-i

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 ;)

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/574342/photo-4685.jpg http://posterous.com/users/5AGhiDWOzAcx Pascal Cremer b00gizm Pascal Cremer
Wed, 25 Mar 2009 21:22:00 -0700 How to embed a navigation controller inside a tab bar controller http://codenugget.org/how-to-embed-a-navigation-controller-inside-a http://codenugget.org/how-to-embed-a-navigation-controller-inside-a

It’s a commonly used design pattern in the iPhone world to combine tab bar and navigation controllers. In the official Apple developer docs you can find some clues how to solve this in a programmatically way, but you can only rarely find a good tutorial for doing this in Interface Builder (IB). So I’ll try to walk you trough all the steps for building a good application framework with one tab bar and one navigation controller.

If you like this tutorial, show some love and flattr it :)

Okay, let’s do this

First of all, launch your Xcode IDE, start a new iPhone window based project (we could use the tab bar based template but we want to create it from scratch) and call it “Tabs”. In “Groups & Files” expand the Resources folder and double-click MainWindow.xib to launch IB. Open the Library and drag a “Tab Bar Controller” onto the little Window named MainWindow.xib. The controller will appear on the workspace and a window with a tab bar layout will pop up.

Screen01

By the way: You can close the blank window layout, we won’t need it here ;) So far so good. We will now fill the two tabs that were created for us. But before that we need to create an outlet for the controller in the Tabs App Delegate object (that orange cube in the left window). We will name this outlet rootController and set the type to UITabBarController. Control-drag from the Tabs App Delegate to our Tab Bar Controller to connect the outlet.

Screen02

After that we return to Xcode in order to create this outlet in the TabsAppDelegate.h. Create a corresponding property as well (I assume you already know about Objective-C 2.0 Properties).

#import UIKit/UIKit.h

@interface TabsAppDelegate : NSObject 
{ 
  IBOutlet UITabBarController *rootController; 
  UIWindow *window; 
} 

@property (nonatomic, retain) IBOutlet UIWindow *window; 
@property (nonatomic, retain) IBOutlet UITabBarController *rootController; 

@end

Now, we will set and create two different controllers for the tabs: First, a subclass of UIViewController and secondly our long-awaited navigation controller ;) Head back to Xcode, control-click the Tabs project (the very first icon at the “Groups & Files” view) and choose Add > New File … Select an UIViewController subclass from the “Cocoa Touch Classes” section and name it FirstViewController (do not forget to create the .h file too). In addition to that create a FirstView.xib file in the Resources folder, open it in interface builder and build a simple view like the one below.

Screen03

In the Identity Inspector (+4) set the class of “File’s Owner” to FirstViewController and control-drag from “File’s Owner” to “View” to connect the view outlet. Save your work an switch back to MainWindow.xib. Now we have to tell the first tab that it has to care about our FirstViewController. In order to do so, select the first tab, open the Identity Inspector (+4) and set the tab’s class to FirstViewController. But what about it’s content? Switch to Attributes Inspector (+1) and choose FirstView from the NIB Name’s drop-drop down box. – What have we done here? We told the first tab to present the contents of our FirstView.xib. Finally, change the tab bar item’s title to “Simple View Controller”. If everything went well, the layout should look like this

Screen04

Time for our first launch, isn’t it? Almost. But first, we have to make some changes in our TabsAppDelegate.m

#import "TabsAppDelegate.h" 

@implementation TabsAppDelegate 

@synthesize window; 
@synthesize rootController; 

- (void)applicationDidFinishLaunching:(UIApplication *)application 
{ 
  // Override point for customization after application launch 
  [window addSubview:rootController.view]; 
  [window makeKeyAndVisible]; 
} 

- (void)dealloc 
{ 
  [window release]; 
  [rootController release]; 
  [super dealloc]; 
} 

@end

In [window addSubview:rootController.view] we add the view property of our root controller as subview to the window. Without that, our tab bar would never be seen on our device respectively our simulator. Save, build and run.

…drumroll…

Screen05

Woohoo! Everything went perfectly fine :) (If it did not for you, check your code and all outlets' connections). But now for the part you all waited for. Generally it’s almost the same steps but we have to watch out for some details. Create a new UIViewController subclass and name it “MyNavigationController” (don’t forget the .h file). Since we need an UINavigationController instead of an UIViewController, open MyNavigationController.h and change UIViewController to UINavigationController in the @interface directive.

#import UIKit/UIKit.h

@interface MyNavigationController : UINavigationController 
{ 

} 

@end

Since we will have to deal with the navigation controller programmatically to push and pop views, it’s a good idea to create an instance variable for it in our Tabs App Delegate class.

#import UIKit/UIKit.h
#import "MyNavigationController.h" 

@interface TabsAppDelegate : NSObject 
{ 
  IBOutlet UITabBarController *rootController; 
  MyNavigationController *navigationController; 
  UIWindow *window; 
} 

@property (nonatomic, retain) IBOutlet UIWindow *window; 
@property (nonatomic, retain) IBOutlet UITabBarController *rootController; 
@property (nonatomic, retain) MyNavigationController *navigationController; 

@end

Our navigation controller needs at least one view controller to display its contents. So go ahead, create another UIViewController named “SecondViewController” and also create a “SecondView.xib” with a layout similar to the first one.

Screen06

Save it and switch back to MainWindow.xib. Here comes the tricky part: Similar to the FirstViewController, select the second tab and set its class to MyNavigationController. After that, select the Tab Bar Controller and open the Attributes Inspector (+1). In the “View Controllers” section, change the term “Item 2” to “Navigation View Controller” (this will be displayed as the second tab’s title) and switch the class to NavigationController.

Screen07

Now we set the navigation controller’s root view controller: In the little MainWindow.xib Window expand the Tab Bar Controller. You should now see a Tab Bar icon and two sub controllers. Select the second one and expand it, too… Aaaaah, there it is! The navigation controller’s root view controller. Select it, set its class (+4) to SecondViewController and choose (+1) SecondView as NIB Name for the content. If everything went well, your layout should look like this:

Screen08

That’s it! Build, run and enjoy your creation

Screen09

As you can see, we built a sophisticated fully-fledged layout with less than 10 lines of self-written code. Feel free to play around with it or try to add some some more view controllers to the tab bar layout (it’s as simple as drag and drop).

Update

Due to huge demand I’ve added a second part of this tutorial that’ll walk you through the steps of having a table view controller instead of a normal view controller as second tab. Jump right into part 2

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/574342/photo-4685.jpg http://posterous.com/users/5AGhiDWOzAcx Pascal Cremer b00gizm Pascal Cremer
Thu, 19 Mar 2009 09:34:00 -0700 NSXML and the iPhone http://codenugget.org/nsxml-and-the-iphone http://codenugget.org/nsxml-and-the-iphone Today I tried to deploy the recent version of Twillo to my iPhone for debugging for the very first time (I received my activation key for the official iPhone Developer Program this morning ;)). Stupidly I didn't had in mind that almost all Cocoa classes for XML handling (especially NSXMLDocument, NSXMLElement and NSXMLNode) are not available on the iPhone plattform. Accordingly to Erica Sadun it seems that Apple has moved them into some private Framework that should not be accessed by "mortal" iPhone developers (maybe for some performance reason or something)

The NSXMLParser is still available though, but it seems for me that Apples way of "Event Driven XML Programming" is more a pain in the ass than a real alternative to NSXMLDocument and XPath. Luckily there's some promising project called TouchXML that delivers an Objective-C wrapper around libxml and uses almost the same syntax as the original Apple classes.

In the following days I'll try to integrate the TouchXML framework into Twillo and I'll keep you updated with the progress ;)

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/574342/photo-4685.jpg http://posterous.com/users/5AGhiDWOzAcx Pascal Cremer b00gizm Pascal Cremer