Showing posts with label Phone Coding. Show all posts
Showing posts with label Phone Coding. Show all posts

Sunday, February 13, 2011

iPhone FBConnect: Facebook Connect Tutorial

Now a days social networking websites like facebook are becoming very popular, so integrating facebook with app has become a necessity to make you application popular. We are going to do the same through this tutorial. The Facebook Connect SDK provides code which third-party developers can embed into their applications to connect to their Facebook accounts and exchange information with iPhone apps. It’s a way of embedding “social context” to an iPhone app, according to Facebook.
Create a Viewbased Application with name ‘FacebookAPI’.
1.Download Facebook Connect for iPhone SDK (
Just go through the project. In particular, the “Connect” sample project. Sample Project gives demo of some of the functionality.
1.1.Open src/FBConnect.xcodeproj from SDK that you downloaded, and your own project as well.
1.2.Drag n drop FBConnect group. Make sure “Copy items into destination group folder” is NOT checked. It should look as shown below

1.3.Go to Project Menu ->Edit project settings and scroll down to “User Header Search Path” add entry which will point to “src folder”
1.4.To test import all .m n .h files in case any miss. And compile.
2.Login to Facebook. After that go to Developers Page ( as shown below.
3.Register your application with Facebook
3.1.Click on Set up New Application Button in the upper right hand corner.
3.2.Give Application name and click on create application button. Then you will see new application screen with detail including “API key”and “API Secret Key”
Note : This application will not work until you provide your Facebook application’s API keys.
Now to get started with actual coding:
Append Following code in


02#import "FBConnect/FBConnect.h"
03#import "FBConnect/FBSession.h"
05@class FacebookAPIViewController;
07@interface FacebookAPIAppDelegate : NSObject  {
08          UIWindow *window;
09          FacebookAPIViewController *viewController;
10          FBSession *_session;
13@property (nonatomic, retain) IBOutlet UIWindow *window;
14@property (nonatomic, retain) IBOutlet
15                           FacebookAPIViewController *viewController;
16@property (nonatomic,retain) FBSession *_session;
Append Following code in FacebookAPIAppDelegate.m

01#import "FacebookAPIAppDelegate.h"
02#import "FacebookAPIViewController.h"
04@implementation FacebookAPIAppDelegate
06@synthesize window;
07@synthesize viewController;
08@synthesize _session;
10- (void)applicationDidFinishLaunching:(UIApplication *)application {
12// Override point for customization after app launch
13[window addSubview:viewController.view];
14[window makeKeyAndVisible];
17- (void)dealloc {
18          [_session release];
19          [viewController release];
20          [window release];
21          [super dealloc];
Here in FacebookAPIAppDelegate we have just declared _session variable of type FBSession to keep track of the session and to check if session for current user exists or not.
Append Following code in FacebookAPIViewController.h

03#import "FBConnect/FBConnect.h"
04#import "FBConnect/FBSession.h"
06@interface FacebookAPIViewController : UIViewController   {
07             FBLoginButton *loginButton;
08             UIAlertView *facebookAlert;
09             FBSession *usersession;
10             NSString *username;
11             BOOL post;
14@property(nonatomic,retain) FBLoginButton *loginButton;
15@property(nonatomic,retain) UIAlertView *facebookAlert;
16@property(nonatomic,retain)  FBSession *usersession;
17@property(nonatomic,retain) NSString *username;
18@property(nonatomic,assign) BOOL post;
20- (BOOL)textFieldShouldReturn:(UITextField *)textField;
Append Following code in FacebookAPIViewController.m

01#import "FacebookAPIViewController.h"
02#import "FacebookAPIAppDelegate.h"
04#define _APP_KEY @"Your API Key Goes here"
05#define _SECRET_KEY @"Your Secrete Key Goes here"
07@implementation FacebookAPIViewController
08@synthesize loginButton;
09@synthesize facebookAlert;
10@synthesize usersession;
11@synthesize username;
12@synthesize post;
14- (void)viewDidLoad {
15               FacebookAPIAppDelegate *appDelegate =
16                          (FacebookAPIAppDelegate *)   [[UIApplication
17                                            sharedApplication]delegate];
18                if (appDelegate._session == nil){
19                appDelegate._session = [FBSession
20                                   sessionForApplication:_APP_KEY
21                                   secret:_SECRET_KEY delegate:self];
22                 }
23                 if(self.loginButton == NULL)
24                 self.loginButton = [[[FBLoginButton alloc] init] autorelease];
25                 loginButton.frame = CGRectMake(0, 0, 100, 50);
26                 [self.view addSubview:loginButton];
28                 [super viewDidLoad];
31- (void)dealloc {
32               [username release];
33               [usersession release];
34               [loginButton release];
35               [super dealloc];
38- (void)session:(FBSession*)session didLogin:(FBUID)uid {
39                self.usersession =session;
40                NSLog(@"User with id %lld logged in.", uid);
41                [self getFacebookName];
44- (void)getFacebookName {
45         NSString* fql = [NSString stringWithFormat:
46         @"select uid,name from user where uid == %lld",
47                               self.usersession.uid];
48        NSDictionary* params =
49        [NSDictionary dictionaryWithObject:fql
50        forKey:@"query"];
51   [[FBRequest requestWithDelegate:self]
52  call:@"facebook.fql.query" params:params];
56- (void)request:(FBRequest*)request didLoad:(id)result {
57              if ([request.method isEqualToString:@"facebook.fql.query"]) {
58                          NSArray* users = result;
59                          NSDictionary* user = [users objectAtIndex:0];
60                          NSString* name = [user objectForKey:@"name"];
61                          self.username = name;
63                          if ( {
64                                     [self postToWall];
65                            = NO;
66                          }
67              }
70- (void)postToWall {
72               FBStreamDialog *dialog = [[[FBStreamDialog alloc] init]
73                                             autorelease];
74               dialog.userMessagePrompt = @"Enter your message:";
75               dialog.attachment = [NSString
76                    stringWithFormat:@"{\"name\":\"Facebook Connect for
77                    iPhone\",\"href\":\"
78                    connect.phptab=iphone\",\"caption\":\"Caption\",
79                    \"description\":\"Description\",\"media\":[{\"type\":
80                    \"image\",\"src\":\"
81                     5914/iphoneconnectbtn.jpg\",\"href\":
82                     \"
83                      tab=iphone/\"}],\"properties\":{\"another link\":
84                      {\"text\":\"Facebook home page\",\"href\":
85                      \"\"}}}"];
87               [dialog show];
91- (BOOL)textFieldShouldReturn:(UITextField *)textField
93                [textField resignFirstResponder];
94                return YES;
Define API key and Secret key with the keys you received while registering your app on facebook.

1#define _APP_KEY @"43e37a535cc09c2013bd76fde78dfcc7"
2#define _SECRET_KEY @"cc14801521a0c4d1dc31b7cacb891072"
Validate session variable in ViewDidLoad. If it doesn’t exist then create the same for using API key and Secret key. For that, one needs to conform the protocol FBSessionDelegate in respective header file. Also create a login button using FBLoginButton.
While implementing protocol FBSessionDelegate one needs to implement following mandatory method

1(void)session:(FBSession*)session didLogin:(FBUID)uid
This methos is automatically called when user is logged in using FBConnect SDK.
In this method we get session for that user and it’s uid which unique identifier for that user.
Once FBSession session is avaiable, we can accesss all the APIs provided by Facebook.
For now, we will see how to post user name and status on the facebook wall.
To get Facebook username a request is send in which select query is written to get username using uid.

1NSString* fql = [NSString stringWithFormat:
2@"select uid,name from user where uid == %lld", self.usersession.uid];
3NSDictionary* params = [NSDictionary dictionaryWithObject:fql forKey:@"query"];
4[[FBRequest requestWithDelegate:self] call:@"facebook.fql.query" params:params];
Override following FBRequestDelegate method to check the reponse of above query.

1(void)request:(FBRequest*)request didLoad:(id)result
The argument result is an array of NSDictionary Objects which contains info for that user as key-value pairs. Retrieve it as follows:

1NSArray* users = result;
2NSDictionary* user = [users objectAtIndex:0];
3NSString* name = [user objectForKey:@"name"];
Use FBStreamDialog class post message on the facbook wall. A dialog pops up with a message box to post on Wall.

1FBStreamDialog *dialog = [[[FBStreamDialog alloc] init] autorelease];
2dialog.userMessagePrompt = @"Enter your message:";
3dialog.attachment = [NSString stringWithFormat:@"{\"name\":\"Facebook Connect for iPhone\",\"href\":\"\",\"caption\":\"Caption\",\"description\":\"Description\",\"media\":[{\"type\":\"image\",\"src\":\"\",\"href\":\"\"}],\"properties\":{\"another link\":{\"text\":\"Facebook home page\",\"href\":\"\"}}}"];
4[dialog show];
Now Save project (Command +S). Build and Run Project.
Simulator will look like as follows

Click on Fconnect Button and Facebook Login Dialog will appear.

Login with your user name and Password . Wait for untill post to Wall Dialog pops up

You can download the source code from here

Tuesday, January 18, 2011

Best 23 Open Source iPhone Apps & Source Code

Best 23 Open Source iPhone Apps & Source Code

The iPhone platform now has more than 100,000 apps, and they're almost all available through the iTunes App Store. That's an amazing rate of growth, and it shows how rich the iPhone platform is for developers. Of course, this list can't possibly be comprehensive. If you're comfortable with having everyone know where you are at all times, go ahead and try those apps out, too. Here, though, are my first favorites.

1. Diceshaker - little dice-rolling utility for your roleplaying sessions and board games. It's designed to be simple, uncluttered and easy to use. source code
2. - Listen to more than 5 million tracks for free with on your iPhone. Create personal radio stations based on any artist or genres, and listen to commercial free music for hours. With on the iPhone you can also check out artist bios and concert information and share your favourite tracks with your friends using the iPhone contact list. source code
3. ABC 123 - " Simple in concept. Brilliantly addictive. Maddeningly challenging." - TheYoshi
Memorize the sequence of letters or numbers. The sequence will then be covered with bubbles. Pop the bubbles in the order of the sequence to beat the level. source code
4. Mobilesynth - open source classic monophonic synthesizer, designed for live performance. Developers are encouraged to visit the website and contribute. source code
5. Gorillas - Gorillas is a port of the original GORILLA.BAS to the iPhone platform. It's a turn based single player game where the objective is to blast your opponent away using carefully aimed bananas. source code
6. PocketFlix - With iPhone and PocketFlicks you can find movies and manage your Netflix information, all while on the go. Heard about a great movie from a friend of yours? Whip out PocketFlicks and add it to your Netflix queue with just a few clicks. You'll never forget about a movie you want to watch now! source code
7. Sci-15 HPCalc - The SCI-15C is the most accurate and precise emulator of the world-renowned HP 15C RPN high-end scientific programmable calculator available for the iPhone and iPod Touch. We use the *exact same* mathematics and calculations of the original to give you reliable, bug-free, precision and accuracy that you can trust. source code
8. Task Coach - This is the iPhone version of the open-source Task Coach desktop application. It features basic task editing and synchronization with its desktop counterpart over the network. source code
9. Tweejump - Tweejump is a jumping arcade game inspired by many wonderful games including Icy Tower, Doodle Jump, PapiJump, and others. source code
10. Freshbooks - MiniBooks Lite puts the popular web invoicing software FreshBooks in the palm of your hand. Manage your clients, send invoices, run timers, and record payments, all while on the go. Plus, MiniBooks Lite fully synchronizes with your FreshBooks account, so you have access to your account even when you're off the grid. source code
11. Colloquy - Colloquy for iPhone and iPod touch puts the power of the most popular IRC client for the Mac in the palm of your hand. Built atop the Chat Core framework, Colloquy Mobile is a full featured client optimized for the on-the-go experience. source code
12. Doom Classic - DOOM Classic includes the original three episodes as well as Episode Four, Thy Flesh Consumed, spread across 36 levels of non-stop carnage and action. source code
13. Molecules - Molecules is an application for viewing three-dimensional renderings of molecules and manipulating them using your fingers. You can rotate the molecules by moving your finger across the display, zoom in or out by using two-finger pinch gestures, or pan the molecule by moving two fingers across the screen at once. Double-tapping on the display lets you switch visualization modes. source code
14. Packlog - Introducing PackLog for Backpack. The easiest way to update your Backpack status and add journal entries right from your iPhone or iPod touch! source code
15. Wikihow - Bonus feature: The application includes the ‘wikiHow Survival Kit,’ a collection of articles to get you through life's most difficult situations. Includes articles on first aid such as CPR, the Heimlich maneuver, treating burns and bleeding. source code
16. Tubestatus - Get up to the minute service level details on all London Underground tube lines, DLR and Overground.  source code
17. Wordpress - Manage your WordPress blog from your iPhone or iPod touch. With WordPress for iPhone, you can moderate comments and create or edit posts and pages. All you need is a blog or a self-hosted blog running WordPress 2.7 or higher. source code
18. YourRights - if government agents question you, it is important to understand your rights. You should be careful about what you say when approached by law enforcement officials. If you give answers, they can be used against you in a criminal, immigration, or civil case. source code
19. Mover - Mover+ is the quickest way to move stuff from iPhone A to iPhone B, with style. Put what you want to send on the Mover table, connect via Wi-Fi or Bluetooth, and flick it offscreen where you want it to go! source code
20. NowPlaying - Added 'People Search' to Netflix. You can now lookup actors, actresses, directors, etc. and get their bio, filmography and additional details. source code
21. Natsulion - is a simple Twitter client for iPhone/iPod touch. It has simple, fast, and slick user-interface to enjoy Twitter. It's based on NatsuLion for Mac OSX and it's open source application, too. source code
22. Twitterfon - Echofon (formerly ‘Twitterfon’) is an easy to use, super-fast Twitter app for the iPhone and iPod Touch. source code
23. Tweetero - Twitter client with image upload support. source code

Saturday, November 27, 2010

iPhone / Objective C Learning

Objective C Learning:

Calling Methods

To get started as quickly as possible, let's look at
some simple examples. The basic syntax for calling a method on an
object is this:

[object method];
[object methodWithInput:input];

Methods can return a value:

output = [object methodWithOutput];
output = [object methodWithInputAndOutput:input];

You can call methods on classes too, which is how you create objects. In the
example below, we call the string method on the NSString class, which
returns a new NSString object:

id myObject = [NSString string];

The id type means that the myObject variable can refer to any kind of object,
so the actual class and the methods it implements aren't known when you compile the app.

In this example, it's obvious the object type will be an NSString, so we can change the type:

NSString* myString = [NSString string];

This is now an NSString variable, so the compiler will warn us if we try to use
a method on this object which NSString doesn't support.

Notice that there's a asterisk to the right of the object type. All Objective-C object variables are
pointers types. The id type is predefined as a pointer type, so there's no need
to add the asterisk.

Nested Messages

In many languages, nested method or function calls look like this:

function1 ( function2() );

The result of function2 is passed as input to function1. In Objective-C, nested messages
look like this:

[NSString stringWithFormat:[prefs format]];

Avoid nested nesting more than two message calls on a single line, as it easily gets unreadable.

Multi-Input Methods

Some methods take multiple input values. In Objective-C, a method name can be split
up into several segments. In the header, a multi-input method looks like this:

-(BOOL)writeToFile:(NSString *)path atomically:(BOOL)useAuxiliaryFile;

You call the method like this:

BOOL result = [myData writeToFile:@"/tmp/log.txt" atomically:NO];

These are not just named arguments. The method name is actually writeToFile:atomically: in the runtime system.


All instance variables are private in Objective-C by default, so you should use
accessors to get and set values in most cases. There are two syntaxes. This is the traditional 1.x syntax:

[photo setCaption:@"Day at the Beach"];
output = [photo caption];

The code on the second line is not reading the instance variable directly.
It's actually calling a method named caption. In most cases, you don't
add the "get" prefix to getters in Objective-C.

Whenever you see code inside square brackets, you are sending
a message to an object or a class.

Dot Syntax

The dot syntax for getters and setters is new in Objective-C 2.0, which is part of Mac OS X 10.5:

photo.caption = @"Day at the Beach";
output = photo.caption;

You can use either style, but choose only one for each project.
The dot syntax should only be used setters
and getters, not for general purpose methods.

Creating Objects

There are two main ways to create an object. The first is the one you saw before:

NSString* myString = [NSString string];

This is the more convenient automatic style. In this case, you are creating an
autoreleased object, which we'll look at in more detail later. In many cases,
though, you need to create an object using the manual style:

NSString* myString = [[NSString alloc] init];

This is a nested method call. The first is the alloc method called on NSString itself. This
is a relatively low-level call which reserves memory and instantiates an object.

The second piece is a
call to init on the new object. The init implementation usually does basic setup, such as
creating instance variables. The details of that are unknown to you as a client of the class.

In some cases, you may use a different version of init which takes input:

NSNumber* value = [[NSNumber alloc] initWithFloat:1.0];

Basic Memory Management

If you're writing an application for Mac OS X, you have the option to enable garbage collection.
In general, this means that you don't have to think about memory management until you get to
more complex cases.

However, you may not always be working with an environment that supports garbage collection. In that
case, you need to know a few basic concepts.

If you create an object using the manual alloc style, you need to release the
object later. You should not manually release an autoreleased object because your
application will crash if you do.

Here are two examples:

// string1 will be released automatically
NSString* string1 = [NSString string];

// must release this when done
NSString* string2 = [[NSString alloc] init];
[string2 release];

For this tutorial, you can assume that an automatic object will go away
at the end of the current function.

There's more to learn about memory management, but it will make more sense
after we look at a few more concepts.

Designing a Class Interface

The Objective-C syntax for creating a class is very simple. It typically
comes in two parts.

The class interface is usually stored in the ClassName.h file, and defines
instance variables and public methods.

The implementation is in the ClassName.m file and contains the actual code for these
methods. It also often defines private methods that aren't available to clients of the class.

Here's what an interface file looks like. The class is called Photo, so
the file is named Photo.h:


@interface Photo : NSObject {
NSString* caption;
NSString* photographer;

First, we import Cocoa.h, to pull in all of the basic classes for a Cocoa app.
The #import directive automatically guards against including a single
file multiple times.

The @interface says that this is a declaration of the class Photo. The colon specifies the superclass, which is NSObject.

Inside the curly brackets, there are two instance variables: caption and photographer.
Both are NSStrings, but they could be any object type, including id.

Finally, the @end symbol ends the class declaration.

Add Methods

Let's add some getters for the instance variables:

@interface Photo : NSObject {
NSString* caption;
NSString* photographer;

- caption;
- photographer;


Remember, Objective-C methods typically leave out the "get" prefix.
A single dash before a method name means it's a instance method. A plus
before a method name means it's a class method.

By default, the compiler assumes a method returns an id object, and that
all input values are id. The above code is technically correct, but it's unusual.
Let's add specific types for the return values:

#import >

@interface Photo : NSObject {
NSString* caption;
NSString* photographer;

- (NSString*) caption;
- (NSString*) photographer;


Now let's add setters:
#import >
@interface Photo : NSObject {
NSString* caption;
NSString* photographer;
- (NSString*) caption;
- (NSString*) photographer;

- (void) setCaption: (NSString*)input;
- (void) setPhotographer: (NSString*)input;


Setters don't need to return a value, so we just specify them as void.

Class Implementation

Let's create an implementation, starting with the getters:

#import "Photo.h"

@implementation Photo

- (NSString*) caption {
return caption;

- (NSString*) photographer {
return photographer;


This part of the code starts with @implementation and the class
name, and has @end, just like the interface. All methods
must appear between these two statements.

The getters should look very familiar if you've ever written code, so let's move
on to the setters, which need a bit more explanation:

- (void) setCaption: (NSString*)input
[caption autorelease];
caption = [input retain];

- (void) setPhotographer: (NSString*)input
[photographer autorelease];
photographer = [input retain];

Each setter deals with two variables. The first is a reference to the
existing object, and the second is the new input object. In a garbage
collected environment, we could just set the new value

- (void) setCaption: (NSString*)input {
caption = input;

But if you can't use garbage collection, you need to release the old
object, and retain the new one.

There are actually two ways to free a reference to an object: release and
autorelease. The standard release will remove the reference immediately.
The autorelease method will release it sometime soon, but it will definitely stay
around until the end of the current function (unless you add custom code to
specifically change this).

The autorelease method is safer inside a setter because the variables for the new
and old values
could point to the same object. You wouldn't want to immediately release an object which
you're about to retain.
This may seem confusing right now, but it will make more
sense as you progress. You don't need to understand it all yet.


We can create an init method to set inital values for our instance variables:

- (id) init

if ( self = [super init] )
[self setCaption:@"Default Caption"];
[self setPhotographer:@"Default Photographer"];
return self;
This is fairly self-explanatory, though the second line may look a bit unusual.
This is a single equals sign, which assigns the result of [super init]
to self.

This essentially just asks the superclass to do its own
initialization. The if statement is verifying that
the initialization was successful before trying to set default values.


The dealloc method is called on an object when it is being removed from
memory. This is
usually the best time to release references to all of your child instance variables:

- (void) dealloc
[caption release];
[photographer release];
[super dealloc];

On the first two lines, we just send release to each of the instance variables.
We don't need to use autorelease here, and the standard release is a bit faster.

The last line is very important. We have to send the message
[super dealloc] to
ask the superclass to do its cleanup. If we don't do this, the object will not
be removed, which is a memory leak.

The dealloc method is not called on objects if garbage collection is enabled.
Instead, you implement the finalize method.

More on Memory Management

Objective-C's memory management system is called reference counting. All you have
to do is keep track of your references, and the runtime does the actual freeing
of memory.

In simplest terms, you alloc an object, maybe retain
it at some point, then send one release for each alloc/retain you sent.
So if you used alloc once and then retain once, you need to release twice.

That's the theory of reference counting. But in practice, there are usually only two reasons to
create an object:

1. To keep it as an instance variable

2. To use temporarily for single use inside a function

In most cases, the setter for an instance
variable should just autorelease the old object, and retain the new one. You then
just make sure to release it in dealloc as well.

So the only real work is managing local references inside a function. And there's
only one rule: if you create an object with alloc or copy,
send it a release or autorelease message at the
end of the function. If you create an object any other way, do nothing.

Here's the first case, managing an instance variable:

- (void) setTotalAmount: (NSNumber*)input
[totalAmount autorelease];
totalAmount = [input retain];

- (void) dealloc
[totalAmount release];
[super dealloc];

Here's the other case, local references. We only need to release the
object created with alloc:

NSNumber* value1 = [[NSNumber alloc] initWithFloat:8.75];
NSNumber* value2 = [NSNumber numberWithFloat:14.78];

// only release value1, not value2
[value1 release];

And here's a combo: using a local reference to set an object as an
instance variable:

NSNumber* value1 = [[NSNumber alloc] initWithFloat:8.75];
[self setTotal:value1];

NSNumber* value2 = [NSNumber numberWithFloat:14.78];
[self setTotal:value2];

[value1 release];

Notice how the rules for managing local references are exactly the same,
regardless of whether you're setting them as instance variables or not.
You don't need to think about how the setters are implemented.

If you understand this, you understand 90% of what you will ever need to
know about Objective-C memory management.


Logging messages to the console in Objective-C is very simple. In fact,
the NSLog() function is nearly identical to the C printf() function, except
there's an additional %@ token for objects.

NSLog ( @"The current date and time is: %@", [NSDate date] );

You can log an object to the console. The NSLog function calls the description method
on the object, and prints the NSString which is returned. You can override the description
method in your class to return a custom string.


When we wrote the accessor methods for caption and author earlier,
you might have noticed that the code is straightforward, and could probably be generalized.

Properties are a feature in Objective-C that allow us to automatically generate
accessors, and also have some other side benefits. Let's convert the Photo class to
use properties.

Here's what it looked like before:

#import >

@interface Photo : NSObject {
NSString* caption;
NSString* photographer;
- (NSString*) caption;
- (NSString*) photographer;

- (void) setCaption: (NSString*)input;
- (void) setPhotographer: (NSString*)input;


Here's what it looks like once converted to properties:


@interface Photo : NSObject {
NSString* caption;
NSString* photographer;
@property (retain) NSString* caption;
@property (retain) NSString* photographer;


The @property is an Objective-C directive which declares the property. The
"retain" in the parenthesis specifies that the setter should retain the input
value, and the rest of the line simply specifies the type and the name of the

Now let's take a look at the implementation of the class:

#import "Photo.h"
@implementation Photo

@synthesize caption;
@synthesize photographer;
- (void) dealloc
[caption release];
[photographer release];
[super dealloc];

The @synthesize directive automatically generates the setters and getters for
us, so all we have to implement for this class is the dealloc method.

Accessors will only be generated if they don't already exist, so feel free to specify @synthesize
for a property, then implement your custom getter or setter if you want. The compiler will
fill in whichever method is missing.

There are many other options for the property declarations, but those are
outside of the scope of this tutorial.

Calling Methods on Nil

In Objective-C, the nil object is the functional equivalent to the NULL

pointer in many other languages. The difference is that you can call methods
on nil without crashing or throwing an exception.

This technique used by the frameworks in a number of different ways, but the
main thing it means to you right now that you usually don't need to check
for nil before calling a method on an object. If you call a method on nil that
returns an object, you will get nil as a return value.

We can also use this to improve our dealloc method slightly:

- (void) dealloc
self.caption = nil;
self.photographer = nil;
[super dealloc];
This works because when we set nil as an instance variable, the setter just retains
nil (which does nothing) and releases the old value. This approach is often better
for dealloc because there's no chance of the variable pointing at random data where
an object used to be.

Note that we're using the self. syntax here, which means
we're using the setter and picking up the memory management for free. If
we just directly set the value like this, there would be a memory leak:

// incorrect. causes a memory leak.
// use self.caption to go through setter
caption = nil;


Categories are one of the most useful features of Objective-C. Essentially,
a category allows you to add methods to an existing class without subclassing
it or needing to know any of the details of how it's implemented.

This is particularly useful because you can add methods to built-in objects. If
you want to add a method to all instances of NSString in your application, you
just add a category. There's no need to get everything to use a custom subclass.

For example, if I wanted to add a method to NSString to determine if the contents
is a URL, it would look like this:


@interface NSString (Utilities)
- (BOOL) isURL;


This is very similar to a class declaration. The differences are that
there is no super class listed, and there's a name for the category in
parenthesis. The name can be whatever you want, though it should communicate
what the methods inside do.

Here's the implementation. Keep in mind this is not a good implementation
of URL detection. We're just trying to get the concept of categories across:

#import "NSString-Utilities.h"

@implementation NSString (Utilities)

- (BOOL) isURL

if ( [self hasPrefix:@"http://"] )
return YES;
return NO;


Now you can use this method on any NSString. The following code will print
"string1 is a URL" in the console:

NSString* string1 = @"";
NSString* string2 = @"Pixar";

if ( [string1 isURL] )
NSLog (@"string1 is a URL");

if ( [string2 isURL] )
NSLog (@"string2 is a URL");

Unlike subclasses, categories can't add instance variables. You can, however, use
categories to override existing methods in classes, but you should do so
very carefully.

Remember, when you make changes to a class using a category, it affects all instances
of that class throughout the application.