Pages

Labels

Thursday, June 28, 2012

JSON WebService in iPhone

iPhone JSON Library

This tutorial uses Stig Brautaset’s JSON library (version 2.2), which provides functionality for parsing and generating JSON. We won’t be using the JSON generating functionality in this tutorial.
The library provides two methods for parsing JSON: (1) a high-level category that extends NSString to include JSON parsing and (2) a more granular, slighly lower level object-based parser. We’ll start simple and use the former; we’ll switch to the latter near the end of the tutorial.
  1. Download the disk image
We’ll include the relevant bits into our project in a later step.

Creating The Project

Launch Xcode and create a new View-Based iPhone application called LuckyNumbers:
  1. Create a new project using File > New Project… from Xcode’s menu
  2. Select View-Based Application from the iPhone OS > Application section, click Choose…
  3. Name the project as LuckyNumbers and click Save

Adding JSON Support To The Project

In order to use the JSON functionality we’ll need to add it to the project:
  1. Expand the LuckyNumbers project branch in the Groups & Files panel of the project
  2. Using Finder, locate the JSON_2.2.dmg file you downloaded earlier and mount it by double clicking its icon. A new finder window with the DMG’s contents will open
  3. Drag and drop the JSON directory from the DMG onto the Classes folder under theLuckyNumbers project icon in the Groups & Files panel in Xcode
We’ll test that the JSON is set up properly by parsing a JSON dictionary string and using the resulting NSDictionary as a datasource for a message we’ll write to the console from our app’sviewDidLoad. This is throw-away code just to test that everything’s wired up properly.
Use this code for LuckyNumbersViewController.m (located in the project’s Classes Xcode folder):
#import "LuckyNumbersViewController.h"
#import "JSON/JSON.h"

@implementation LuckyNumbersViewController

- (void)viewDidLoad { 
 [super viewDidLoad];
 NSString *jsonString = [NSString stringWithString:@"{\"foo\": \"bar\"}"];
 NSDictionary *dictionary = [jsonString JSONValue];
 NSLog(@"Dictionary value for \"foo\" is \"%@\"", [dictionary objectForKey:@"foo"]);
}

- (void)dealloc {
    [super dealloc];
}

@end
Build and run the project. If the JSON SDK is configured properly you should see an entry in the console that says, Dictionary value for “foo” is “bar”.

Setting Up The (Spartan) UI

Our finished app will need a UILabel to display the lucky numbers that we’ll eventually grab using HTTP and JSON.
Use this code for LuckyNumbersViewController.h (located in the project’s Classes Xcode folder):
#import <UIKit/UIKit.h>

@interface LuckyNumbersViewController : UIViewController {
 IBOutlet UILabel *label;
}

@end
IBOutlet is a macro that tells the compiler that it needs to wire up this variable to a corresponding UILabel element added WYSIWYG in Interface Builder. In the next step, we’ll add that element and connect the two pieces:
Edit the LuckyNumbersViewController.xib file in Interface Builder:
  1. Expand the Resources folder under the LuckyNumbers project branch in the Groups & Files panel.
  2. Double-click the LuckyNumbersViewController.xib file
Make sure that the Library, Inspector and View windows are open/visible. If they are not:
  1. Show the Library window using Tools > Library from the menu
  2. Show the Inspector window using Tools > Inspector from the menu
  3. Show the View by clicking the View icon on the LuckyNumbersViewController.xib window
Add the label:
  1. Locate the Label component in the Library window and drag it onto the view
  2. In the View window use the label’s handles to enlarge it to about half the size of the view
  3. In the Inspector window under View Attributes (the left-most tab), set the label’s number of lines to 0.
Setting the label’s number of lines to zero configures the label dynamically size the text to fit within its bounds.
Connect the Interface Builder label the code’s label. While still in Interface Builder:
  1. Control-click on File’s Owner icon in the LuckyNumbersViewController.xib window
  2. In the resulting pop-up menu, click-and-hold (i.e., don’t unclick) on the right-justified circle in the locationLabel row of the Outlets section
  3. Drag the mouse to the Label in the View. A blue line will connect the two.
Confirm that the two have been connected. The pop-up menu should look like the image on the right.
If everything looks right, save the changes and close Interface Builder.

Fetching JSON Over HTTP

We’ll use Cocoa’s NSURLConnection to issue an HTTP request and retrieve the JSON data.
Cocoa provides both synchronous and asynchronous options for making HTTP requests. Synchronous requests run from the application’s main runloop cause the app to halt while it waits for a response. Asynchronous requests use callbacks to avoid blocking and are straightforward to use. We’ll use asynchronous requests.
First thing we need to do is update our view controller’s interface to include an NSMutableData to hold the response data. We declare this in the interface (and not inside a method) because the response comes back serially in pieces that we stitch together rather than in a complete unit.
Update LuckNumbersViewController.h. Changes are in bold:
#import <UIKit/UIKit.h>

@interface LuckyNumbersViewController : UIViewController {
 IBOutlet UILabel *label;
 NSMutableData *responseData;
}

To keep things simple, we’ll kick off the HTTP request from viewDidLoad.
Replace the contents of LuckyNumbersViewController.m with:

#import "LuckyNumbersViewController.h"
#import "JSON/JSON.h"

@implementation LuckyNumbersViewController

- (void)viewDidLoad { 
 [super viewDidLoad];

 responseData = [[NSMutableData data] retain];  
 NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.unpossible.com/misc/lucky_numbers.json"]];
 [[NSURLConnection alloc] initWithRequest:request delegate:self];   
}

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
 [responseData setLength:0];
}

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
 [responseData appendData:data];
}

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
 label.text = [NSString stringWithFormat:@"Connection failed: %@", [error description]];
}

- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
 [connection release];  
}

- (void)dealloc {
    [super dealloc];
}

@end  

This mostly boilerplate code initializes the responseData variable to be ready to hold the data and kicks off the connection in viewDidload; it gathers the pieces as they come in indidReceiveData; and the empty connectionDidFinishLoading stands ready to do something with the results.

Using The JSON Data

Next, we’ll flesh out the connectionDidFinishLoading method to make use of the JSON data retrieved in the last step.
Update the connectionDidFinishLoading method in LuckyNumbersViewController.m. Use this code:
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {  
 [connection release];

 NSString *responseString = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
 [responseData release];
 
 NSArray *luckyNumbers = [responseString JSONValue];
 
 NSMutableString *text = [NSMutableString stringWithString:@"Lucky numbers:\n"];
 
 for (int i = 0; i < [luckyNumbers count]; i++) 
  [text appendFormat:@"%@\n", [luckyNumbers objectAtIndex:i]];

 label.text =  text;
}
Our earlier throw-away test code created an NSDictionary. Here it creates an NSArray. The parser is very flexible and returns objects — including nested objects — that appropriately match JSON datatypes to Objective-C datatypes.

Better Error Handling

Thus far, we’ve been using the the convenient, high-level extensions to NSString method of parsing JSON. We’ve done so with good reason: it’s handy to simple send the JSONValuemessage to a string to accessed to the parsed JSON values.
Unfortunately, using this method makes helpful error handling difficult. If the JSON parser fails for any reason it simply returns a nil value. However, if you watch your console log when this happens, you’ll see messages describing precisely what caused the parser to fail.
It’d be nice to be able to pass those error details along to the user. To do so, we’ll switch to the second, object-oriented method, that the JSON SDK supports.
Update the connectionDidFinishLoading method in LuckyNumbersViewController.m. Use this code:
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {  
 [connection release];

 NSString *responseString = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
 [responseData release];
 
 NSError *error;
 SBJSON *json = [[SBJSON new] autorelease];
 NSArray *luckyNumbers = [json objectWithString:responseString error:&error];
 [responseString release]; 
 
 if (luckyNumbers == nil)
  label.text = [NSString stringWithFormat:@"JSON parsing failed: %@", [error localizedDescription]];
 else {  
  NSMutableString *text = [NSMutableString stringWithString:@"Lucky numbers:\n"];
  
  for (int i = 0; i < [luckyNumbers count]; i++) 
   [text appendFormat:@"%@\n", [luckyNumbers objectAtIndex:i]];

  label.text =  text;
 }
}
Using this method gives us a pointer to the error object of the underlying JSON parser that we can use for more useful error handling.

Tuesday, June 19, 2012

UIView programmatically with rounded corners


  • // don't forget to import quartz core
      

  • #import <QuartzCore/QuartzCore.h>  

  •   

  • // setting up size and position of the UIView  

  • int leftBorder = 20;  

  • int topBorder = 35;  

  • int width = 150;  

  • int height = 160;  

  •   

  • // creating new view  

  • UIView *myView = [[UIView alloc] initWithFrame:CGRectMake(leftBorder, topBorder, width, height)];  

  •   

  • // setting up rounded corners  

  • myView.layer.cornerRadius = 10;  

  •   

  • // setting color for our view  

  • myView.backgroundColor = [UIColor redColor];  

  •   

  • // adding our new view on the  

  • [self.view addSubview:myView];  
  • Sunday, June 17, 2012

    How to send mail using iphone

    - (void)mailComposeController:(MFMailComposeViewController*)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError*)error 
    {
    message.hidden = NO;
    // Notifies users about errors associated with the interface
    //NSLog(result);
    switch (result)
    {
    case MFMailComposeResultCancelled:
    //message.text = @"Result: canceled";
    message.text = @"Composed Mail was canceled";
    break;
    case MFMailComposeResultSaved:
    //message.text = @"Result: saved";
    message.text = @"Mail was saved";
    break;
    case MFMailComposeResultSent:
    //message.text = @"Result: sent";
    message.text = @"Mail sent successfully!";
    break;
    case MFMailComposeResultFailed:
    //message.text = @"Result: failed";
    message.text = @"Failed";
    break;
    default:
    //message.text = @"Result: not sent";
    message.text = @"Mail was not sent";
    break;
    }
    [self dismissModalViewControllerAnimated:YES];
    /*
    MailComposerViewController *dal=[[MailComposerViewController alloc]init];
    [self.navigationController pushViewController:dal animated:YES];
    */
    //Appointment2 *dal=[[Appointment2 alloc]init];
    NSLog(@"Call back");
    //Appointment2 *dal=[[Appointment2 alloc]init];
    //[self.navigationController pushViewController:dal animated:YES];

    NSString *strinfo;
    strinfo=message.text;//[NSString stringWithFormat:message.text];
    UIAlertView *alert = [[UIAlertView alloc] init];
    [alert setTitle:@"INFORMATION"];
    [alert setMessage:strinfo];
    [alert setDelegate:self];
    [alert addButtonWithTitle:@"OK"];
    [alert show];
    [alert release];
    [self.navigationController popViewControllerAnimated:YES];
    }


    this is the delegate method


    Main function is


    MFMailComposeViewController *picker = [[MFMailComposeViewController alloc] init];
    picker.mailComposeDelegate = self;
    [picker setSubject:@""];//Test subject
    // Set up recipients
    NSArray *toRecipients = [NSArray arrayWithObject:ApptNEWOBJ.appMailID]; 
    NSArray *ccRecipients = [NSArray arrayWithObjects: nil]; 
    //NSArray *bccRecipients = [NSArray arrayWithObject:@""]; ///support@therasoftonline.com
    [picker setToRecipients:toRecipients];
    [picker setCcRecipients:ccRecipients];
    //[picker setBccRecipients:bccRecipients];
    // Attach an image to the email
    //NSString *path = [[NSBundle mainBundle] pathForResource:@"rainy" ofType:@"png"];
       // NSData *myData = [NSData dataWithContentsOfFile:path];
    //[picker addAttachmentData:myData mimeType:@"image/png" fileName:@"rainy"];
    // Fill out the email body text
    NSString *emailBody = @"";//Testing Email body!
    [picker setMessageBody:emailBody isHTML:NO];
    [self presentModalViewController:picker animated:YES];
        [picker release];


    Tuesday, June 12, 2012

    How to Check whether Network is available or not

    Header File:



    #import <Foundation/Foundation.h>
    #import <SystemConfiguration/SystemConfiguration.h>
    #import <netinet/in.h>

    typedef enum {
    NotReachable = 0,
    ReachableViaWiFi,
    ReachableViaWWAN
    } NetworkStatus;
    #define kReachabilityChangedNotification @"kNetworkReachabilityChangedNotification"

    @interface Reachability: NSObject
    {
    BOOL localWiFiRef;
    SCNetworkReachabilityRef reachabilityRef;
    }

    //reachabilityWithHostName- Use to check the reachability of a particular host name. 
    + (Reachability*) reachabilityWithHostName: (NSString*) hostName;

    //reachabilityWithAddress- Use to check the reachability of a particular IP address. 
    + (Reachability*) reachabilityWithAddress: (const struct sockaddr_in*) hostAddress;

    //reachabilityForInternetConnection- checks whether the default route is available.  
    //  Should be used by applications that do not connect to a particular host
    + (Reachability*) reachabilityForInternetConnection;

    //reachabilityForLocalWiFi- checks whether a local wifi connection is available.
    + (Reachability*) reachabilityForLocalWiFi;

    //Start listening for reachability notifications on the current run loop
    - (BOOL) startNotifier;
    - (void) stopNotifier;

    - (NetworkStatus) currentReachabilityStatus;
    //WWAN may be available, but not active until a connection has been established.
    //WiFi may require a connection for VPN on Demand.
    - (BOOL) connectionRequired;
    @end



    Implementation File:



    #import <sys/socket.h>
    #import <netinet/in.h>
    #import <netinet6/in6.h>
    #import <arpa/inet.h>
    #import <ifaddrs.h>
    #import <netdb.h>

    #import <CoreFoundation/CoreFoundation.h>

    #import "Reachability.h"

    #define kShouldPrintReachabilityFlags 1

    static void PrintReachabilityFlags(SCNetworkReachabilityFlags    flags, const char* comment)
    {
    #if kShouldPrintReachabilityFlags
        NSLog(@"Reachability Flag Status: %c%c %c%c%c%c%c%c%c %s\n",
    (flags & kSCNetworkReachabilityFlagsIsWWAN)   ? 'W' : '-',
    (flags & kSCNetworkReachabilityFlagsReachable)            ? 'R' : '-',
    (flags & kSCNetworkReachabilityFlagsTransientConnection)  ? 't' : '-',
    (flags & kSCNetworkReachabilityFlagsConnectionRequired)   ? 'c' : '-',
    (flags & kSCNetworkReachabilityFlagsConnectionOnTraffic)  ? 'C' : '-',
    (flags & kSCNetworkReachabilityFlagsInterventionRequired) ? 'i' : '-',
    (flags & kSCNetworkReachabilityFlagsConnectionOnDemand)   ? 'D' : '-',
    (flags & kSCNetworkReachabilityFlagsIsLocalAddress)       ? 'l' : '-',
    (flags & kSCNetworkReachabilityFlagsIsDirect)             ? 'd' : '-',
    comment
    );
    #endif
    }


    @implementation Reachability
    static void ReachabilityCallback(SCNetworkReachabilityRef target, SCNetworkReachabilityFlags flags, void* info)
    {
    #pragma unused (target, flags)
    NSCAssert(info != NULL, @"info was NULL in ReachabilityCallback");
    NSCAssert([(NSObject*) info isKindOfClass: [Reachability class]], @"info was wrong class in ReachabilityCallback");

    //We're on the main RunLoop, so an NSAutoreleasePool is not necessary, but is added defensively
    // in case someon uses the Reachablity object in a different thread.
    NSAutoreleasePool* myPool = [[NSAutoreleasePool alloc] init];
    Reachability* noteObject = (Reachability*) info;
    // Post a notification to notify the client that the network reachability changed.
    [[NSNotificationCenter defaultCenter] postNotificationName: kReachabilityChangedNotification object: noteObject];
    [myPool release];
    }

    - (BOOL) startNotifier
    {
    BOOL retVal = NO;
    SCNetworkReachabilityContext context = {0, self, NULL, NULL, NULL};
    if(SCNetworkReachabilitySetCallback(reachabilityRef, ReachabilityCallback, &context))
    {
    if(SCNetworkReachabilityScheduleWithRunLoop(reachabilityRef, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode))
    {
    retVal = YES;
    }
    }
    return retVal;
    }

    - (void) stopNotifier
    {
    if(reachabilityRef!= NULL)
    {
    SCNetworkReachabilityUnscheduleFromRunLoop(reachabilityRef, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
    }
    }

    - (void) dealloc
    {
    [self stopNotifier];
    if(reachabilityRef!= NULL)
    {
    CFRelease(reachabilityRef);
    }
    [super dealloc];
    }

    + (Reachability*) reachabilityWithHostName: (NSString*) hostName;
    {
    Reachability* retVal = NULL;
    SCNetworkReachabilityRef reachability = SCNetworkReachabilityCreateWithName(NULL, [hostName UTF8String]);
    if(reachability!= NULL)
    {
    retVal= [[[self alloc] init] autorelease];
    if(retVal!= NULL)
    {
    retVal->reachabilityRef = reachability;
    retVal->localWiFiRef = NO;
    }
    }
    return retVal;
    }

    + (Reachability*) reachabilityWithAddress: (const struct sockaddr_in*) hostAddress;
    {
    SCNetworkReachabilityRef reachability = SCNetworkReachabilityCreateWithAddress(kCFAllocatorDefault, (const struct sockaddr*)hostAddress);
    Reachability* retVal = NULL;
    if(reachability!= NULL)
    {
    retVal= [[[self alloc] init] autorelease];
    if(retVal!= NULL)
    {
    retVal->reachabilityRef = reachability;
    retVal->localWiFiRef = NO;
    }
    }
    return retVal;
    }

    + (Reachability*) reachabilityForInternetConnection;
    {
    struct sockaddr_in zeroAddress;
    bzero(&zeroAddress, sizeof(zeroAddress));
    zeroAddress.sin_len = sizeof(zeroAddress);
    zeroAddress.sin_family = AF_INET;
    return [self reachabilityWithAddress: &zeroAddress];
    }

    + (Reachability*) reachabilityForLocalWiFi;
    {
    struct sockaddr_in localWifiAddress;
    bzero(&localWifiAddress, sizeof(localWifiAddress));
    localWifiAddress.sin_len = sizeof(localWifiAddress);
    localWifiAddress.sin_family = AF_INET;
    // IN_LINKLOCALNETNUM is defined in <netinet/in.h> as 169.254.0.0
    localWifiAddress.sin_addr.s_addr = htonl(IN_LINKLOCALNETNUM);
    Reachability* retVal = [self reachabilityWithAddress: &localWifiAddress];
    if(retVal!= NULL)
    {
    retVal->localWiFiRef = YES;
    }
    return retVal;
    }

    #pragma mark Network Flag Handling

    - (NetworkStatus) localWiFiStatusForFlags: (SCNetworkReachabilityFlags) flags
    {
    PrintReachabilityFlags(flags, "localWiFiStatusForFlags");

    BOOL retVal = NotReachable;
    if((flags & kSCNetworkReachabilityFlagsReachable) && (flags & kSCNetworkReachabilityFlagsIsDirect))
    {
    retVal = ReachableViaWiFi;
    }
    return retVal;
    }

    - (NetworkStatus) networkStatusForFlags: (SCNetworkReachabilityFlags) flags
    {
    PrintReachabilityFlags(flags, "networkStatusForFlags");
    if ((flags & kSCNetworkReachabilityFlagsReachable) == 0)
    {
    // if target host is not reachable
    return NotReachable;
    }

    BOOL retVal = NotReachable;
    if ((flags & kSCNetworkReachabilityFlagsConnectionRequired) == 0)
    {
    // if target host is reachable and no connection is required
    //  then we'll assume (for now) that your on Wi-Fi
    retVal = ReachableViaWiFi;
    }
    if ((((flags & kSCNetworkReachabilityFlagsConnectionOnDemand ) != 0) ||
    (flags & kSCNetworkReachabilityFlagsConnectionOnTraffic) != 0))
    {
    // ... and the connection is on-demand (or on-traffic) if the
    //     calling application is using the CFSocketStream or higher APIs

    if ((flags & kSCNetworkReachabilityFlagsInterventionRequired) == 0)
    {
    // ... and no [user] intervention is needed
    retVal = ReachableViaWiFi;
    }
    }
    if ((flags & kSCNetworkReachabilityFlagsIsWWAN) == kSCNetworkReachabilityFlagsIsWWAN)
    {
    // ... but WWAN connections are OK if the calling application
    //     is using the CFNetwork (CFSocketStream?) APIs.
    retVal = ReachableViaWWAN;
    }
    return retVal;
    }

    - (BOOL) connectionRequired;
    {
    NSAssert(reachabilityRef != NULL, @"connectionRequired called with NULL reachabilityRef");
    SCNetworkReachabilityFlags flags;
    if (SCNetworkReachabilityGetFlags(reachabilityRef, &flags))
    {
    return (flags & kSCNetworkReachabilityFlagsConnectionRequired);
    }
    return NO;
    }

    - (NetworkStatus) currentReachabilityStatus
    {
    NSAssert(reachabilityRef != NULL, @"currentNetworkStatus called with NULL reachabilityRef");
    NetworkStatus retVal = NotReachable;
    SCNetworkReachabilityFlags flags;
    if (SCNetworkReachabilityGetFlags(reachabilityRef, &flags))
    {
    if(localWiFiRef)
    {
    retVal = [self localWiFiStatusForFlags: flags];
    }
    else
    {
    retVal = [self networkStatusForFlags: flags];
    }
    }
    return retVal;
    }
    @end




    Call this Function When Needed Like:


        internetReach = [[Reachability reachabilityForInternetConnection] retain];
        NetworkStatus netStatus = [internetReach currentReachabilityStatus];
        if(netStatus != NotReachable)
        {
          
        }
        else{
            
          
        }      
        
        


    Tuesday, June 5, 2012

    Higlight the UI Button

    IBOutlet NSButton * mode1;// declare buttons
    IBOutlet NSButton * mode2;
    - (void)highlightButton1:(UIButton *)a { 
        [mode1 setHighlighted:YES];
        [mode2 setHighlited:NO];
    }
    
    - (void)highlightButton2:(UIButton *)b { 
        [mode1 setHighlighted:NO];
        [mode2 setHighlited:YES];
    }
     
    Loading