Monday, June 18, 2012

XML parser in Objective-C for iPhone Projects (KissXML Parser)

There are many XML parsers for iPhone project :



But here I want to share my view on KissXML Parser, because I have implemented this in all my projects.

Getting started with  KissXML Parser :

1.       Download the API's package for KissXML Parser from here.

2.      Add all files of this package in your project.

3.      Add libxml2.dylib framework in your project.

4.      Do some setting in your project:
         Open application file under Target in left panel of xcode ->  Go To build tab -> set the values of "Other Linker Flags" and "Header Search Paths" as shown in below picture:

5.      Now suppose your xml is in this formate:

     and you want to parse this xml and save it data in an array.

6.   Now open your app.h file and write this code :
7.   Now open your app.m file and write this code :
Note: Here, this xml is static for static data, you can create your own dynamic xml for dynamic data.


Add Images To iPhone Simulator photo gallery

There are 2 ways to add image to iphone photo gallery:

  • Direct Method(drag and drop method).
  • Though coding.
Direct Method(drag and drop method):

Launch the simulator and go to this screen:
 
Drag the image which you want to add in gallery and drop on safari icon:
Click on image(anywhere inside the red rectangle in above image) and hold it: 
You will get above 3 options: Save Image, Copy and Cancle.
Click on Save Image.
Now to see the saved image Go To below screen and click on photo: 
 It will open the iPhone Album, select the 1st row of table, it will open all saved images.
Just double click on image to open.
Though coding : 
  1. Create a new project in xcode and name it as addImageInPhotoGallery.
  2. Add the image(Ref step 3 of .....) which you want to add in photo gallery in Resource folder of project.
  3. Open addImageInPhotoGallery.m, and write this code :

 - (void)viewDidLoad {
    
//suppose you have added photo.png in resource folder.
UIImage *sampleImage = [UIImage imageNamed:@"photo.png"];
    
UIImageWriteToSavedPhotosAlbum(sampleImage, self, @selector(image:didFinishSavingWithError:contextInfo:), nil);
   
 [super viewDidLoad];
}

- (void) image:(UIImage *) image didFinishSavingWithError:(NSError *) error contextInfo:(void *) contextInfo {
    UIAlertView *alert;
   
    // Unable to save the image 
    if (error)
        alert = [[UIAlertView alloc] initWithTitle:@"Error"
                                           message:@"Unable to save image to Photo Album."
                                          delegate:self cancelButtonTitle:@"Ok"
                                 otherButtonTitles:nil];
    else // All is well
        alert = [[UIAlertView alloc] initWithTitle:@"Success"
                                           message:@"Image saved to Photo Album."
                                          delegate:self cancelButtonTitle:@"Ok"
                                 otherButtonTitles:nil];
   
   
    [alert show];
    [alert release];
   
}


4. Now just build and run this code.
 You will not see any thing on simulator screen, Go to photo gallery, open the Album and you will see  that photo is added to photo gallery.
 
 



 
 

iPhone/iPad Technical Interview Question(FAQ) with answers(Part 2)


Q11. What is atomic and nonatomic property attribute? 
A.
Both are same unless we use our setter and getter methods.
If we create our own setter and getter method, then atomic is useful in thread processing, but it is slow.
Nonatomic does not give guarantee on thread processing but it is fast.

Q12. What is the life cycle of view controller?
A.  Press here....
  
Q13. Difference between viewDidLoad, viewWillAppear, viewDidAppear and viewLoad?
A.
  • ViewDidLoad - The viewDidLoad method is only called when the view is first loaded from the Nib file. If the view was already loaded and you push the view again it will not fire again. viewDidLoad is things you have to do once.Whenever I'm adding controls to a view that should appear together with the view, right away, I put it in the ViewDidLoad method. Basically this method is called whenever the view was loaded into memory. So for example, if my view is a form with 3 labels, I would add the labels here; the view will never exist without those forms.
  • ViewWillAppear: I use ViewWillAppear usually just to update the data on the form. So, for the example above, I would use this to actually load the data from my domain into the form. Creation of UIViews is fairly expensive, and you should avoid as much as possible doing that on the ViewWillAppear method, becuase when this gets called, it means that the iPhone is already ready to show the UIView to the user, and anything heavy you do here will impact performance in a very visible manner (like animations being delayed, etc).
when you are loading things from a server, you also have to think about latency. If you pack all of your network communication into viewDidLoad or viewWillAppear, they will be executed before the user gets to see the view - possibly resulting a short freeze of your app. It may be good idea to first show the user an unpopulated view with an activity indicator of some sort. When you are done with your networking, which may take a second or two (or may even fail - who knows?), you can populate the view with your data. Good examples on how this could be done can be seen in various twitter clients. For example, when you view the author detail page in Twitterrific, the view only says "Loading..." until the network queries have completed.
  • ViewDidAppear: Finally, I use the ViewDidAppear to start off new threads to things that would take a long time to execute, like for example doing a webservice call to get extra data for the form above.The good thing is that because the view already exists and is being displayed to the user, you can show a nice "Waiting" message to the user while you get the data.
  • ViewLoad: loadView is the method in UIViewController that will actually load up the view and assign it to the "view" property. This is also the location that a subclass of UIViewController would override if you wanted to programatically set up the "view" property.
          I've found that often when I add init code to loadView, I end up with an infinite stack trace
          Don't read self.view in -loadView. Only set it, don't get it.
          The self.view property accessor calls -loadView if the view isn't currently loaded. There's your infinite recursion.

Very Soon I am going to answer these questions: 
Q.What is the life cycle of iPhone app?

iPhone/iPad Technical Interview Question(FAQ) with answers(Part 1)

Q1.What is the iPhone Application Entry point?
A. The main function:
int main(int argc, char *argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];


    int retVal = UIApplicationMain(argc, argv, nil, nil);
    [pool release];
    return retVal;
 }

Q2.What is the GUI Entry Point?
A. 
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {    

    
    // Override point for customization after application launch.

    // Add the view controller's view to the window and display.
    [self.window addSubview:viewController.view];
    [self.window makeKeyAndVisible];

    return YES;
}

Q3.What is the Model structure of iPhone Application?
A.
@interface RootViewController : UITableViewController {
 NSArray *tableDataSource;

NSString *CurrentTitle;
NSInteger CurrentLevel;
IBOutlet UITableView * newsTable
UIActivityIndicatorView * activityIndicator
CGSize cellSize
NSMutableArray * stories
NSMutableDictionary * item;
NSString * currentElement
NSMutableString * currentTitle, * currentDate, * currentSummary, * currentLink
}

@property (nonatomic, retain) NSArray *tableDataSource;
@property (nonatomic, retain) NSString *CurrentTitle;
@property (nonatomic, readwrite) NSInteger CurrentLevel;



Q4.What is the View structure of iPhone Application?
A.
@interface loancalculatorViewController : UIViewController {
IBOutlet UITextField *tbxLoanAmount;
IBOutlet UITextField *annualInterestRate;
IBOutlet UITextField *noOfYears;
IBOutlet UILabel *monthlyPayment;
IBOutlet UILabel *totalInterest;
IBOutlet UILabel *totalPayment;
}

@property (nonatomic,retain) UITextField *tbxLoanAmount;
@property (nonatomic,retain) UITextField *annualInterestRate;
@property (nonatomic,retain) UITextField *noOfYears;
@property (nonatomic,retain) UILabel *monthlyPayment;
@property (nonatomic,retain) UILabel *totalInterest;
@property (nonatomic,retain) UILabel *totalPayment;


Q5.What is the Controller structure of iPhone Application?
A.

@interface RootViewController : UITableViewController {
mainView* myMainView;
}
- (id)init;
- (void)dealloc;
- (void)loadView;


Q6. What are Delegates in Objective-C?

A. 
When we create an object of a class then some methods are automatically called, these methods are called delegates.
For example: when we create an object of UITableView like: UITableView *myTable;
then some methods like:
  • numberOfSectionsInTableView:
  • numberOfRowsInSection:
  • heightForRowAtIndexPath:
  • cellForRowAtIndexPath:
  • didSelectRowAtIndexPath: 

automatically called. These methods are called delegated.

Q7. What is the need of these Delegates?
A.
 To execute some of must to do actions, we need these delegates.
For example: for a table it is must decided that, 
  • How many row will be there.
  • What will be the content on cell of each row.
  • What will happen after selecting the row.


Q8. How Memory Management is handle in iphone?



Q9. What is MVC ?
A.
MVC (Model View Controller) is a design pattern used in services architectures. MVC separate the software architecture into three distinct elements. The 'Model' is how the underlying data is structured. The 'View' is what is presented to the user or consumer. The 'Controller' is the element that performs the processing. More.....




Q10.  MVC supports loose or tight coupling?
A. 
MVC supports both loose and tight coupling, because there is usually a tight coupling
between the view and the controller because user actions are difficult to interpret without details of the presentation. For example:
   • What object mouse clicked on 
   • What text area user typed into
Actions must be interpreted in terms of presentation
View has the information to map points in view to application objects

Refer the figure in this post.

•    View needs to know about model. Controller needs to know about model and view, So view and the controller are tightly coupled.
•    Model doesn’t need to know about either’s design, So Model loosely coupled to view/controller

Memory Management in iPhone

In Mac OS X we have 2 options for memory management:
  • Reference Counting.
  • Garbage Collection(GC).
But, in iPhone there is no Garbage Collection(GC), it uses Reference Counting only.
Reference Counting also called as Retain Counting and Managed Memory.

Now, what is Reference Counting?

Each object keeps a count of how many other objects are using it (it is discussed in terms of Ownership).

If we create an object i.e. receive an object from a method that begins with alloc or new or contains the word copy, it means we own the object, and it reference count becomes 1.

If we receive an object from other method, we do not own the object. If we want to keep the object i.e. store it in an instance variable, we have to take ownership of that object by sending it a retain message, which increment it's retain count by 1.

We may also take ownership by copying the object  if it is capable of being copied, the object class must implement copyWithZone: .

If we own an object by any above method, we must relinquish our ownership by sending a release message to the object, which decreases its reference count by 1.

When an object's reference count becomes zero (0), the object is deallocated and its memory is returned to the heap.

If a release message causes an object's retain count to drop to zero(0), the release method  invokes the object's dealloc method.

QR Code reader/scanner for iphone app in objective c (source code) using ZBarSDK

Hey, I have googled a lot and found very less material for how to implement a QR code reader in our iPhone app. Here I have integrated all material and implemented in my project.
So here I am sharing my experience of implementing a QR code reader in our iPhone app using ZBarSDK.


Step 1: Download  ZBarSDK from here.


Step 2: Create a new project in xcode and name it as QRscanner.


Step 3: Integrate this  ZBarSDK folder in your xcode project by drag and drop on equal level of class folder in left panel in xcode.


Step 4: Add these 7 frameworks in Frameworks folder: 


  1. AudioToolbox.framework
  2. CoreMedia.framework
  3. QuartzCore.framework
  4. SystemConfiguration.framework
  5. libiconv.dylib
  6. AVFoundation.framework
  7. CoreVideo.framework

Step 5: Now Go To this link and generate some QR codes.
(to generate QR codes only add the text which you want to attach with QR code at the end of the link (e.g. I have written archana) and press enter, and right click to save this image.) 


Step 6: Add these generated QR code's image in iphone library.


Step 7: Now open QRscannerViewController.h in your xcode and write this code:


#import
#import "ZBarSDK.h"

@interface QRscannerViewController : UIViewController {

IBOutlet UITextView *resultTextView;
}
@property (nonatomic, retain) IBOutlet UITextView *resultTextView;
@property (nonatomic, retain) UIImagePickerController *imgPicker;

-(IBAction)StartScan:(id) sender;

@end

Step 8: Now open QRscannerViewController.m in your xcode and write this code:





#import "QRscannerViewController.h"

@implementation QRscannerViewController

@synthesize imgPicker,resultTextView;

-(IBAction)StartScan:(id) sender
{
ZBarReaderViewController *reader = [ZBarReaderViewController new];
reader.readerDelegate = self;
reader.readerView.torchMode = 0;
ZBarImageScanner *scanner = reader.scanner;
// TODO: (optional) additional reader configuration here
// EXAMPLE: disable rarely used I2/5 to improve performance
[scanner setSymbology: ZBAR_I25
  config: ZBAR_CFG_ENABLE
  to: 0];
// present and release the controller
[self presentModalViewController: reader
animated: YES];
[reader release];
resultTextView.hidden=NO;
}

- (void) readerControllerDidFailToRead: (ZBarReaderController*) reader
                             withRetry: (BOOL) retry{
NSLog(@"the image picker failing to read");
}

- (void) imagePickerController: (UIImagePickerController*) reader didFinishPickingMediaWithInfo: (NSDictionary*) info
{
NSLog(@"the image picker is calling successfully %@",info);
// ADD: get the decode results
id<NSFastEnumeration> results = [info objectForKey: ZBarReaderControllerResults];
ZBarSymbol *symbol = nil;
NSString *hiddenData;
for(symbol in results)
hiddenData=[NSString stringWithString:symbol.data];
NSLog(@"the symbols  is the following %@",symbol.data);
// EXAMPLE: just grab the first barcode
//  break;
// EXAMPLE: do something useful with the barcode data
//resultText.text = symbol.data;
resultTextView.text=symbol.data;
NSLog(@"BARCODE= %@",symbol.data);
NSUserDefaults *storeData=[NSUserDefaults standardUserDefaults];
[storeData setObject:hiddenData forKey:@"CONSUMERID"];
NSLog(@"SYMBOL : %@",hiddenData);
resultTextView.text=hiddenData;
[reader dismissModalViewControllerAnimated: NO];
}


Step 9: Now open QRscannerViewController.xib and design it UI like this:
Step 10: Now make connection of above 2 objects(UITextView and UIButton) with IBOutlet resultTextView and IBAction StartScan.(Refer Step 7 of…) 


At last build and run this app.


How to run this app:


Press  "START SCAN" button, and as we are running our app in simulator you will get screen like this:
Now press and hold (alt key)+(left click), Photo Album (image gallery, photo library) will open.
Select any QR code image. It will take hardly 2-3 seconds for scanning and finally you will get home screen with scanned data associated with QR code image on text view.