Sqlite Database

Hello Everyone,

This tutorial is about saving and retrieving and deleting data from Sqlite Database in an iOS application.

To get this done we need the following steps to be followed:

1. We need to crate a database file from Sqlite manager add-on in Mozilla Firefox.

Screen Shot 2014-10-07 at 4.41.25 PM

Screen Shot 2014-10-07 at 4.57.36 PM

2. After creating the Database we need to create an Sqlite file from Sqlite manager add-on in Mozilla Firefox.

3. After creating the Sqlite file, we need to create a table and add the columns we need to perform these operations that we intent to do.

4. After that we need to drag and drop the Sqlite file in to our x-code project.

5. After that add libsqlite3.dylib and libsqlite3.0.dylib to the x-code project

6. When coming to the coding part we need a NSObject Class where we create methods to perform these operations and then call these methods in appropriate classes that we need. Name the class SqlDatabase .h and .m respectively.

Now Let us see the coding part that performs these operations.

Our SqlDatabase.h file looks like this

import <Foundation/Foundation.h>
#import <sqlite3.h>

@interface SqlDatabase : NSObject

{

}

+(NSInteger)insertData:(NSMutableArray *)dataArr;
+(NSMutableArray *)getData;
+(void)tablerowsDelete:(NSString *)name;

@end

In SqlDatabase.m we need to implement the code for saving and retrieving data

Our SqlDatabase.m file looks like this

#import “SqlDatabase.h”

sqlite3 *dataBase=nil;
NSString *dbPath=nil;

@implementation SqlDatabase

//  checking if the sqlite file exists in the Document directory and creating it if not created already.   //
+(NSString *)getDataBasePath
{
NSArray *docDir = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *DBfolder = [NSString stringWithFormat:@”%@/AllDataBases”,[docDir objectAtIndex:0]];
NSFileManager *fileManager = [NSFileManager defaultManager];
if (![fileManager fileExistsAtPath:DBfolder]) {
[fileManager createDirectoryAtPath:DBfolder withIntermediateDirectories:YES attributes:nil error:nil];
}
dbPath = [DBfolder stringByAppendingPathComponent:@”/Database.sqlite”];
if (![fileManager fileExistsAtPath:dbPath]) {
[fileManager copyItemAtPath:[[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@”Database.sqlite”]  toPath:dbPath error:nil];
}
return dbPath;
}

// Inserting Data into Sqlite Database  //
+(NSInteger)insertData:(NSMutableArray *)dataArr
{

dbPath=[self getDataBasePath];

if (sqlite3_open([dbPath UTF8String], &dataBase) == SQLITE_OK)
{
sqlite3_stmt *statement=nil;

NSString *name = [dataArr objectAtIndex:0] ;
NSString *sex = [dataArr objectAtIndex:1];
NSString *age = [dataArr objectAtIndex:2];
NSString *nationality = [dataArr objectAtIndex:3];
NSString *phone = [dataArr objectAtIndex:4];
NSString *occupation = [dataArr objectAtIndex:5];

if(statement == nil)
{
const char *sql = “INSERT INTO myDetailTable(Name,Sex,Age,Nationality,Phone,Occupation) VALUES(?,?,?,?,?,?)”;

if(sqlite3_prepare_v2(dataBase, sql, -1, &statement, NULL) != SQLITE_OK)
{
NSUInteger i=sqlite3_last_insert_rowid(dataBase);
sqlite3_close(dataBase);
return i;
}

sqlite3_bind_text(statement, 1,name==nil?””:[name UTF8String], -1, SQLITE_TRANSIENT);
sqlite3_bind_text(statement, 2,sex==nil?””:[sex UTF8String], -1, SQLITE_TRANSIENT);
sqlite3_bind_text(statement, 3,age==nil?””:[age UTF8String], -1, SQLITE_TRANSIENT);
sqlite3_bind_text(statement, 4,nationality==nil?””:[nationality UTF8String], -1, SQLITE_TRANSIENT);
sqlite3_bind_text(statement, 5,phone==nil?””:[phone UTF8String], -1, SQLITE_TRANSIENT);
sqlite3_bind_text(statement, 6,occupation==nil?””:[occupation UTF8String], -1, SQLITE_TRANSIENT);

int k=sqlite3_step(statement);
if(SQLITE_DONE !=k )
{
//NSAssert(0, @”Error while inserting data.);

return -1;
}
sqlite3_finalize(statement);
}
}
NSUInteger i=sqlite3_last_insert_rowid(dataBase);
sqlite3_close(dataBase);
return i;
}

// Retrieving data from Sqlite Database //
+(NSMutableArray *)getData;
{
NSMutableArray *temp = [[NSMutableArray alloc] init];
dbPath=[self getDataBasePath];
NSMutableDictionary *item;

if (sqlite3_open([dbPath UTF8String], &dataBase) == SQLITE_OK)
{
NSString *qs=@”select * from myDetailTable”;
const char *sql=[qs UTF8String];
sqlite3_stmt *selectstmt;
if(sqlite3_prepare_v2(dataBase, sql, -1, &selectstmt, NULL) == SQLITE_OK)
{
while(sqlite3_step(selectstmt) == SQLITE_ROW)
{
item=[[NSMutableDictionary alloc] init];

[item setObject:[NSString stringWithUTF8String: (char *)sqlite3_column_text(selectstmt, 0)] forKey:@”name”];
[item setObject:[NSString stringWithUTF8String: (char *)sqlite3_column_text(selectstmt, 1)] forKey:@”sex”];
[item setObject:[NSString stringWithUTF8String: (char *)sqlite3_column_text(selectstmt, 2)] forKey:@”age”];
[item setObject:[NSString stringWithUTF8String:(char *)sqlite3_column_text(selectstmt, 3)] forKey:@”nationality”];
[item setObject:[NSString stringWithUTF8String:(char*)sqlite3_column_text(selectstmt, 4)] forKey:@”phone”];
[item setObject:[NSString stringWithUTF8String:(char*)sqlite3_column_text(selectstmt, 5)] forKey:@”occupation”];

}
[temp addObject:item];

sqlite3_finalize(selectstmt);
}
}
sqlite3_close(dataBase);
return temp;
}

// Deleting Table rows from Table in Sqlite Database //
+(void)tablerowsDelete:(NSString *)name
{

NSString *dbPath3=[self getDataBasePath];

if (sqlite3_open([dbPath3 UTF8String], &dataBase) == SQLITE_OK)
{

NSString *qs=[NSString stringWithFormat:@”Delete from myDetailTable where Fullname like ‘%@'”,name];
const char *sql=[qs UTF8String];
sqlite3_stmt *selectstmt;

if (sqlite3_prepare_v2(dataBase, sql, -1, &selectstmt, nil) != SQLITE_OK)
{
/**this one will execute when there is error in your query**/

}
else
{
/************just add this one****************/
sqlite3_step(selectstmt);
}

sqlite3_finalize(selectstmt);
}

sqlite3_close(dataBase);

}

Now in the ViewController.m we need to import the NSObject class.

Then Our ViewController.m looks like

#import “ViewController.h”
#import “SqlDatabase.h”      // importing the SqlDatabase Class

@interface ViewController ()
{
NSMutableArray *insertArray;   // array for inserting the data into Sqlite database

NSMutableArray *fetchingArray;  // array for retrieving the data from Sqlite database

}

@end

@implementation ViewController

– (void)viewDidLoad

{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
fetchingArray=[[NSMutableArray alloc]init];
insertArray=[[NSMutableArray alloc]initWithObjects:@”KiranKumar”,@”Male”,@”26″,@”Indian”,@”08569884750″,@”Engineer”, nil];

// This line indicates the calling of inseting data method in SqlDatabase class which performs the insertion of data into Sqlite Database File

[SqlDatabase insertData:insertArray];
// This line indicates the calling of retrieving data method in SqlDatabase class which performs the retrieving of data from Sqlite Database File

fetchingArray= [SqlDatabase getData];

// This line indicates the calling of deleting data method in SqlDatabase class which performs the deleting of data from Sqlite Database File
//  [SqlDatabase tablerowsDelete:@”Name”];

}

Crash Report iOS

In this tutorial we will learn how to get crash report through code.

While developing an app we will send updates to testing team for testing, suppose the app crashed they will get reason for crash using tools. Here our code will also show the exact reason why app is crashed in the next run(useful for manual tester as well as developer and client).

Create an NSObject class (CrashController)

Write below code in .h file

#define Iscrashed @"isCrashKey";
#define crashReport
#import <Foundation/Foundation.h>
extern NSString *CrashReportKey;
@interface CrashController : NSObject 
+ (CrashController*)sharedInstance;
- (NSArray*)callstackAsArray;
- (void)handleSignal:(NSDictionary*)userInfo;
- (void)handleNSException:(NSDictionary*)userInfo;
+ (NSMutableDictionary *)getCrashReportFromLibrary;
@end

Write below code in .m file

#import "CrashController.h"
#include <signal.h>
#include <execinfo.h>
NSString *CrashReportKey =@"CrashReportKey";
static CrashController *sharedInstance = nil;
#pragma mark C Functions 
void sighandler(int signal)
{
  const char* names[NSIG];
  names[SIGABRT] = "SIGABRT";
  names[SIGBUS] = "SIGBUS";
  names[SIGFPE] = "SIGFPE";
  names[SIGILL] = "SIGILL";
  names[SIGPIPE] = "SIGPIPE";
  names[SIGSEGV] = "SIGSEGV";
  CrashController *crash = [CrashController sharedInstance];
  NSArray *arr = [crash callstackAsArray];
  NSString *title = [NSString stringWithFormat:@"Crash: %@", [arr objectAtIndex:6]];  // The 6th frame is where the crash happens
  NSDictionary *userInfo = [NSDictionary dictionaryWithObjectsAndKeys:arr, @"Callstack",title, @"Title",[NSNumber numberWithInt:signal], @"Signal",[NSString stringWithUTF8String:names[signal]], @"Signal Name",nil];
  [crash performSelectorOnMainThread:@selector(handleSignal:) withObject:userInfo waitUntilDone:YES];
}
void uncaughtExceptionHandler(NSException *exception)
{
  CrashController *crash = [CrashController sharedInstance];
  NSArray *arr = [crash callstackAsArray];
  NSString *title = [NSString stringWithFormat:@"Exception: %@", [arr objectAtIndex:8]];  // The 8th frame is where the exception is thrown
  NSDictionary *userInfo = [NSDictionary dictionaryWithObjectsAndKeys:arr, @"Callstack",title, @"Title",exception, @"Exception",nil];
  [crash performSelectorOnMainThread:@selector(handleNSException:) withObject:userInfo waitUntilDone:YES];
}
@interface CrashController()
@end
@implementation CrashController
#pragma mark Singleton methods
+ (CrashController*)sharedInstance
{
  @synchronized(self)
  {
    if (sharedInstance == nil)
      sharedInstance = [[CrashController alloc] init];
  }
  return sharedInstance;
}
+ (id)allocWithZone:(NSZone *)zone
{
  @synchronized(self)
  {
    if (sharedInstance == nil)
    {
      sharedInstance = [super allocWithZone:zone];
      return sharedInstance;
    }
  }
  return nil;
}
- (id)copyWithZone:(NSZone *)zone
{
  return self;
}
#pragma mark Lifetime methods
- (id)init
{
  if ((self = [super init]))
  {
    signal(SIGABRT, sighandler);
    signal(SIGBUS, sighandler);
    signal(SIGFPE, sighandler);
    signal(SIGILL, sighandler);
    signal(SIGPIPE, sighandler);    
    signal(SIGSEGV, sighandler);
    NSSetUncaughtExceptionHandler(&uncaughtExceptionHandler);
  }
  return self;
}
- (void)dealloc
{
  signal(SIGABRT, SIG_DFL);
  signal(SIGBUS, SIG_DFL);
  signal(SIGFPE, SIG_DFL);
  signal(SIGILL, SIG_DFL);
  signal(SIGPIPE, SIG_DFL);
  signal(SIGSEGV, SIG_DFL);
  NSSetUncaughtExceptionHandler(NULL);
}
#pragma mark methods
- (NSArray*)callstackAsArray
{
  void* callstack[128];
  const int numFrames = backtrace(callstack, 128);
  char **symbols = backtrace_symbols(callstack, numFrames);
  NSMutableArray *arr = [NSMutableArray arrayWithCapacity:numFrames];
  for (int i = 0; i < numFrames; ++i) 
  {
    [arr addObject:[NSString stringWithUTF8String:symbols[i]]];
  }
  free(symbols);
  return arr;
}
- (void)handleSignal:(NSDictionary*)userInfo
{
  NSUserDefaults *crashDefault=[NSUserDefaults standardUserDefaults];
  [crashDefault setObject:@"1" forKey:@"CrashIs"];
  [crashDefault setObject:userInfo forKey:@"CrashSig"];
  [crashDefault synchronize];
}
- (void)handleNSException:(NSDictionary*)userInfo
{ 
 if ([userInfo objectForKey:@"Exception"]) {
  NSUserDefaults *crashDefault=[NSUserDefaults standardUserDefaults];
  [crashDefault setObject:[NSString stringWithFormat:@"%@",[userInfo objectForKey:@"Exception"]] forKey:@"CrashException"];
  [crashDefault setObject:@"1" forKey:@"CrashIs"];
  [crashDefault synchronize];
  }
}
+ (NSMutableDictionary *)getCrashReportFromLibrary
{
  NSUserDefaults *crashDefault=[NSUserDefaults standardUserDefaults];    if ([[crashDefault objectForKey:@"CrashIs"] length]>0 ) 
{
    NSMutableDictionary *tempDict =[NSMutableDictionary new];
   [tempDict setObject:[crashDefault objectForKey:@"CrashException"] forKey:@"CrashException"];
  [tempDict setObject:[crashDefault objectForKey:@"CrashSig"] forKey:@"CrashSig"];
  NSMutableDictionary *crashDict =[NSMutableDictionary new];
  [crashDict setObject:tempDict forKey:CrashReportKey];
  [crashDefault setObject:@"" forKey:@"CrashIs"];
  [crashDefault setObject:@"" forKey:@"Crash"];
  [crashDefault synchronize];
  return crashDict;
  }
 return nil;
}
@end

Now to get crash report when app crashes open your AppDelegate .m file and import CrashController.h and in “didFinishLaunchingWithOptions” method write below code

 [CrashController sharedInstance]; // create instance here
 NSMutableDictionary *errorReport =[CrashController getCrashReportFromLibrary];
    if (errorReport)
    {
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Crash" message:[NSString stringWithFormat:@"%@",[errorReport objectForKey:CrashReportKey]] delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];        [alert show];
    }
Hope this will help..
Charan Giri

UIImage: Image enhancements

In this tutorial we are discussing about enhancements.

While we upload an image to server it doesn’t matter what is size of image but sometimes it matters pixel rate of image, here we need to reduce the pixel rate.
When we save an image as an profile pic in the app we need image @100*100 size, we will resize the image.
Changing the images colors, reducing brightness of images….

Below are few useful methods

Create an NSObject class ex:(ImageEnhanceMents)
In ImageEnhanceMents.h  file
+(UIImage *)scaleAndRotateImage:(UIImage *)image size:(int)maxSize;
+(UIImage *)scaleImage:(UIImage *)image toSize:(CGSize)targetSize;
+ (UIImage *)croppIngimageByImageName:(UIImage *)imageToCrop toRect:(CGRect)rect forImageViewRect:(CGSize)imageVwRect;
+(UIImage *)resizeImage:(UIImage*)image newSize:(CGSize)newSize;
+ (UIImage *)getBlackAndWhiteForImage:(UIImage *)someImage;
+(UIImage *)grayishImageFor:(UIImage *)inputImage ;
+(UIImage *)lightenTheImage:(UIImage *)img withBrightness:(float)intensity;
+(UIImage *)rotateImage:(UIImage *)image byDegrees:(CGFloat)degrees;
In ImageEnhanceMents.m  file
+(UIImage *)resizeImage:(UIImage*)image newSize:(CGSize)newSize
{
 CGRect newRect = CGRectIntegral(CGRectMake(0, 0, newSize.width, newSize.height));
 CGImageRef imageRef = image.CGImage;
 UIGraphicsBeginImageContextWithOptions(newSize, NO, 0);
 CGContextRef context = UIGraphicsGetCurrentContext();
 // Set the quality level to use when rescaling
 CGContextSetInterpolationQuality(context, kCGInterpolationHigh);
 CGAffineTransform flipVertical = CGAffineTransformMake(1, 0, 0, -1, 0, newSize.height);
 
 CGContextConcatCTM(context, flipVertical);
 // Draw into the context; this scales the image
 CGContextDrawImage(context, newRect, imageRef);
 
 // Get the resized image from the context and a UIImage
 CGImageRef newImageRef = CGBitmapContextCreateImage(context);
 UIImage *newImage = [UIImage imageWithCGImage:newImageRef];
 CGImageRelease(newImageRef);
 UIGraphicsEndImageContext();
 return newImage;
}
+(UIImage *)scaleAndRotateImage:(UIImage *)image size:(int)maxSize {
 // int kMaxResolution = 640; // Or whatever
 int kMaxResolution = maxSize; // Or whatever
 CGImageRef imgRef = image.CGImage;
 CGFloat width = CGImageGetWidth(imgRef);
 CGFloat height = CGImageGetHeight(imgRef);
 CGAffineTransform transform = CGAffineTransformIdentity;
 CGRect bounds = CGRectMake(0, 0, width, height);
 if (width > kMaxResolution || height > kMaxResolution) {
 CGFloat ratio = width/height;
 if (ratio > 1) {
 bounds.size.width = kMaxResolution;
 bounds.size.height = roundf(bounds.size.width / ratio);
 }
 else {
 bounds.size.height = kMaxResolution;
 bounds.size.width = roundf(bounds.size.height * ratio);
 }
 }
 CGFloat scaleRatio = bounds.size.width / width;
 CGSize imageSize = CGSizeMake(CGImageGetWidth(imgRef), CGImageGetHeight(imgRef));
 CGFloat boundHeight;
 UIImageOrientation orient = image.imageOrientation;
 switch(orient) 
 {
 case UIImageOrientationUp: //EXIF = 1
 transform = CGAffineTransformIdentity;
 break;
 
 case UIImageOrientationUpMirrored: //EXIF = 2
 transform = CGAffineTransformMakeTranslation(imageSize.width, 0.0);
 transform = CGAffineTransformScale(transform, -1.0, 1.0);
 break;
 
 case UIImageOrientationDown: //EXIF = 3
 transform = CGAffineTransformMakeTranslation(imageSize.width, imageSize.height);
 transform = CGAffineTransformRotate(transform, M_PI);
 break;
 
case UIImageOrientationDownMirrored: //EXIF = 4
transform = CGAffineTransformMakeTranslation(0.0, imageSize.height);
transform = CGAffineTransformScale(transform, 1.0, -1.0);
break;
 
 case UIImageOrientationLeftMirrored: //EXIF = 5
 boundHeight = bounds.size.height;
 bounds.size.height = bounds.size.width;
 bounds.size.width = boundHeight;
 transform = CGAffineTransformMakeTranslation(imageSize.height, imageSize.width);
 transform = CGAffineTransformScale(transform, -1.0, 1.0);
 transform = CGAffineTransformRotate(transform, 3.0 * M_PI / 2.0);
 break;
 
 case UIImageOrientationLeft: //EXIF = 6
 boundHeight = bounds.size.height;
 bounds.size.height = bounds.size.width;
 bounds.size.width = boundHeight;
 transform = CGAffineTransformMakeTranslation(0.0, imageSize.width);
 transform = CGAffineTransformRotate(transform, 3.0 * M_PI / 2.0);
 break;
 
 case UIImageOrientationRightMirrored: //EXIF = 7
 boundHeight = bounds.size.height;
 bounds.size.height = bounds.size.width;
 bounds.size.width = boundHeight;
 transform = CGAffineTransformMakeScale(-1.0, 1.0);
 transform = CGAffineTransformRotate(transform, M_PI / 2.0);
 break;
 
 case UIImageOrientationRight: //EXIF = 8
 boundHeight = bounds.size.height;
 bounds.size.height = bounds.size.width;
 bounds.size.width = boundHeight;
 transform = CGAffineTransformMakeTranslation(imageSize.height, 0.0);
 transform = CGAffineTransformRotate(transform, M_PI / 2.0);
 break;
 
 default:
 [NSException raise:NSInternalInconsistencyException format:@"Invalid image orientation"];
 }
 UIGraphicsBeginImageContext(bounds.size);
 CGContextRef context = UIGraphicsGetCurrentContext();
 
 if (orient == UIImageOrientationRight || orient == UIImageOrientationLeft) {
 CGContextScaleCTM(context, -scaleRatio, scaleRatio);
 CGContextTranslateCTM(context, -height, 0);
 }
 else {
 CGContextScaleCTM(context, scaleRatio, -scaleRatio);
 CGContextTranslateCTM(context, 0, -height);
 }
 
 CGContextConcatCTM(context, transform);
 
 CGContextDrawImage(UIGraphicsGetCurrentContext(), CGRectMake(0, 0, width, height), imgRef);
 UIImage *imageCopy = UIGraphicsGetImageFromCurrentImageContext();
 UIGraphicsEndImageContext();
 
 return imageCopy;
}
+(UIImage *)scaleImage:(UIImage *)image toSize:(CGSize)targetSize {
 CGFloat scaleFactor = 1.0;
 if (image.size.width > targetSize.width || image.size.height > targetSize.height)
 if (!((scaleFactor = (targetSize.width / image.size.width)) > (targetSize.height / image.size.height))) //scale to fit width, or
 scaleFactor = targetSize.height / image.size.height; // scale to fit heigth.
 UIGraphicsBeginImageContext(targetSize);
 CGRect rect = CGRectMake((targetSize.width - image.size.width * scaleFactor) / 2,
 (targetSize.height - image.size.height * scaleFactor) / 2,
 image.size.width * scaleFactor, image.size.height * scaleFactor);
 [image drawInRect:rect];
 UIImage *scaledImage = UIGraphicsGetImageFromCurrentImageContext();
 UIGraphicsEndImageContext();
 return scaledImage;
}
+ (UIImage *)croppIngimageByImageName:(UIImage *)imageToCrop toRect:(CGRect)rect forImageViewRect:(CGSize)imageVwRect{
 
 // UIImage *tempImage;
 // tempImage=[self scaleImage:imageToCrop toSize:imageVwRect];
 
 CGImageRef imageRef = CGImageCreateWithImageInRect([imageToCrop CGImage], rect);
 UIImage *cropped = [UIImage imageWithCGImage:imageRef];
 CGImageRelease(imageRef);
 
 // cropped=[self scaleImage:cropped toSize:rect.size];
 return cropped;
}
+ (UIImage *)getBlackAndWhiteForImage:(UIImage *)someImage
{
 CIImage *beginImage = [CIImage imageWithCGImage:someImage.CGImage];
 
 CIImage *blackAndWhite = [CIFilter filterWithName:@"CIColorControls" keysAndValues:kCIInputImageKey, beginImage, @"inputBrightness", [NSNumber numberWithFloat:0.0], @"inputContrast", [NSNumber numberWithFloat:1.1], @"inputSaturation", [NSNumber numberWithFloat:0.0], nil].outputImage;
 CIImage *output = [CIFilter filterWithName:@"CIExposureAdjust" keysAndValues:kCIInputImageKey, blackAndWhite, @"inputEV", [NSNumber numberWithFloat:0.7], nil].outputImage;
 
 CIContext *context1 = [CIContext contextWithOptions:nil];
 CGImageRef cgiimage = [context1 createCGImage:output fromRect:output.extent];
 UIImage *newImage = [UIImage imageWithCGImage:cgiimage];
 
 CGImageRelease(cgiimage);
 
 return newImage;
}
+(UIImage *)grayishImageFor:(UIImage *)inputImage {
 
 // Create a graphic context.
 UIGraphicsBeginImageContextWithOptions(inputImage.size, YES, 1.0);
 CGRect imageRect = CGRectMake(0, 0, inputImage.size.width, inputImage.size.height);
 
 // Draw the image with the luminosity blend mode.
 // On top of a white background, this will give a black and white image.
 [inputImage drawInRect:imageRect blendMode:kCGBlendModeLuminosity alpha:1.0];
 
 // Get the resulting image.
 UIImage *filteredImage = UIGraphicsGetImageFromCurrentImageContext();
 UIGraphicsEndImageContext();
 
 return filteredImage;
}
+(UIImage *)lightenTheImage:(UIImage *)img withBrightness:(float)intensity
{
 CIFilter* brightnessFilter2 = [CIFilter filterWithName:@"CIColorControls" keysAndValues: @"inputImage", [CIImage imageWithCGImage:img.CGImage], nil];
 
 [brightnessFilter2 setValue:[NSNumber numberWithFloat:((intensity * 2.0) - 1.0)] forKey: @"inputBrightness"];
 
 CIImage* outputImage = [brightnessFilter2 outputImage];
 CIContext* context2 = [CIContext contextWithOptions:nil];
 
 CGImageRef cgiig = [context2 createCGImage:outputImage fromRect:[outputImage extent]];
 UIImage* newUIImage = [UIImage imageWithCGImage:cgiig];
 
 return newUIImage;
}
+(UIImage *)rotateImage:(UIImage *)image byDegrees:(CGFloat)degrees
{
 // calculate the size of the rotated view's containing box for our drawing space
 UIView *rotatedViewBox = [[UIView alloc] initWithFrame:CGRectMake(0,0,image.size.width, image.size.height)];
 CGAffineTransform t = CGAffineTransformMakeRotation(M_PI/180.0f*degrees);
 rotatedViewBox.transform = t;
 CGSize rotatedSize = rotatedViewBox.frame.size;
 // Create the bitmap context UIGraphicsBeginImageContext(rotatedSize);
 CGContextRef bitmap = UIGraphicsGetCurrentContext();
 // Move the origin to the middle of the image so we will rotate and scale around the center.
 CGContextTranslateCTM(bitmap, rotatedSize.width/2, rotatedSize.height/2); 
 // Rotate the image context
 CGContextRotateCTM(bitmap, (M_PI/180.0f*degrees));
 
 // Now, draw the rotated/scaled image into the context
 CGContextScaleCTM(bitmap, 1.0, -1.0);
 CGContextDrawImage(bitmap, CGRectMake(-image.size.width / 2, -image.size.height / 2, image.size.width, image.size.height), [image CGImage]);
 
 UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
 UIGraphicsEndImageContext();
 return newImage;
 
}
Hope this will help…
Charan Giri

Hot to Sharing information from iOS app to Social network(Facebook , twitter, whatsapp)

Here we are discussing using native sharing features(SLComposeViewController) of iOS and WhatsApp. Use the below code of facebook when you need a sharing feature only, where app doesn’t need social network login for facebook.

#import <Accounts/Accounts.h> and  #import <Social/Social.h> in your ViewController

For Facebook

if ([SLComposeViewController isAvailableForServiceType:SLServiceTypeFacebook])
 {
 SLComposeViewController *fbPost = [SLComposeViewController
 composeViewControllerForServiceType:SLServiceTypeFacebook];
 [fbPost setInitialText:@"Blog on iOS"];
 [fbPost addURL:[NSURL URLWithString:@"https://charangiri.wordpress.com"]];
[fbPost addImage:[UIImage imageNamed:@"shareImage.png"]];
 [self presentViewController:fbPost animated:YES completion:nil];
 [fbPost setCompletionHandler:^(SLComposeViewControllerResult result) {
 switch (result) {
 case SLComposeViewControllerResultCancelled:
 NSLog(@"Post Canceled");
 break;
 case SLComposeViewControllerResultDone:
 NSLog(@"Post Sucessful");
 break;
 default:
 break;
 }
 [self dismissViewControllerAnimated:YES completion:nil];
 }];
 }
 else{
 NSLog(@"SLServiceTypeFacebook isNotAvailableForServiceType");
}

For Twitter

if ([SLComposeViewController isAvailableForServiceType:SLServiceTypeTwitter])
 {
 SLComposeViewController *fbPost = [SLComposeViewController
 composeViewControllerForServiceType:SLServiceTypeTwitter];
[fbPost setInitialText:@"Blog on iOS"];
 [fbPost addURL:[NSURL URLWithString:@"https://charangiri.wordpress.com"]];
[fbPost addImage:[UIImage imageNamed:@"shareImage.png"]];
[self presentViewController:fbPost animated:YES completion:nil];
[fbPost setCompletionHandler:^(SLComposeViewControllerResult result) {
switch (result) {
 case SLComposeViewControllerResultCancelled:
 NSLog(@"Post Canceled");
 break;
 case SLComposeViewControllerResultDone:
 NSLog(@"Post Sucessful");
 break;
default:
 break;
 }
[self dismissViewControllerAnimated:YES completion:nil];
}];
}
else{
 NSLog(@"SLServiceTypeTwitter isNotAvailableForServiceType");
}

For SinaWeibo

if ([SLComposeViewController isAvailableForServiceType:SLServiceTypeSinaWeibo])
 {
 SLComposeViewController *fbPost = [SLComposeViewController
 composeViewControllerForServiceType:SLServiceTypeSinaWeibo];
[fbPost setInitialText:@"Blog on iOS"];
 [fbPost addURL:[NSURL URLWithString:@"https://charangiri.wordpress.com"]];
[fbPost addImage:[UIImage imageNamed:@"shareImage.png"]];
[self presentViewController:fbPost animated:YES completion:nil];
[fbPost setCompletionHandler:^(SLComposeViewControllerResult result) {
switch (result) {
 case SLComposeViewControllerResultCancelled:
 NSLog(@"Post Canceled");
 break;
 case SLComposeViewControllerResultDone:
 NSLog(@"Post Sucessful");
 break;
default:
 break;
 }
[self dismissViewControllerAnimated:YES completion:nil];
}];
}
 else{
 NSLog(@"SLServiceTypeSinaWeibo isNotAvailableForServiceType");
}

For WhatsApp :(No need of any framework to import)

NSURL *whatsappURL = [NSURL URLWithString:@"whatsapp://send?text=Hello%2C%20World!"];
if ([[UIApplication sharedApplication] canOpenURL: whatsappURL]) {
    [[UIApplication sharedApplication] openURL: whatsappURL];
}
Hope this will help…
Charan Giri

Customizing NSLog

This code will help you to get the line number and the way it prints the log will look clear and well formatted.

Write below code in AppDelegate or .PCH file. 

#ifdef DEBUG
#define CLog( s, ... ) NSLog( @"\n\n************************ DEBUG ***********************\n Class&method: %@,\n Line of Code: %d\n element Info: %@\n******************************************************************\n\n",  \ [[NSString stringWithUTF8String:__FUNCTION__] lastPathComponent], __LINE__, \ [NSString stringWithFormat:(s), ##__VA_ARGS__] );
#else
#define CLog(...)
#endif

After writing this code you need to call CLog instead of NSLog

Example:

CLog(@"some text here");
CLog(@"%@",someObject);
CLog(@"some text here %@ with another text %u",someObject, anotherObject);
Hope this will help…
Charan Giri

States of Application

An app can only be in one state at a particular time. These states changes to the different state as per user or system actions. For example, suppose we press the Home button and a phone call comes in then the currently running app changes its state to the response.

Not running – The app is not launched yet or exited by the system.
Inactive – An app stays in this state when it is running but executing other code.
Active – The app is running in the foreground and responding for users action. This is the normal mode for any running app.
Background – The app is running in background and executing code. The app enetrs this state while working on any other app in foreground.
Suspended – The app is running in background but not executing code.
Return to Not Running/Termination (Rare) – Occasionally, the application’s process is destroyed,
and the application returns to the Not Running state. This happens in low-memory situations, or if the user manually terminates the application.

When app goes from one state to another state, It is called app delegate methods. These methods provide a way to take appropriate action on app state changes.

List of methods along with summary:

application:didFinishLaunchingWithOption :- This method is called just after an app is launched first time.
applicationDidBecomeActive :- This method is called just after an app enters in foreground mode. This indicates that app is in Active state
applicationWillResignActive :- This method is called just before an app enters in Background state. This Indicates that app is in Inactive state.
applicationDidEnterBackground :- This method is called just after an app enters in Background state. In this state app may be suspended at any time.
applicationWillEnterForeground :- This method is called when an app state changes from background mode to foreground mode. It indicates that app is in Inactive state
applicationWillTerminated :- This method is called just before an app exits and try to go into Not running state.

What we can do in Background State

For a fixed amount of time one can request app for background execution.
We can declare some specific services for regular background execution.
We can use local notifications to display alert on particular time for running an application.
We can get user’s current location when app is in background state.
Register a Background Task – If an application needs to complete an important task, it can ask iOS not to interrupt the task when the application moves into the background. For example, an application might need to finish logging in a user, or finish downloading a large file.
Register as a Background-Necessary Application – An app can register as a specific type of application that has known, specific backgrounding requirements, such as Audio, Location . These applications are allowed continuous background processing privileges as long as they are performing tasks that are within the parameters of the registered application type.

You can also enable this support by including the UIBackgroundModes key with the location value in your app’s Info.plist file
You can also enable this support by including the UIBackgroundModes key with the audio value in your app’s Info.plist file
You can also enable this support by including the UIBackgroundModes key with the voip value in your app’s Info.plist file
You can also enable this support by including the UIBackgroundModes key with the remote-notification value in your app’s Info.plist file
You can also enable this support by including the UIBackgroundModes key with the external-accessory value in your app’s Info.plist file
You can also enable this support by including the UIBackgroundModes key with the bluetooth-peripheral value in your app’s Info.plist file
You can also enable this support by including the UIBackgroundModes key with the newsstand-content value in your app’s Info.plist file

Hope this will help….
Charan Giri

How to Upload multiple Images to server ?

Usually we need to upload image to server in POST format. Here is an example how we will post multiple Images to server from an iOS app.

-(void)uploadMultiplePics 
{ 
NSString *string ; 
NSData *imageData; 
NSString*urlString=[NSString stringWithFormat:@"http://******"]; 
// urlString=[urlString stringByReplacingOccurrencesOfString:@" " withString:@""]; 
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init]; 
[request setURL:[NSURL URLWithString:urlString]]; 
[request setHTTPMethod:@"POST"]; 
NSMutableData *body; 
body = [NSMutableData data]; 
for(int j=0;j < scrollViewImageArray.count;j++) // scrollViewImageArray is images count 
{ 
double my_time = [[NSDate date] timeIntervalSince1970]; 
int k=j+1; 
NSString *imageName = [NSString stringWithFormat:@"%d%d",j,(int)(my_time)]; 
NSString *imagetag=[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"image%d\"; filename=\"",k]; 
string = [NSString stringWithFormat:@"%@%@%@", imagetag, imageName, @".jpg\"\r\n\""]; 
NSString *boundary = @"---------------------------14737809831466499882746641449"; 
NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@",boundary]; 
[request addValue:contentType forHTTPHeaderField: @"Content-Type"]; 
[body appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]]; 
[body appendData:[[NSString stringWithString:string] dataUsingEncoding:NSUTF8StringEncoding]]; 
[body appendData:[@"Content-Type: application/octet-stream\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]]; 
UIImage *image=[[UIImage alloc]init]; 
image=[scrollViewImageArray objectAtIndex:j]; 
// scrollViewImageArray images array 
imageData = UIImageJPEGRepresentation(image, 90); 
[body appendData:[NSData dataWithData:imageData]]; 
[body appendData:[[NSString stringWithFormat:@"\r\n--%@--\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]]; 
} 
[request setHTTPBody:body]; 
NSData *returnData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil]; 
NSString*s= [[NSString alloc] initWithData:returnData encoding:NSUTF8StringEncoding];
}


 

Here is the code for PHP server

$uploaddir = "../images/profile_images/";
 $file = basename($_FILES['image']['name']); 
 $uploadfile = $uploaddir . $file;
 if (move_uploaded_file($_FILES['image']['tmp_name'], $uploadfile)) 
 { $updt_img = "UPDATE tiny_users SET profile_photo = '".$file."' WHERE user_id = '".$final_res[1]."'";
 mysql_query($updt_img); }}

Hope this will help…
Charan Giri

NSData

NSData and its mutable subclass NSMutableData provide data objects, object-oriented wrappers for byte buffers. Data objects let simple allocated buffers (that is, data with no embedded pointers) take on the behavior of Foundation objects.

NSData creates static data objects, and NSMutableData creates dynamic data objects. NSData and NSMutableData are typically used for data storage and are also useful in Distributed Objects applications, where data contained in data objects can be copied or moved between applications.

Creating Data Objects

data
dataWithBytes:length:
dataWithBytesNoCopy:length:
dataWithBytesNoCopy:length:freeWhenDone:
dataWithContentsOfFile:
dataWithContentsOfFile:options:error:
dataWithContentsOfMappedFile:
 (iOS 8.0)
dataWithContentsOfURL:
dataWithContentsOfURL:options:error:
dataWithData:
initWithBase64EncodedData:options:
initWithBase64EncodedString:options:
initWithBase64Encoding:
 (iOS 7.0)
initWithBytes:length:
initWithBytesNoCopy:length:
initWithBytesNoCopy:length:deallocator:
initWithBytesNoCopy:length:freeWhenDone:
initWithContentsOfFile:
initWithContentsOfFile:options:error:
initWithContentsOfMappedFile:
 (iOS 8.0)
initWithContentsOfURL:
initWithContentsOfURL:options:error:
initWithData:

Base-64 Encoding

base64EncodedDataWithOptions:
base64EncodedStringWithOptions:
base64Encoding
 (iOS 7.0)
Testing Data
isEqualToData:
length

Storing Data

writeToFile:atomically:
writeToFile:options:error:
writeToURL:atomically:
writeToURL:options:error:

Constants

NSDataReadingOptions
NSDataBase64EncodingOptions
NSDataBase64DecodingOptions
Legacy Reading Options
NSDataWritingOptions
Legacy Writing Options
NSDataSearchOptions

Prior to iOS 7.0, Base64 encoding and decoding tasks required you to implement your own method or include part of a third party framework.In typical Apple fashion, it’s now very easy to use this functionality. There are four core Base64 methods as follows:

- (id)initWithBase64EncodedString:(NSString *)base64String 
 options:(NSDataBase64DecodingOptions)options;
 
- (NSString *)base64EncodedStringWithOptions:
 (NSDataBase64EncodingOptions)options;
 
- (id)initWithBase64EncodedData:(NSData *)base64Data 
 options:(NSDataBase64DecodingOptions)options;
 
- (NSData *)base64EncodedDataWithOptions:
 (NSDataBase64EncodingOptions)options;

Example for Create a Base64 Encoded NSString Object

// Create NSData object
NSData *nsdata = [@"Your Name encoded in Base64"
 dataUsingEncoding:NSUTF8StringEncoding];
 
// Get NSString from NSData object in Base64
NSString *base64Encoded = [nsdata base64EncodedStringWithOptions:0];
 
// Print the Base64 encoded string
NSLog(@"Encoded: %@", base64Encoded);
  
// NSData from the Base64 encoded str
NSData *nsdataFromBase64String = [[NSData alloc]
 initWithBase64EncodedString:base64Encoded options:0];
 
// Decoded NSString from the NSData
NSString *base64Decoded = [[NSString alloc] 
 initWithData:nsdataFromBase64String encoding:NSUTF8StringEncoding];
NSLog(@"Decoded: %@", base64Decoded);

Example for Base64 Encode an NSData Object

// Create NSData object
NSData *dataObject = [@"Your Name" dataUsingEncoding:NSUTF8StringEncoding];
 
// Convert to Base64 data
NSData *base64Data = [dataObject base64EncodedDataWithOptions:0];
NSLog(@"%@", [NSString stringWithUTF8String:[base64Data bytes]]);

// Now convert back from Base64
NSData *nsdataDecoded = [base64Data initWithBase64EncodedData:base64Data options:0];
NSString *str = [[NSString alloc] initWithData:nsdataDecoded encoding:NSUTF8StringEncoding];
NSLog(@"%@", str);
Hope this will help
Charan Giri

IOS Global variables using AppDelegate / NSUserDefaults / Keychain

In order to use global variables,which we need to use throughout the project,we need to use AppDelegate/NSUserDefaults/Keychain We can declare a variable in AppDelegate/NSUserDefaults/Keychain and access it through out the project as per our requirement.

Global variables in AppDelegate

Here variable will stay alive till app is in Foreground state or background state. If app is deleted from background the information in AppDelegate will be lost.

Global variables in NSUserDefaults

Here variable will stay alive till app is not deleted on the device. If app is deleted from device the information in
NSUserDefaults will be lost.

Global variables in Keychain

Here variable will stay alive till app is installed in the device. If app is deleted from device and when we re-install the app then from Keychain we can get information back to app.

What all we can save
NSString
NSNumber
NSDate
NSArray
NSDictionary
NSData

Let us consider an example where we are saving the userId in NSString format once user login with valid credentials. and how we use the userId using AppDelegate / NSUserDefaults / Keychain

Here is the trick of how to use the app delegate variables as global variables and access them globally throughout the project.

First we need to declare a variable in .h file of app delegate.

@property (nonatomic, String) NSString *userId;

Then we need to synthesize it in .m file of app delegate.

@synthesize userId;

In AppDelegate create an class method for AppDelegate instance

First we need to declare a method in .h file of app delegate as

+ (AppDelegate*)sharedInstanceofAppdelegate;

Then, we need to implement that method in .m file of app delegate as

+ (AppDelegate*)sharedInstanceofAppdelegate
{
 return (AppDelegate *)[UIApplication sharedApplication].delegate;
}

Now, how we set value to the userId, as per the example we took we need to save it in successful login. Lets consider user login is successful and we are saving the userId in userId(appdelegate)

first import AppDelegate, create an instance object for AppDelegate as
#import "AppDelegate.h"
AppDelegate *appDelegate;
appDelegate=[AppDelegate sharedInstanceofAppdelegate];//in didLoad method
appDelegate.userId=@"userId value here";
to retrieve information from AppDelegate variable
//appDelegate.userId
NSLog(@"%@",appDelegate.userId);
Here is the trick of how to use the NSUserDefaults variables as global variables and access them globally throughout the project.
NSUserDefaults gives you a way to save key value pairs in a way that will persist even when your application closes.
You can think of NSUserDefaults as being very similar to a NSDictionary but one that has plumbing in place to write and read to storage.
The easiest way to use NSUserDefaults is to call the class method standardUserDefaults like this:
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
How to save userId in NSUserDefaults
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setValue:@"userId value here" forKey:@"userId"];
How to get userId from NSUserDefaults
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults objectForKey:@"userId"];
To sync data in defaults (best practice to synchronize when data will be kept on updating).
//[defaults synchronize];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setValue:@"userId value here" forKey:@"userId"];
[defaults synchronize];

Here is the trick of how to use the Keychain variables as global variables and access them globally throughout the project.

Saving userId in Keychain is not a good practice, because if user want to change the user of app then this doesn’t help we need to save it if it is must.

Below is example for saving emailId and password. Create an NSObject class with name “KeychainAcess”

In your KeychainAcess.h

#import <Foundation/Foundation.h>

@interface KeychainAcess : NSObject

+ (void)save:(NSString *)service data:(id)data;
+ (id)load:(NSString *)service;
+ (void)delete:(NSString *)service;

@end

In your KeychainAcess.m

#import "KeychainAcess.h"

@implementation KeychainAcess

+ (NSMutableDictionary *)getKeychainQuery:(NSString *)service {
 return [NSMutableDictionary dictionaryWithObjectsAndKeys:
 (__bridge id)kSecClassGenericPassword, (__bridge id)kSecClass,
 service, (__bridge id)kSecAttrService,
 service, (__bridge id)kSecAttrAccount,
 (__bridge id)kSecAttrAccessibleAfterFirstUnlock, (__bridge id)kSecAttrAccessible,
 nil];
}

+ (void)save:(NSString *)service data:(id)data {
 NSMutableDictionary *keychainQuery = [self getKeychainQuery:service];
 SecItemDelete((__bridge CFDictionaryRef)keychainQuery);
 [keychainQuery setObject:[NSKeyedArchiver archivedDataWithRootObject:data] forKey:(__bridge id)kSecValueData];
 SecItemAdd((__bridge CFDictionaryRef)keychainQuery, NULL);
}

+ (id)load:(NSString *)service {
 id ret = nil;
 NSMutableDictionary *keychainQuery = [self getKeychainQuery:service];
 [keychainQuery setObject:(id)kCFBooleanTrue forKey:(__bridge id)kSecReturnData];
 [keychainQuery setObject:(__bridge id)kSecMatchLimitOne forKey:(__bridge id)kSecMatchLimit];
 CFDataRef keyData = NULL;
 if (SecItemCopyMatching((__bridge CFDictionaryRef)keychainQuery, (CFTypeRef *)&keyData) == noErr) {
 @try {
 ret = [NSKeyedUnarchiver unarchiveObjectWithData:(__bridge NSData *)keyData];
 }
 @catch (NSException *e) {
 NSLog(@"Unarchive of %@ failed: %@", service, e);
 }
 @finally {}
 }
 if (keyData) CFRelease(keyData);
 return ret;
}

+ (void)delete:(NSString *)service {
 NSMutableDictionary *keychainQuery = [self getKeychainQuery:service];
 SecItemDelete((__bridge CFDictionaryRef)keychainQuery);
}
@end

Now use relevant Method according to requirement.

Hope this will help…
Charan Giri

Protocols

Objective-C allows you to define protocols, which declare the methods expected to be used for a particular situation.
Delegation is a design pattern which allows one class to take some responsibility from another in a way that decouples the code (very good, flexible thing).
Protocols are an Objective-C language feature which allows you to write and use code which makes use of the delegation concept

Defining the protocol

A protocol is defined by using the @protocol compiler directive, and ends with an @end directive. In between the two directives, we must declare the protocol method:

@protocol protocolName
method declarations;
@end

Method in protocol

In protocols there are 2 types of methods
i. required (These methods must be implemented)
ii. optional (These methods will be implemented if required.)

Creating a delegate property

The delegate property is created in the class definition of the object that will utilize a delegate. A delegate property is created by defining an instance variable in the header file and synthesizing it in the implementation file.

Example, define an instance variable called delegate of type <protocolName>:

id <protocolName> delegate;

The instance variable must be synthesized in the implementation file with the following command:

@synthesize delegate

Let us consider an example, we have 2 viewControllers where in first viewController we have a list of posts (Like a facebook app post with no.of comments likes…), when we click on comment button then it will navigate to second screen where we can write a comment. Suppose we wrote a comment then the no.of comments for that post in the first viewController should be increased by “1”. When we go back to first viewController after writing a comment to make the comment count updated we need to call webservice. Instead of that Protocols will help a lot. As we know whether we made a comment or not. if we made a comment we will send information to first ViewController.

How to do it? 

From the above example we need to send information from second view controller to first so,

In SecondViewController:

To create your own custom delegate protocol, modify the header file for the selected class to add the @protocol declaration, a delegate @property, and declare the methods that delegates can implement.

#import <UIKit/UIKit.h>
@protocol resultToFirstScreen <NSObject>
- (void)sendnformationBackToFirstScreen :(NSDictionary *)infoDict; // if nothing is mentioned then the method is required
/* 
@required
- (void)sendnformationBackToFirstScreen :(NSDictionary *)infoDict;
@optional
- (void)sendnformationBackToFirstScreen :(NSDictionary *)infoDict;
*/
@end
@interface SecondViewController : UIViewController
@property (weak) id<resultToFirstScreen> delegate;
@end

In the implementation file, anytime you want to call a delegate method, first check to see if the delegate is set, and if it responds to the selector. Then call the method:

Under @implementation write

 @synthesize delegate=_delegate;

In Comment button action (sending information to first ViewController)

if (_delegate)
 {
 NSDictionary *s=[[NSDictionary alloc] initWithObjectsAndKeys:@"hi",@"say", nil];
 [_delegate sendnformationBackToFirstScreen:s];
 }
In FirstViewController

Now for classes you want to conform to your new protocol, include the header file(secondViewController) and delegate protocol in the @interface:

 @interface FirstViewController ()<resultToFirstScreen>
Implement the protocol method:
-(void)sendnformationBackToFirstScreen :(NSDictionary *)infoDict
{
 NSLog(@"infoDict %@===>",infoDict); here we will say [self.tableView reload];
}

*Note: When you navigate from First ViewController to Second You need to set delegate like this otherwise Protocols will not work.

 SecondViewController *sec =[[SecondViewController alloc]init];
 sec.delegate =self;
Hope this will help…
Charan Giri