Sunday, June 2, 2013

Target - Action in action - software design pattern in Cocoa - basics



Design Patterns 

"A design pattern is a tool of abstraction used in object-oriented software development as well as other fields. It is a template for a design that solves a general, recurring problem in a particular context. A design pattern is thus a kind of guide for a particular, concrete design: an “instantiation” of a pattern, in a sense. There is some flexibility in how you can apply a design pattern, and often things such as the programming language and existing architectures can determine how the pattern is applied. " - Getting Started by Apple Dev. Portal

So, design pattter is a clever way, how to do things... Software Design Patterns are templates that descirbes how we should design and implement parts of our functionality to:
  • avoid errors 
  • keep it simple
  • speed up development
  • build easy to maintain aplication

It is good to know design patterns and in Cocoa Framework few Design patterns are "must know & understant". 


Popular Design Patterns in iOS:
  • Action-Target
  • Model-View-Controller (MVC)
  • Delegate
  • Key-Value Observer (KVO)

There are more design patterns of them that  used by Cocoa but i won't mention them now. 



Target - Action

Target - Action was implemented in Cocoa Touch to make things simpler. 
But what it exactly stands for? 
Target - Action  is a concept of communication between objects. 
Action represents function we want to call and target represents the object with will be invoked by this function. There is also sender, which is very important as it initiates call. All information necessary for function should be in sender context as we cannot pass arguments, what i will explain later. 

Why we need another method for calling a function? This method allows us to define logic before action will need took place and it is very handy way for doing so. 
Best example, and also the main function of this pattern is to provide tools for user interaction  like pressing a button, tapping view or swiping for sliding a screen. 

Target-Action is strongly supported by XCode editor and it makes it strong and agile.

Lets look on example: 
We only need to add element  (like UIButton)  into editor (XIB - interface file ) and drag + control element into .h file using assistant view to generate sender instance (while connection  = "outlet"  is selected in small popup window - assistant). Doing same thing and control+dragging from UI-element to target (file) you can change connection to "Action" and define properties for it.  



 XCode will require you to select event who will initiate Target-Action call. For pressing button this is usually "Touch Up Inside" but feel free to explore other events. 


As you will open "Arguments" list you will see that there are only 3 ways of defining Target-Action call. We can pass no arguments to action, we can inform target about sender and eventually we can also pass the event which invoked sender for calling action. 

Simplest function interface look like this:

- (IBAction)action; 

"action" is a function name i have typed in editor. IBAction is a ObjC return type for those type of functions, but you can think of it same as (void). 


- (IBAction)action:(id)sender;
- (IBAction)action:(id)sender forEvent:(UIEvent *)event;

Here we have two more possible overloads - one with sender and second one with sender and event.  You can inspect active connections from XIB to your classes on outlet view in XCode. Here we can see that under "Received Actions" we have defined call on "Touch up Inside" event witch will invoke action:forEvent: method. 

Why we need sender and event? There are no more overloads so it is handy to keep all required informations in sender context. Imagine that you are adding Picker View to your application. You want to associate Target-Action call to inform your application on decision user had made, but you cannot pass argument to function. So how to know what was the decision. In this case Picker View will be sender, and it will hold information about user decision.

Ok... XCode strongly supports Target-Action and this allows as to define user interactions in no-time. 
We can also define same connections from Objective-C code. 
If we have button adding Target-Action will look like this:

UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[button addTarget:self 
           action:@selector(aMethod:)
 forControlEvents:UIControlEventTouchDown];
... // decorating button
[view addSubview:button];

addTarget:action:forControlEvents: - is a method defined in UIControl so it is inherited  by all UIelements. In this example button will be sender, and aMethod will be called on self.

So this is how Target-Action is used in Cocoa Touch. If you find this article useful or it missing something - let me know. 

No comments:

Post a Comment