Monday, June 7, 2010

4 ways to save data in iphone

Saving data is very important in many applications. May it be games or other applications, data persistence is essential. There are mainly 4 ways to save data in iphone. They are as follows:

1. User Defaults:
This is probably the easiest and simplest way to save data in iphone. You can save the plist objects ie NSData, NSString, NSArray, NSNumber, NSDate and NSDictionary using user defaults. Other data types like floats, doubles, integers, booleans can also be saved using user defaults. Lets see some examples.

Saving:
[[NSUserDefaults standardUserDefaults] setInteger:5 forKey:@"number"];
[[NSUserDefaults standardUserDefaults] setObject:@"hello" forKey:@"string"];


Retrieving:
NSInteger i = [[NSUserDefaults standardUserDefaults] integerForKey:@"number"];
NSString *s = [[NSUserDefaults standardUserDefaults] objectForKey:@"string"];


2. Files:
Data can also be saved in files using file manager. The following code shows an example of how an array is saved in a file named file.plist in the document directory and retreived later.

//save data
-(void)saveData{
      NSString *path = [(NSString *) [NSSearchPathForDirectoriesInDomains (NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0] stringByAppendingPathComponent:@"file.plist"];
      NSArray *dataArray = [NSArray arrayWithObjects:@"item1",@"item2",nil];
      [dataArray writeToFile:path atomically:YES];
}

//load data
- (void) loadData {
      NSString *path = [(NSString *) [NSSearchPathForDirectoriesInDomains (NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0] stringByAppendingPathComponent:@"file.plist"];
      if ([[NSFileManager defaultManager] fileExistsAtPath: path]) {
            NSArray *dataArray= [[NSArray alloc] initWithContentsOfFile: path];       }
      else {
            NSLog(@"File not found");
      }
}


3. SQLite Database:
If you need a full-blown database functionality, iphone provides you with the ability to use SQLite databases. You can have databases and write normal SQL queries. But ever since the introduction of core data in iphone OS 3, core data is much preferred than using raw SQLite. Internally core data also uses SQLite but it abstracts all the ugly details of underlying SQLite. If you are planning to use SQLite, I would suggest you to use core data instead. But if you are curious and want to learn how to use SQLite, there is a very nice 4 part tutorial at icodeblog.

4. Core Data:
As I said earlier, core data is an abstraction layer that sits on top of SQLite database. Majority of people prefer core data to using raw SQLite. But the learning curve is a more steep. You will find quite a lot of new concepts and terminologies in core data which can be quite intimidating at the beggining. Also it is a quite a big topic that entire books have been written on it. If you are really willing to master core data, then Core Data for iPhone by Tim Isted might be the book for you. Apple's tutorials for core data is also a good place to start learning core data.

Sunday, June 6, 2010

Saving persistent data on iphone while application exits

In many instances you would want to save application data when user exits your application. Since exiting an application programmatically is forbidden, the only way to exit any application in iphone is to press the home button. So how would you be able to save the data when user exits your application?

When the home button is pressed the UIApplication's delegate method applicationWillTerminate is called. So you can put the code to save your persistent data inside this method in your appDelegate class.

- (void)applicationWillTerminate:(UIApplication *)application{
//code to save your data
//If you don't know how data is saved, view this post on saving data in iphone
}


But there is still one problem. Since the above method will be in you appDelegate class, it might be troublesome to save data in other view controller classes. To solve this problem you can subscribe to notification named UIApplicationWillTerminateNotification.

-(void)viewDidLoad{
[[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(appTermination:) name: @"UIApplicationWillTerminateNotification" object: nil];
}

-(void)appTermination:(id)sender{
//code to save your data
//If you don't know how data is saved, view this post on saving data in iphone
}


What this does is that it subscribes for the UIApplicationWillTerminateNotification notification in viewDidLoad method and sets appTermination method to be called when this notification is received

Saturday, May 29, 2010

Memory management and properties in Objective C

It is often confusing to understand memory management while using properties. Properties have semantic attributes viz. assign, copy and retain which play a vital role in memory management. Lets consider an example:
@interface MyClass : NSObject{
     NSString *myString;
     NSString *yourString;
}
@property (nonatomic, retain) NSString *myString;
@property (nonatomic, assign) NSString *yourString;
@end

In the above example you can see that both string declarations are pretty same except that myString uses retain but yourString uses assign. Now lets see how memory management works for both.

Lets see the implementation code:
@implementation MyClass
@synthesize myString;
@synthesize yourString;

-(id)init{
    if((self = [super init])){
        self.myString = [[NSString alloc] initWithString:@"this is my string"];
        self.yourString = [[NSString alloc] initWithString:@"this is your string"];
    }
    return self;
}

-(void)dealloc{
     [myString release];
     [yourString release];
     [super dealloc];
}
@end

Ok, can you see a memory leak here. See the line
self.myString = [[NSString alloc] initWithString:@"this is my string"];

Remember that we declared myString as
@property (nonatomic, retain) NSString *myString;


So using self.myString will retain the string (rather than just assign) after it has been 'alloced'. Since we must release the object when we either use alloc or retain, we have to release the object myString twice but we have released it just once in dealloc method which means we will have a memory leak.

Solutions:
Method 1:
NSString *temp =  [[NSString alloc] initWithString:@"this is my string"];
   self.myString = temp;
   [temp release];
 
Here the 'alloced' string is released right after myString retains it. myString is released in dealloc method.

Method 2:
self.myString = [[[NSString alloc] initWithString:@"this is my string"] autorelease];
Short form for method 1.

Method 3:
myString = [[NSString alloc] initWithString:@"this is my string"];
Using myString alone without the self. prefix means that we are not using it as a property. So it is not retained. Hence the string is released in dealloc method.

Now as for our another string ie 'yourString', it doesn't have any error in above sample class but lets assume if we had done something like this:
self.yourstring = [NSString stringWithString:@"this is my string"];

Remember we used assign for yourString:
@property (nonatomic, assign) NSString *yourString;

So neither did we alloc this string nor do we retain it. Hence we don't own it. Releasing this object will produce an error.

Wednesday, May 26, 2010

Memory management basics in Objective C

In any platform with garbage collection enabled, you don't really have to worry about memory management. Developers who come from a garbage collected environment like Java will specially find it difficult to understand the concepts of memory management. Memory management is probably one of the toughest obstacles that a beginner might face while learning Objective C. Since there is no garbage collection facility in iphone, any wannabe iphone developer must learn about it. So one question might pop up in your mind. Why is it so important? Because iphone has limited memory and you don't want to burn its memory out so that your application just crashes out. Now lets get to the basic concepts of memory management.

Object Ownership
There are certain conditions when you'll become the owner of an object. There are 3 ways by which you can become an owner of an object. But remember you have to dispose all objects you own.

Case 1. You created a new object in the memory using alloc.
e.g. NSString *string1 = [[NSString alloc] initWithString:@"hello"];

Case 2. You copied an existing object to another object.
e.g. NSString *string2 = [string1 copy];

Case 3. You retain an existing object.
e.g. [string2 retain];

In case 1, you used alloc to create an object so a new object named 'string1' is created. In case 2, you copied string1 to string2. In case 3, you retained an already existing object 2. So you have ownership of string1 and double ownership of string2.

Any object that is created using any other method is not owned by you.
e.g. NSString *string3 = [NSString stringWithFormat:@"%d",12345];

Although it seems as if you just created a string object, you don't own it.

Object Disposal
You have to dispose every object that you own. You dispose an object by sending a release or an autorelease message. To dispose the objects from the above 3 cases we have to do the following:

Case 1: [string1 release];
Case 2: [string2 release];
Case 3: [string2 release];

The difference between release and autorelease is that autorelease releases the object only after certain events are processed whereas release will release the object instantly.

Retain Count
Internally Objective C uses the concept of retain counts for memory management. Every object has a retain count. Retain counts can increase and decrease. When the retain count of any object becomes zero, it is released from memory. It means that the object is no longer available. Trying to access a released object will cause the application to crash. Here are the retain count rules:

1. When you create an object with alloc or copy, it has a retain count of 1.
2. When you send an object a retain message, its retain count is incremented by 1.
3. When you send an object a release message, its retain count is decremented by 1.
4. When you send an object a autorelease message, its retain count is decremented by 1 at some stage in the future.
5. If an object’s retain count is reduced to 0, it is deallocated.

eg: NSString *string = [[NSString alloc] initWithString:@"hello"]; => retain count = 1
[string retain]; => retain count = 2
[string release]; => retain count = 1
[string release]; => retain count = 0(object released or disposed)


Tuesday, May 25, 2010

A complete beginners guide to start iphone development

So you are a beginner and want to start programming for iphone or ipad and don't have an idea of where to start. Then you have come to the right place. At this point of time you may not own a mac for iphone development, or don't have an iphone. You may not even know that there exists a language called Objective C in which you will be doing your iphone development. Now lets go through the steps that you'll need to follow to start iphone development.

Step 1: Get a mac
First of all you'll need to buy an apple macintosh computer if you don't have it. Since macbook pro and iMacs are relatively expensive, if you don't have enough money you can buy a mac mini which are cheaper and costs about $600. Iphone development in other platforms is virtually impossible. You might be able to build a simple app using 3rd party tools but you would never be able to deploy them to app store. So rather than wasting time trying to build iphone app on other platforms go and buy a mac right now!

Step 2: Download Xcode
So you've bought a mac my dear beginner! If you don't know how to use a mac, you can visit Mac 101 to learn about using mac. Now you'll have to download XCode. So what is XCode? Well its an IDE for mac/iphone development. To download it, first go to http://developer.apple.com/iphone . You'll need to register as developer with apple before you can download the XCode IDE. So click on login and register. Now you can download the XCode for your mac OS. Installing XCode is pretty straightforward. You'll gradually learn how to use and take full advantage of XCode gradually. Teaching how to use XCode is beyond the scope of this tutorial. A good book to learn about XCode is XCode 3 unleashed by Fritz Anderson.

Step 3: Learn Objective C
Probably the biggest mistake a beginner would make while starting iphone development, is to jump into iphone development without learning the basics of Objective C. Its a mistake that I made. I started with apples sample iphone app tutorial when I didn't have any knowledge of Objective C. And I understood nothing. So I had to go back and study Objective C first. I learnt a lot about Objective C from Learn Objective–C on the Mac . Its a language with an odd syntax quite different from the languages you might be familiar with like C, C++ or Java. Objective C is an object oriented language but the fun part is that you can mix C with it.

Step 4: Learn iphone SDK
Phew, finally the real fun begins. You now have to learn the iphone SDK. There are a lot of books on learning iphone SDK and there always is the good ol' Apple's Iphone SDK Documentation. You can either download the documentation through XCode or just use the online documentation . I studied quite a few books while learning iphone development. These are some books that proved to be extremely helpful to me.
1. iPhone SDK Development
2. Beginning iPhone 3 Development: Exploring the iPhone SDK
3.The iPhone Developer's Cookbook

Step 5: Get developers license
So now you can build your own app huh! But you'll be able to test it only on the simulator and also you cannot deploy it to app store. For building your app to the device and deploying to the app store you'll need to get a paid developer license which costs $99.

Step 6: Buy iphone/ipod touch
Now that you have a developers license, you can buy an iphone or ipod touch to test your app on. You can learn about how to deploy your app to your device and the app store from apples program portal which will be available after you get developers license.

Lets have some fun

Hey guys! Lets have some fun with iphone programming. I've been programming iphone for about 8-9 months now. I will be sharing tips, tricks and the lessons that I have thus far learnt. So lets get started