Using data semphores in iOS (Synchronous Request)

Introduction

As per Apple Documentation,

A dispatch semaphore is an efficient implementation of a traditional counting semaphore. Dispatch semaphores call down to the kernel only when the calling thread needs to be blocked. If the calling semaphore does not need to block, no kernel call is made.

Continue reading “Using data semphores in iOS (Synchronous Request)”

Swift – Optionals

Introduction

With the introduction to a new programming language known as SWIFT in the past year by the biggest technical giants Apple Inc, most dominant player in the mobile market, a new stage was set for developers to come up with more. I will agree that Swift is an easier platform to learn for all the developers though specially who are new to iOS development platform but shifting from Obj-C is not easy particularly not using the (*) pointer notation [Just kidding..].

Even if you are new to iOS there are lot of concepts that are not so friendly to understand and pretty much creates a confusion while learning and using the language basics.

One of most limbo concept is Optionals. It took me really good time to understand what it is all about specially when I was coming from the Obj-C background.

As it is said, there are 2 sides of the coin. Here to its has pros as well as cons. On the cons, the highly relative term is complexity. Trust me if you do not understand why ? or ! operators are used you will land in dead zone.

Let’s start with the basics.

Continue reading “Swift – Optionals”

Using Blocks in Objective C

Introduction

When programmers and developers from the other high level languages such as Java and other similar ones shifts to Objective C, Blocks is one of the most confusing concept. But trust me its the most important concept in Objective C which is extensively used in Objective C style programming. Moreover once you know the basics its becomes really easy to use it. Continue reading “Using Blocks in Objective C”

Using NSUserDefaults in iOS

Hi All,

I know that most of the people reading the post are familiar with the concept of NSUserDefaults.

Just to summarize, NSUserDefaults is a programmatic interface to interact with the user system. It allows the application to store and access the data that is specific to the user.  So lets just quickly see how to access and store the data specific to the user in the iOS application context.

Continue reading “Using NSUserDefaults in iOS”

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 🙂

Overscroll Problem Phonegap iOS Jquery Mobile

Hi All,

I was working over the project and came across a problem while using the jquerymobile and phonegap for a Hybrid Application.
Whenever the keyboard/picker is displayed on the screen there was a problem of the scroll which made my app look pathetic. So tried to find out the solution which can work over the other platforms also without changing the native code.

By default, the iOS webview have a elastic configuration which means if you drag the screen down, the whole content in the application seems to scroll.
Using phonegap you can either use a plugin like iScroll to overcome the problem or make changes to the custom code to make this work. This goes good for the iOS but what about the other platforms. When we are targeting a Hybrid App it means that the application tends work appropriately on every platform without much of the changes to the native code.

I tried to find out the solution to the problem and ended up finally getting some info from the PHONEGAP site.
I changed the configuration settings of the Phonegap specified in the config.xml which controls the in and out of the application. This can be done by changing the KEYBOARDSHRINKSVIEW property to TRUE.

Config.xml

But using this property has a drawback. Huh! I was stuck again into the problem. This setting goes true for all the screens in the application due to which when my content size tends to increase and keyboard/picker is displayed, my content tends to be hidden below it and i was not able to view it at all.

I started over all again and then came across a solution that helped me solve the problem i was facing.
I used the javascript and some css to make this work. Here is how i did it.

Put this piece of code into the application deviceready function so that it binds the event to every page in the application.


document.body.addEventListener('touchmove',function(e){
if(!$(e.target).hasClass("scrollable")) {
e.preventDefault();
}
else
{
console.log("Scroll");
}
});

Here is the CSS Code that i used:

.scrollable {
overflow: auto;
overflow-x: hidden;
-webkit-overflow-scrolling: touch;
border:1px solid;
}
.scrollable * {
-webkit-transform: translate3d(0,0,0);
}

Also provide the scrollable class to the content which is required to be scroll in the application.
For example, if you want your content container to scroll then provide the scrollable class to the root element of the application.