Objective-C for PHP Developers, Introduction

Apr 1, 2010  

It is easiest to learn a new language by comparing it to a language you already know. When I learned Laotian, I was taught its alphabet in a similar way you are taught English: A is for Apple.  In Lao, ກ is for ໄກ່. Just by learning the alphabet, I could pair words to their English equivalent. I learned that ໄກ່ = chicken, ຂ້ອຍ = I, me, mine, my (depending on context).

The same is true with programming languages. I’ve often heard that the first language you learn is the hardest. While this may not be entirely true, I believe that learning programming paradigms such as MVC, OO, design patterns, loops, etc., require more learning and understanding while working with your first language than with subsequent ones.

This post is the first in a series that will provide some parallels that I have discovered during my short time exploring Obj-C and the Cocoa Touch framework. Going through various tutorials, I would frequently think about how I would solve a particular problem in PHP and then compare how Obj-C would solve it.

Since this is just an introduction primer, I want to state that I am going to focus specifically on the Cocoa Touch frameworks for iPhone/iPod Touch/iPad and not on functionality in Objective-C that is not available for these platforms.

iPhone applications are all built using Apple’s IDE, XCode. In general, it is a very nice application. It will build the skeleton application for you, including many of the files that you need to get started. With PHP there are many applications available to you. I use TextWrangler often when I am prototyping and NetBeans when I am integrating with SVN and the other developers at work. Neither of these applications provides you with the same level of integration like XCode does for Obj-C (I know that Zend Studio, the super-pricey Eclipse-based application, does give you similar functionality for Zend Framework).

In addition to XCode, Apple also provides the developer with Interface Builder, which is a WYSIWG editor for the view-based part of your application. You can manage and build your view from within XCode, but for the most part, it’s nicer to build various UI pieces in Interface Builder.
iPhone apps are built using MVC. In its simplest form, you have an application delegate that loads a view controller. If you want to communicate with various elements in your view, you can create IBOutlets which are basically links to items like labels and text fields, and IBActions, which are methods that you can tie events to.

Hello World Example

Let’s look at a very simple “hello world” example using a view controller. Since I want to keep this in the context of MVC, for PHP I’m going to use the Zend Framework.

IndexController.php

1 <?php
2 class IndexController extends Zend_Controller_Action {
3 	public function indexAction() {
4 		$this->view->message = ''hello world!'';
5 	}
6  }

Let’s look at the code we created here. In the Zend Framework, we have a controller and an action. In this case, we are looking at the IndexController and the IndexAction which means that we are looking at the first page of a ZF-based application.

We interact with the view by accessing a special view object called $this->view. We can assign values to view variables by just calling them. In our case we want to set the view’s message variable and we do this by calling $this->view->message.

I don’t think I need to go into much detail here, since the premise is that you already know PHP :-). So… let’s look at how we might set up a simple iPhone application that would display “hello world”.

First, we would create a new View-based application in XCode called “HelloWorld”. This would generate a bunch of new files for us. There are two that we are interested in here. They are HelloWorldViewController.h and HelloWorldViewController.m. Let’s look at each file. I have highlighted the code that we are adding to the skeleton.

HelloWorldViewController.h

1 #import <UIKit/UIKit.h>
2 @interface HelloWorldViewController : UIViewController {
3 	UILabel *message;
4 }
5 @property (nonatomic, retain) IBOutlet UILabel *message;
6 @end;

This file is essentially where we define what the .m file is going to look like. There is not an equivalent file to this in PHP-land. I tend to think of this file as something akin to a PHP interface since in both we would define what variables and methods are required, but don’t add any logic. It gets confusing when we introduce Objective-C protocols which really are more like PHP interfaces, so don’t get to hung up on how this file relates to PHP.

There are 3 key pieces here that I want to mention: * Line 2: To extend a class, you use a colon. In our file, we are extending UIViewController. * Line 3: Here we define any variables that we want to use and we set their type. In our case, we want to create a UILabel called message. * Line 5: Obj-C allows us to create getter/setter methods easily by adding a property line for each variable. On this line we give the UILabel an IBOutlet type which allows us to tie in with our Interface Builder file later on.

HelloWorldViewController.m

 1 #import "HelloWorldViewController.h"
 2 
 3 @implementation HelloWorldViewController
 4 @synthesize message;
 5 - (void)viewDidLoad {
 6 	self.message.text = @"hello world!";
 7 	[super viewDidLoad];
 8 }
 9 
10 - (void)viewDidUnload {
11 	self.message = nil;
12 }
13 
14 - (void)dealloc {
15 	[message release];
16 	[super dealloc];
17 }
18 @end

The implementation file is really where all the meat and potatoes is… Let’s go over the lines that we added: * Line 4: The @synthesize line tells the compiler to create getter and setter methods for any variables that we want to be public. In PHP, we have __get($var) and __set($var, $value) magic methods that we can set to mimic this functionality. * Line 6: viewDidLoad is the equivalent of indexAction… it is called when the view loads, so that we can do any programatic logic to the view. * Line 7: This is the equivalent to $this->view->message in our PHP. There are few items of interest that I want to mention about getter/setter in Obj-C. First, in many languages, it is common to use getVar() and setVar($value). In Obj-C the methods are generally called var and setVar. In addition, Objective-C supports two different syntaxes for accessing setters and getters. Both lines below are equivalent:

    self.message.text = @"hello world";
    [[self message] setText:@"hello world"];

As a PHP developer, the first line makes more sense, but to diehard Objective-C programmers, using the dot-syntax is too much like Java. We’ll talk about the second syntax in a later post.
  • Line 8: [super viewDidLoad] = parent::indexAction();
  • Line 11, 16: Objective-C for iPhone does not support garbage collection. PHP developers generally don’t have to worry about garbage collection, so this is an important one to remember. Any time you retain a variable, you need to remember to release it when you are done.

The only step left to get this app running is to design the view itself. You do this by opening the HelloWorldViewController.xib file in the Resources folder. This file should open up in Interface Builder. I don’t want to spend too much time on this, since there are so many wonderful tutorials out there, but you want to drag a UILabel from the Library to the View window. Then you want to right click + drag from the File’s Owner to the UILabel you just created. This should load a small window with the option to attach it to the ‘message’ outlet. Save the changes, go back to Xcode and build and run. Your HelloWorld app should load in the iPhone simulator and say “hello world!”

Conclusion

We’ve covered a lot in this post, but it was all pretty basic. We’ve learned a little about XCode and Interface Builder. We’ve learned how the view controller communicates with the view, how to create variables and access them in class methods. We’ve learned how to extend a base class. We’ve learned how to create getter and setter methods. We learned that we have to manage our resources. Future articles will delve further into variables, methods, static calls, abstract classes, interfaces, etc. Stay tuned.