lunes, 19 de diciembre de 2011

Execute methods asynchronously using NSOperation

Sometimes we want to run some methods in background, for example a service request.
Cocoa has a class ready for execute asynchronous methods, it's NSOperation. NSOperation is a key value coding and key value observing compilant, this means that you can observe some properties to perform different actions in your application, for example, if it finished executing (isExecuting).


  1. //We init a new queue
  2. //Create a new operation
  3. NSInvocationOperation *operation = [NSInvocationOperation alloc] initWithTarget:self selector:@selector(getAge:) object:@"Nicolas"];
  4. //Add operation to the queue
  5. [queue addOperation:operation];


Right here we are creating a new queue and adding an operation to it, this way the callback is in the queue and will be called asynchronously.
So we need to declare the callback


  1. -(void)getAge:(id)sender
  2. {
  3.    //Do magic
  4. }


In this case sender will be an (NSString *) object with value "Nicolas", but you can send whatever object you want as a parameter to the callback.

How to use NSUserDefaults

NSUserDefaults is a useful class used to store data in the device, you can save and access information quickly.


  1. //First we get the singleton initialization for NSUserDefaults
  2. NSUserDefaults *myPreferences = [NSUserDefaults standardUserDefaults];
  3. // We are trying to save our volume value
  4. [myPreferences  setDouble:0.9 forKey:@"Volume"];
  5. //We will force to synchronize
  6. [myPreferences  synchronize];


Notice that in this case we have saved our volume value which is a double, but we can store integer, string, even an object to NSUserDefaults class.

So now we can call synchronize to synch all the values that we have been set. Synchronize method is not necessary because it is called during a period of time, but you can call it to ensure that your data is synched.

So now if we need to get the value of our volume, we can just write:

  1. //We use our NSUserDefaults object to get the Volume
  2. double volume = [myPreferences doubleForKey@"Volume"];

And that's all, we can store some values in our device using this simple class.

miércoles, 14 de diciembre de 2011

Working with NSNotifications

Notifications are a great way to communicate with all the application, you can send just a message or add an object to the notification too.
The way it works is very simple, you need to post a notification with a name, for example if i want to let the project know my name, i could write :

  1. //Post notification
  2. [[NSNotificationCenter defaultCenter] postNotificationName:@"myNameIs"];

Right there you can see that NSNotificationCenter class has a defaultCenter. Commonly defaultCenter provides a singleton design pattern which has exactly one instance.
This way you'll use always the same object at memory, but how could the application knows my name if i'm not sending it?

You can also add an object to the postNotification method, for example in this case:

  1. //Now we add an object...
  2. [[NSNotificationCenter defaultCenter] postNotificationName:@"myNameIs" object:@"Nicolas Vidal"];

Gotcha! Now all the project should know my name, but... we need a way to listen to this notification.

So let's see that another ViewController is telling himself... "Which is his name?", so here come's the magic.

In the ViewController event, "ViewDidLoad" we must add an observer to that notification and a callback to receive that object.
So why ViewDidLoad? Because this event is called just when the View is loaded, remember that we need to add just ONE observer for each class/controller , and then remove our observer when we not need it
anymore.

  1. //Listen to notification
  2. [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(knowHisName:) name:@"myNameIs" object:nil] ;

That way we need to implement the selector this way :
  1. -(void)knowHisName:(NSNotification *) nameNotification
  2. {
  3.    NSString *hisName = [nameNotification object];
  4.    NSLog("%@",hisName);
  5. }
We could observe that the NSNotification has an object, the same that we sent in postNotification, pretty simple, huh?

Now we need to remove the observer to not listen anymore to my notification :
  1. //Removing notification
  2. [[NSNotificationCenter defaultCenter] removeObserver:self name:@"myNameIs" object:nil];

That's all... now you can send messages through all the application with this amazing class.

lunes, 12 de diciembre de 2011

Introduction to the Interface Builder

The interface builder is a great tool for designing the user interface (user interface) of our application.
From XCode 4, Interface Builder is integrated into XCode and can be used with ".xib" files.
XIB, short for Mac OS X Interface Builder, are XML files that contain the positions, types of elements and controls that contains the view you are creating.


The controls are part of the xib and must be IBOutlet type, so if we want to create a button in our view, we need to create it inside @interface.


  1. @interface xibTestViewController : UIViewController
  2. {
  3.       IBOutlet UIButton *_customButton;
  4. }


In case of events, for example when you press the button (event TouchUpInside:), action must be IBAction. Tapping the button will call an event like this:

  1. //Touch event
  2. -(IBAction) customButtonTouched:(id)sender;

After writing this in the interface, we can go to ".xib" file and drag a button to the view, as we see in the picture





Pressing right button we will see that it will list the events you can call, and also the ability to reference the IBOutlet.
Remember that the IBOutlet will serve to change control properties, such as text, size, among others.


We will see something like this:



If we hold down on the circle at the right of each event, and drag on "File's Owner", we will be able to see all IBOutlet controls that are in the interface, in this case, the buttons.


This is a quick introduction to the interface builder, I will post later more advanced articles on it.

domingo, 11 de diciembre de 2011

Basic language syntax III

Properties



Properties help us to define a piece of information, either a variable or object, and that it is visible to all classes that are going to consume it.
To create a property on the interface we must write the following

  1. //Property example
  2. @property(nonatomic,retain) NSString *example;

The parentheses "()" will specify the attributes of our property, for example, I decided to use nonatomic and retain.

Nonatomic means that if the setter or getter is being accessed from multiple threads, can not be interrupted, also nonatomic properties are much faster to access.

Making alloc and init makes retain count increases by 1.

On implementation side we call the @synthesize, to tell the compiler to generate the methods getter / setter that are necessary for the attributes that we have specified in the property.
For example:

  1. //@Synthesize generates our getter/setter functions
  2. @synthesize example;

To use it we call it this way:

  1. //Use self. to call our properties
  2. self.example = @"This is a test";

If we want to have a class variable and maintain the state both inside the class and when accessed from outside, we do as follows:

Interface

  1. @interface Test : NSObject
  2. {
  3.     NSString *_example;
  4. }
  5. @property(nonatomic,retain) NSString *example;

Implementation

  1. @implementation Test
  2. @synthesize example = _example;

When we use it

  1. self.example = @"Test";
  2. //Or...
  3. _example = @"Test";

sábado, 10 de diciembre de 2011

Basic language syntax II

It once learned as a class consists in Objective-C, next thing to learn is functions and methods


Functions and methods


As explained above, a class in Objective-C had an interface (. H) and implementation (. M).
Therefore the interface must list all methods and functions, an example of method could be:

  1. //Declare...
  2. -(void)addFriendWithName:(NSString *)name;

In the implementation ...

  1. -(void)addFriendWithName:(NSString *)
  2. {
  3.        //Code for our method
  4. }

We can see that there is a method start (-) to indicate that this method will be used
when you instantiate the class that contains it.

For example we could use the class importing the header (interface), in this case we could call it "Friend".

Then it would be something like:

  1. //Import header file
  2. #import "Friend.h"

And when we call it, we must instantiate it like

  1. Friend *objFriend = [[[Friend alloc] init] autorelease];
  2. [objFriend addFriendWithName:@"Nicolas"];

In this way we create a pointer to memory using alloc, initialize and invoke autorelease to tell the compiler to add the pointer to a release stack. This means that when not needed, this object will be removed automatically.
Recall that in Objective-C, we use memory management, so the objects must be freed as we don't need them anymore.

We could also start the method with a (+), which means it will be a class method or function. You can call directly without being allocated, either instantiated.
So when we write the call...

  1. //Call method
  2. [Friend addFriendWithName:@"Nicolas"];

If we write a method that contains more than one parameter:

  1. //More parameters!
  2. -(void)addFriendWithName:(NSString *)name withEmail:(NSString *)email;

miércoles, 7 de diciembre de 2011

Basic language syntax


Objective-C language can be a strange and uncomfortable digging into this technology. At first it may be awkward syntax, but once used to call methods, statements, and other memory management, things get easier.


Classes


Classes in Objective-C are composed of an interface or protocol (".h" extension), and an implementation (".m" extension)


Protocols


A protocol is a public contract that lists the statements of the methods and properties, in turn the protocol defines which is the parent class that inherits from.


What does this mean? All classes that use the class created will have knowledge of what properties and methods can be used, as well as who inherits the class.


An example:

  1. #import <UIKit/UIKit.h>
  2. @interface iPhoneTestViewController: UIViewController <UITableViewDelegate,
  3. UITableViewDataSource>
  4. {  
  5. }

In the top line as we can see the interface iPhoneTestViewController inherits from UIViewController.
Later I will explain in detail the utility of each Controller in Cocoa.


You can also see that in "<>" possibility of adding delegates that will
observe the events dispatched by the controller.
You can also import other interfaces of other classes to be used in it,
in this case we are importing UIKit, library required for all iPhone applications.

Implementations



Just as we saw that there are protocols that define how you will involve the class, these are
accompanied by a file that defines the implementation of it (. m).
This can be used to develop the behavior of the methods, overwrite
methods of the parent class and implement the event behavior of some
delegate. An example might be

  1. #import "iPhoneTestViewController.h"      //This is the header   
  2. @implementation iPhoneTestViewController
  3. //Class constructor
  4. - (id)init {    
  5.     [super init];
  6.     return self;
  7. }


This is a simple example of a class implementation, where the protocol is imported and we have an init method. The init method is used as a constructor of a class to instantiate,
for now I will not go into detail on class constructors or overloads.