Exchanging data using Delegates in iOS

Introduction

The delegates are quite a powerful concept when it comes to exchanging data in iOs or query some other class without knowing much about it. This post will cover the process to create a simple delegate and how to make it work to exchange data between different view controllers.

Delegation Pattern:

As per wikipedia, The delegation pattern is a design pattern in object-oriented programming where an object, instead of performing one of its stated tasks, delegates that task to an associated helper object.

Somehow it also allows us to implement the concept of Multiple Inheritance in iOS by allowing helper class to perform operations on behalf of the base class.

Summary

The post consists of an example which consists of the following files:

CMGViewController: Base Controller which come to the view when the user loads the application. It implements the CMGViewControllerDelegate to perform an operation on behalf of CMGSecondViewController.

CMGSecondViewController: This is a view controller which asks for the user input. Once the user input the data to control and submits it, the data is displayed on the control is send back to the CMGViewController along with the input added by the user.

Download the full source of the example from here: DOWNLOAD SOURCE

Lets begin with the more interesting stuff and understand how the delegation pattern works.

Code

Step 1: Open Xcode and create a new project with Single View Application selected.

Step 2: Add a view controller to the application.

Step 3: Open the .h file for the controller


@protocol CMGSecondViewControllerDelegate <NSObject>

-(void) submitButtonActionPerformed:(NSString *) stringValue;

@end

#import <UIKit/UIKit.h>

@interface CMGSecondViewController : UIViewController
@property (strong,nonatomic) id<CMGSecondViewControllerDelegate> delegate;
@property (strong,nonatomic) IBOutlet UITextField *departmentTextField;
@property (strong,nonatomic) IBOutlet UIButton *submitButton;

-(IBAction)submitButtonPressed:(id)sender;

What we have here?

We have created a new protocol for the application with the specified name which our main view controller will implement to perform operations on behalf of our second view controller. We have declared a method here which returns nothing but takes a NSString as an argument.


@protocol CMGSecondViewControllerDelegate <NSObject>

-(void) submitButtonActionPerformed:(NSString *) stringValue;

@end

We have an instance of UITextField and UIButton which allows user to interact with the application. The user types in the data to the textfield and submits it. The data is accordingly displayed on instance of UILabel in main view controller.

Now we have to declare a property here with the type as the delegate name.


@property (strong,nonatomic) id<CMGSecondViewControllerDelegate> delegate;

Remember you have to connect your controls to the Storyboard View. I leave the connection stuff to you as I pre assume that you will be able to do that easily.

Step 4: Switch to your .m file for the controller and add the following code to it.


@synthesize departmentTextField;
@synthesize submitButton;

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}

- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
}

- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}

// Submit Button Action Performed
-(void) submitButtonPressed:(id)sender
{
NSString *textFieldValue = [self.departmentTextField text];
[self dismissViewControllerAnimated:YES completion:^{
[self.delegate submitButtonActionPerformed:textFieldValue];
}];
}

Above code consists of an action method that is performed when the user hits the button on the controller view. It dismisses the current dialog and passes the value to the first view controller to display in the label instance. We have to make a call to submitButtonActionPerformed: method on the delegate instance to call the implementation in the main controller file. This code is added in the completion block of the dismissViewControllerAnimated: method.

Step 5: Now switch to your main controller .h file and add the following code for your delegate pattern to work correctly.


#import "CMGSecondViewController.h"

@interface CMGViewController : UIViewController <CMGSecondViewControllerDelegate>

@property (strong,nonatomic) IBOutlet UILabel *departmentLabel;

Here we add the protocol that we defined in the second view controller file in between the angle brackets so that we can access the methods and provide an implementation of it in the .m file.

Step 6: Add the following code to .m file. This consists of  implementation of protocol methods as we generally do in iOS.


//
//  CMGViewController.m
//  DelegateExample
//
//  Created by CMGabriel on 03/12/13.
//  Copyright (c) 2013 Example. All rights reserved.
//

#import "CMGViewController.h"
#import "CMGSecondViewController.h"

@interface CMGViewController ()

@end

@implementation CMGViewController

@synthesize departmentLabel;

- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}

- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}

-(void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
CMGSecondViewController *secondViewController = (CMGSecondViewController *)segue.destinationViewController;
secondViewController.delegate = self;
}

#pragma mark - CMGSecondViewControllerDelegateMethods
-(void) submitButtonActionPerformed:(NSString *) stringValue
{
self.departmentLabel.text = stringValue;
}

@end

Step 7: Run the application to view the delegates do the working. Whatever you will specify in the textfield in the second view controller will be displayed in the main view controller on hit of a button.

So we are done with the show. In hope you enjoyed it !!!. Keep looking forward to more posts.

iOS Access webservices using NSURLConnection

Introduction

With geometric rate of progression in the mobile technology, almost each application is required to exchange data with the server. This aspect of an application is achieved using web services. Web services act as a middle ware between your server and front end client. This post will help you to access the webservices data using the predefined class in iOS framework i.e. NSURLConnection. This example demonstrates the application to connect with webservices SYNCHRONOUSLY. Will guide you to connecting with webservices using asynchronous connection in a separate post. So Let us begin!!!

PLEASE NOTE: You can download the whole source code from here – DOWNLOAD CODE

We will take a simple example to demonstrate this up.

The example consists of a TableView embedded in a NavigationController. The application connects to a public web service, in this case RottenTomatoes.com and loads the data to the table view as required. You will be required to signup with  website to generate an API Key and run the example code successfully.

Summary:

Main.storyboard – This file is a storyboard file for iOS which consists of a NavigationController with a table view embedded to it.

WSViewController.h – The header implementation file consisting of definitions to run the code successfully.

WSViewController.m – The implementation file consisting of the code to handle the request and accordingly display data to the user.

WSAppDelegate.h & WSAppDelegate.m  – The AppDelegate files for the application to manage the workflow and correct functioning of App.

Code Time:

Step 1: Prepare your application views to handle the code in the implementation file. With the introduction of storyboads in iOS 5 it takes very less effort to maintain the files for the View part of application.

Delete the view controller already created by default by Xcode.

Drag a TableViewController instance to the view and drop it.

Select the instance, go to Editor > Embed In > Navigation Controller. This will embed you current view into a NavigationController and making NavigationController as the InitialViewController.

Step 2: Refactor your code in .h file. Extend your class to UITableViewController and implement UITableViewDataSource, UITableViewDelegate and NSURLConnectionDataDelegate.

@interface WSViewController :
UITableViewController<UITableViewDataSource,UITableViewDelegate,
NSURLConnectionDataDelegate>

Step 3: Switch back to your main storyboard file.

Add the class name to property inspector.

Screen Shot 2013-12-01 at 6.04.30 pm

Step 4: Add the property declarations to the .h file

//Stores the values for the data that is returned from the webservice.
@property (strong,nonatomic) NSMutableData *wsData;
//Stores the values for the final results in an array.
@property (strong,nonatomic) NSMutableArray *results;
@property (strong,nonatomic) NSMutableDictionary *jsonData;

Now, time to add the code for connecting and rendering the data.

Step5: Switch to .m file.

Synthesize the properties declared in .h file.

@synthesize wsData;
@synthesize results;
@synthesize jsonData;

Now add the following code to your viewDidLoad to connect to the URL synchronously and fetch the data.

//Initiate the variables to store data to be used in the application.
self.jsonData = [NSMutableDictionary dictionary];
self.results = [NSMutableArray array];
self.wsData = [[NSMutableData alloc] init];

//Create the URL String using URI and API Key
NSString *uriString = [NSString stringWithFormat:@"%@%@",URI,API_KEY];

//Intial setup to make a call to webservice.
NSURL *url = [NSURL URLWithString:uriString];

//Create a request object to make a request to the URL.
NSURLRequest *request = [NSURLRequest requestWithURL:url];
NSURLResponse *response = nil;
NSError *error = nil;

NSData *data = [NSURLConnection
sendSynchronousRequest:request
returningResponse:&response
error:&error];

if(error == nil)
{
[self.wsData appendData:data];
self.jsonData = (NSMutableDictionary *)[NSJSONSerialization
JSONObjectWithData:(NSMutableData *)self.wsData
options:NSJSONReadingMutableContainers
error:nil];

self.results = [self.jsonData
objectForKey:@"movies"];

}

In the above code, we have created a NSURL instance which consists of a URL that we are required to connect to fetch the data which is to be used as a datasource in our application.

NSURL instance is then wrapped in a NSURLRequest instance to be used for connecting and making a request using the NSURLConnection.

+ sendSynchronousRequest:returningResponse:error is a static method in NSURLConnection class that allows us to connect to the URL and fetch the response accordingly. It returns a NSData object.

To convert the data to JSON format we will be using the NSJSONSerialization class static method. It converts the NSData Object into a NSDictionary. Once done the data is ready to be used in the application.

Step 6: Implement the TableView Delegate and Datasource methods.

#pragma mark TableView Datasource Methods
-(NSInteger) numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}

-(NSInteger) tableView:(UITableView *) tableView numberOfRowsInSection:(NSInteger)section
{
return [self.jsonData count];
}

#pragma mark TableView Delegate Methods

-(UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CELL_IDENTIFIER = @"WEBSERVICETABLECELL";

UITableViewCell *cell = [tableView
dequeueReusableCellWithIdentifier:CELL_IDENTIFIER];

if(cell == nil)
{
cell = [[UITableViewCell alloc]
initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:CELL_IDENTIFIER];
}

//Mainuplate data and set the cell text and image values.

NSDictionary *resultDictionary = [self.results objectAtIndex:indexPath.row];
NSDictionary *posterDictionary = [resultDictionary objectForKey:@"posters"];

cell.textLabel.text = [resultDictionary objectForKey:@"title"];

cell.imageView.image = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:[posterDictionary objectForKey:@"thumbnail"]]]];
return cell;
}

Step 7: Run your code to check out the output. You will be able to see the output as the image provided below

Screen Shot 2013-12-01 at 6.21.10 pm

I hope you enjoyed the post, keep looking forward to more.

Access media/photos/videos using ALAssetsLibrary iOS/Objective-C

Introduction
With the progressive success to media applications in growing social market, the access to Media Library over iOS device is more or less one of the core requirement. This post focuses on using the ALAssetsLibrary to get access to your media on your iOS device.

What is ALAssetsLibrary ?
ALAssetsLibrary is core class added to the framework to get access to the media on your iOS device. This library was introduced in iOS 5 and has an extensive use in the media applications. All the methods, constants and other connecting libraries are listed over Apple Developer documentation.

Code Time!!!
To use the ALAssetsLibrary in your code, you will be required to import the header file into your class.

 #import <AssetsLibrary/AssetsLibrary.h>

Once the header file is added to your code, you will have access to the methods and constants that are predefined in the header file. With the code assistance provided by Xcode, you can check out other methods available that can be useful in different situations.

Now create a ALAssetsLibrary Object into your scope to be used for accessing media of your device.

ALAssetsLibrary *assetLibrary = [[ALAssetsLibrary alloc] init];

First of all to access the library you will be required check whether the user has authorized your app to access the media or not.

if([ALAssetsLibrary authorizationStatus])
{
//Library Access code goes here
}
else{
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Permission Denied" message:@"Please allow the application to access your photo and videos in settings panel of your device" delegate:[PHCPCSyncController getSharedSyncInstance] cancelButtonTitle:@"Ok" otherButtonTitles: nil];
[alertView show];
}

 

The above constant authorizationStatus checks whether the user of application has provided access to the application to access the Assets or not. In case not then it shows up a alert to the end user to enable manually via Settings. One thing to remember there is no way you can change the settings through your app programatically. So this has to be done manually as its upto end user to allow access to Assets for the particular application.

Now if authorizationStatus returns true then you will be able to access the Assets. Lets move ahead and see how to do this stuff.

[assetLibrary enumerateGroupsWithTypes:ALAssetsGroupAll usingBlock:^(ALAssetsGroup *group, BOOL *stop) {
if(group)
{
//Filter photos
photoArray = [self getContentFrom:group withAssetFilter:[ALAssetsFilter allPhotos]];
//Enumerate through the group to get access to the photos.

[contentDictionary setObject:photoArray forKey:@"Photos"];

//Filter videos

videoArray = [self getContentFrom:group withAssetFilter:[ALAssetsFilter allVideos]];
[contentDictionary setObject:videoArray forKey:@"Videos"];

[[NSNotificationCenter defaultCenter] postNotificationName:@"assetread" object:nil];

}
} failureBlock:^(NSError *error) {
NSLog(@"Error Description %@",[error description]);
}];

 

There are groups in AssetsLibrary one is for Photos and other for Videos. The above method enumerateGroupsWithTypes:usingBlock helps to do fast enumeration over the groups that exists in the library.

Now to get access to a specific group, we setup a filter using setFilter:
We can provide the specific filter in the initialization also but here we specified ALAssetsGroupAll to access all the media provided.

Once we have attached the specified filter to group we can access the media in that group. I did that in a separate method to keep the understanding clean.

-(NSMutableArray *) getContentFrom:(ALAssetsGroup *) group withAssetFilter:(ALAssetsFilter *)filter
{
NSMutableArray *contentArray = [NSMutableArray array];
[group setAssetsFilter:filter];

[group enumerateAssetsUsingBlock:^(ALAsset *result, NSUInteger index, BOOL *stop) {

//ALAssetRepresentation holds all the information about the asset being accessed.
if(result)
{

ALAssetRepresentation *representation = [result defaultRepresentation];

//Stores releavant information required from the library
NSMutableDictionary *tempDictionary = [[NSMutableDictionary alloc] init];
//Get the url and timestamp of the images in the ASSET LIBRARY.
NSString *imageUrl = [representation UTI];
NSDictionary *metaDataDictonary = [representation metadata];
NSString *dateString = [result valueForProperty:ALAssetPropertyDate];

// NSLog(@"imageUrl %@",imageUrl);
// NSLog(@"metadictionary: %@",metaDataDictonary);

//Check for the date that is applied to the image
// In case its earlier than the last sync date then skip it. ##TODO##

NSString *imageKey = @"ImageUrl";
NSString *metaKey = @"MetaData";
NSString *dateKey = @"CreatedDate";

[tempDictionary setObject:imageUrl forKey:imageKey];
[tempDictionary setObject:metaDataDictonary forKey:metaKey];
[tempDictionary setObject:dateString forKey:dateKey];

//Add the values to photos array.
[contentArray addObject:tempDictionary];
}
}];
return contentArray;
}

 

This method takes the group and filter as an input, process over media and returns the array consisting of custom data.
ALRepresentation is class used to represent a particular asset. Once we have the representation from the asset, we are allowed to access various attributes of the object. All these can be found in ALAsset Class available in the Apple Developer Documentation. To know more about the options please refer to the documentation.

I hope so you enjoyed the post, look forward to more in near future!!!
Thanks for your time 🙂

Create a Singleton class in objective-C

Overview

Singleton implementation is basically creating a single object for access throughout the application. It works on the global access principle. Singleton pattern is implemented by creating a class method that generates an instance of the class only if the one doesnot exists in the memory.

Just keep a note of that singleton instance should always be created carefully in a Multithreaded environment. So just be sure while creating a class that its method is accessible by one thread at a time otherwise there might be condition raised which can crashes your application during runtime. Moreover these bugs are very hard to find in the environment for iOS development.

Like other languages, we can create a singleton class in Objective-C which is pretty much required when you want to share the resources among different classes in the application.

The biggest example of the Singleton is APPDELEGATE of an iOS app which is shared globally across the application.

How to implement ?

Create a class. It might extend NSObject or any other class which can particularly provide the additional methods required as per your implementation.

 #import <foundation/Foundation.h>

@interface MyManager : NSObject {

NSString *someProperty;

}

@property (nonatomic, retain) NSString *someProperty;

+ (id)sharedManager;

@end

You create an a static method that return <id> back to the caller. <id> is the default datatype for all the objects in Objective C.

Now switch to your implementation file.

The Singleton can be implemented using a couple of ways.

One is the use of the GCD to create one and other is using the normal Objective-C syntax.

Using GCD:

#import "MyManager.h"

@implementation MyManager

@synthesize someProperty;

#pragma mark Singleton Methods

+ (id)sharedManager { static MyManager *sharedMyManager = nil;

static dispatch_once_t onceToken;

dispatch_once(&onceToken, ^{

sharedMyManager = [[self alloc] init];

});

return sharedMyManager;

}

- (id)init {

if (self = [super init]) {

someProperty = [[NSString alloc] initWithString:@"Default Property Value"];

}

return self;

}

@end

Using Objective C Syntax:

+ (id)sharedManager {
static MyManager *sharedMyManager = nil;
@synchronized(self) {
if (sharedMyManager == nil)
sharedMyManager = [[self alloc] init];
}
return sharedMyManager;
}

Here the @synchronized is used to allow the code to be accessed by a single thread only. Else you can create a property with the atomic attribute to make it Thread Safe.

How to access the instance ?

You can access the static components using the class name.

MyManager *sharedInstance = [MyManager sharedManager];
Posted in iOS

Sencha Touch 2 – Create a new application using terminal

This post allows you to understand that how to create your first application for the sencha touch 2.

Here are the steps that allows you to create a new application using the terminal/command line:

Pr-requisites:

  • Sencha touch 2 downloaded.
  • Sencha Cmd installed.
  • MAMP already installed on the system.

Steps:

  1. Navigate to the directory where you have extracted the contents of the package downloaded from the website. In case you are in a wrong directory and you try to create a new application, the script will be at halt and will show an error.
  2. Once navigated, type the following
    sencha -sdk /path/to/sencha-touch-sdk generate app MyApp /path/to/www/myapp
  3. On the completion of the script, the location specified in the above command will have the content as follows:

.sencha/                # Sencha-specific files (for example configuration)
    app/                # Application-specific content
        sencha.cfg      # Configuration file for Sencha Cmd
        plugin.xml      # Plugin for Sencha Cmd
    workspace/          # Workspace-specific content (see below)
        sencha.cfg      # Configuration file for Sencha Cmd
        plugin.xml      # Plugin for Sencha Cmd</code></strong></pre>
touch/ # A copy of the Sencha Touch SDK
 cmd/ # Sencha Touch-specific content for Sencha Cmd
 sencha.cfg # Configuration file for Sencha Cmd
 plugin.xml # Plugin for Sencha Cmd
 src/ # The Sench Touch source
 sencha-touch-*.js # Pre-compiled and bootstrap files
 ...

app # Your application's source code in MVC structure
 controller
 model
 profile
 store
 view
 Main.js # The main view of the application

resources
 css
 app.css # The main stylesheet, compiled from app.scss

sass
 app.scss # The Sass file which compiles to app.css above,
 # includes Sencha Touch theme by default

icons # Application icons for all mobile devices
 # When replacing these default images with your own,
 # make sure the file name and the dimension stays exactly the same
 ...
 loading # Application start-up screens for iOS devices
 # Similarly to icons, make sure the file names and
 # dimension stays the same
 ...
 images # Put other images used by your application here

index.html
 app.js # Contains application's initialization logics
 app.json # Configuration for deployment
 packager.json # Configuration for native packaging

Getting started with Sencha Touch 2 on your MAC

As the fresh developers to the sencha touch development, one of the challenges is to configure sencha touch 2 on the machine. This is a small post the defines the steps to install and configure the Sencha Touch 2 on the system.

Please Note: This installation steps are specifically for the Mac Machines.

Pr-requisites: You will require a local server to run the applications built on the Sencha Touch Platform such as MAMP.

1. Download the Sencha touch package from the website. Click Here to download the package.

2. Unzip the package and extract the contents to a destination.

3. Download the Sencha Command Tool from the sencha touch website. Click here to download the installation setup.

4. Run the installation file that is downloaded from the website.

5. To check whether the Sencha Command is installed properly or not, Open Terminal and type “sencha” to it. The output similar to the one specified in the image below will be displayed to you in case the installation is done successfully.

Sencha Cmd

Sencha Command helps you to compile, run and create the applications using the command line.

The installation and configuration of the sencha on the machine is done successfully.

You can use any type of editor to manage the files for the sencha touch application. The recommended are Sencha Touch 2 Architect, Aptana Studio, Xcode, Dashcode.

To view how to create an application using the sencha cmd please look into the next post of the series.

Introduce HMVC into Codeigniter Application

As the market for the reusable components increases, the use of the HMVC(Hierarichal Model View Controller) has pushed up the stacks geometrically with the frameworks.

By default, the Codeigniter framework follows the Model-View-Controller approach. The ease of use and lightning speed of the framework has gained the framework a lot of importance in comparison to other frameworks such as Zend, CakePhp etc. The frameworks enable to users to use the core features of the language with the extended features that are available in the framework to ease the road to development.

One of the feature which the framework lacks is the reuse of the components to extensive level. You can create custom components in the MVC based codeigniter but the re-usability is available to a limited extent.
HMVC extensions enables the developers to extend and reuse the functionality to an extensive level with minimal modification to the underlying code. Use of the HMVC provides the following benefits to the developers:

  • Modularization: Reduction of dependencies between the disparate parts of the application.
  • Organization: Having a folder for each of the relevant triads makes for a lighter work load.
  • Reusability: By nature of the design it is easy to reuse nearly every piece of code.
  • Extendibility: Makes the application more extensible without sacrificing ease of maintenance.

This enables the developers to maintain the code to a better level with more focus on the business logic of the application.

This post will help you to successfully configure codeiginiter with the HMVC extensions.

Steps:

CodeIgniter WebSite

  • Once downloaded, extract the content to htdocs/www folder of the local server. For eg. for MAMP: Goto Application->MAMP->htdocs. Your folder should be similar to the one displayed in the image below:

Screen Shot 2013-09-03 at 7.57.44 PM

  • Now download the HMVC extensions for the following location: HMVC Extensions
  • Extract the content of the compressed file. The contents of the folder will be similar to the one displayed below:

Screen Shot 2013-09-03 at 7.55.42 PM

  • In your CI installation add a folder named modules to it. Your CI application folder will look similar to this. The configuration of the Codeigniter on the local server is not specified in this post, It is assumed that you know how to configure the other properties in the CI config directory. You can also use some other name for your modules folder if you wish to, but in such a case you will be required to specify the path to folder in the config file. This can be done in a following way:

$config['modules_locations'] = array(APPPATH.'modules/' => '../modules/');

Screen Shot 2013-09-03 at 7.59.36 PM

  • Now copy the “core” and “third party” folder from your HMVC extension folder and copy it to the applications folder.
  • Your installation is ready to use the HMVC architecture.
  • Now create the module with a specified name, In this case the name of the module is core_main.
  • Create the folder for controllers,models and views respectively into the core_main folder. In HMVC, each module has their own respective controller,model and view folders.
  • Please note the name of the module should match the controller name else in such a case if you are using the routing feature in codeigniter then you have to specify the folder name along with the name of the controller.

Screen Shot 2013-09-03 at 8.03.02 PM

  • Defining a Controller – Normally we extend the CI_Controller class to extend the functionality of our classes but when using HMVC we will extend our controller class with MX_Controller. So now we define the controller in the following way:


class Core_main extends MX_Controller

Your system is now ready to use the HMVC extension.