Posts Tagged ‘iPhone Apps Development’

Integrating Google oAuth APIs with iPhone Applications

This blog is an effort to round up on how to consume Google’s REST APIs in an iPhone App.  As usual with RESTful APIs, the client specifies an action using an HTTP verb such as POST, GET, PUT, or DELETE and the resource by a globally-unique URI of the following form: https://www.googleapis.com/apiName/apiVersion/resourcePath?parameters The response will be returned by the API in JSON format. The APIs use OAuth 2.0 protocol for authentication and authorization. Google supports several OAuth 2.0 flows that cover common web server, JavaScript, device, installed application, and server to server scenarios. Here we are dealing with installed application on device scenario. Steps to integrate the Google APIs in a normal iOS application are not different than the normal OAuth flow. Register Application: First of all , the application must be registered through Google API console. The result of this registration process is a set of values that are known to both Google and application (e.g. client_id, client_secret, redirect_uri, etc.). The set of values generated varies based on the type of application you are building. Another thing that you need to do is to turn on the APIs that your application needs to access in API Console. Obtain an Access Token from the Google Authorization Server: This is the normal OAuth flow where we need to get the access token to call an API. For authorization call this url, it will show a gmail login window which needs user login credentials:
Parameters Value
response_type code
client_id the client_id obtained from the APIs Console.
redirect_uri the redirect_uri values registered at the APIs Console.
scope space delimited set of permissions the application requests.
state anything
In iPhone, application can fetch authorization code from following code:
NSString *tokenCode
   = [theWebView stringByEvaluatingJavaScriptFromString:@"document.getElementsByTagName('title')[0].innerHTML;"];
Authorization code will be something like “token = tokenValue”. Retrieve the tokenValue and use that to obtain an access token from Google by shooting the post request to following url.
<pre><em id="__mceDel">NSString *url = @"https://accounts.google.com/o/oauth2/token?";
NSString  *data =[NSString stringWithFormat: @"code=%@&client_id=testing.apps.googleusercontent.com&client_secret=OxVwVVgYqvlgjoidgdfghdDv&redirect_uri=urn:ietf:wg:oauth:2.0:oob&grant_type=authorization_code",token];
Response of above url will return the dictionary having token, expire time, refresh token and token type. { “access_token”:”1/fFAGRNJru1FTz70BzhT3Zg”, “expires_in”:<expiry_time>, “token_type”:”Bearer”, “refresh_token”:”1/xEoDL4iW3cxlI7yDbSRFYNG01kVKM2C-259HOF2aQbI” } After obtaining access token above, you are ready to call the Google API for your purpose. Calling Google Api: After application has obtained an access token, application can access a Google API by including it in either an access_token query parameter or an Authorization: Bearer HTTP header. Application can call on those api which are passed as scope in authorization URL. For example, a call to theCalendar API using the access_token query string parameter looks like this: https://www.googleapis.com/calendar/v3/users/me/calendarList?access_token=1/fFAGRNJru1FTz70BzhT3Zg This will return entries on the user’s calendar list. Similarly you can call any other API from the API console which requires an OAuth Token. Enjoy building the cool apps that integrate with Google API !!

Getting HTML elements value from UIWebView

Recently, we came across a problem where we had to fetch some html values from UIWebView. The blog lists source code for extracting a few common elements from UIWebView. The instance method stringByEvaluatingJavaScriptFromString of UIWebView comes in hefty to find such a value.This function will grab the current HTML contents of the view using the Document Object Model, parse the Javascript, then give it to you as an NSString of HTML. Examples To get string from the title of the HTML page:
NSString *currentURL = [theWebView stringByEvaluatingJavaScriptFromString:@"document.getElementsByTagName('title')[0].innerHTML;"];
To get string from class name:
NSString *someHTML = [theWebView stringByEvaluatingJavaScriptFromString:@"document.getElementsByClassName('class name')[0].innerHTML;"];
To get string from element id:
NSString *html = [theWebView stringByEvaluatingJavaScriptFromString:@"document.getElementById('div id').textContent=''"];
theWebView – UIWebView object on which html page is loaded. This approach comes in pretty handy when you want minimal user interaction in some browser savvy process(such as openauth authentication) and hence resulting in a better User Experience. Enjoy the UIWebView awesomeness !!

Implementing Local Notifications in iPhone Applications

Integrating push notifications with iPhone has been really tricky before iOS4.0. You needed to have a dedicated server to push notifications to the applications. However with iOS4.0, Apple introduce the concept of local notificatiions. Local Notifications are a new way to send “push notifications” to your app without having a dedicated server and associated server side coding. Local notifications can be scheduled on the user’s device to fire at any given time; you can even set them to be recurring.The primary purpose of local notifications is to provide a mechanism for a suspended or background application to gain the attention of the user. For example, an audio streaming app might need to notify the user about the loss of network connection or a calendar based application an approaching appointment. The blog details about the coding of delivering a local notification on an iOS device. How To use Local Notification To have iOS deliver a local notification at a later time, an application creates a UILocalNotification object, assigns it a delivery date and time, specifies presentation details, and schedules it. However, make sure you are implementing application:didreceiveLocalNotification in your app delegate if you want to see the notification while your app is in the foreground. Scheduling Notifications
- (IBAction) scheduleAlarm:(id) sender
{
    [eventText resignFirstResponder];

    // Get the current date
    NSDate *pickerDate = [NSDate date];

    // Break the date up into components
    NSDateComponents *dateComponents = [calendar components:( NSYearCalendarUnit | NSMonthCalendarUnit |  NSDayCalendarUnit )
												   fromDate:pickerDate];
    NSDateComponents *timeComponents = [calendar components:( NSHourCalendarUnit | NSMinuteCalendarUnit )
												   fromDate:pickerDate];
    // Set up the fire time
    NSDateComponents *dateComps = [[NSDateComponents alloc] init];
    [dateComps setDay:[dateComponents day]];
    [dateComps setMonth:[dateComponents month]];
    [dateComps setYear:[dateComponents year]];
    [dateComps setHour:[timeComponents hour]]; // Notification will fire in one minute
    [dateComps setMinute:[timeComponents minute]];

    NSDate *itemDate = [calendar dateFromComponents:dateComps];
    [dateComps release];

    UILocalNotification *localNotif = [[UILocalNotification alloc] init];
    if (localNotif == nil)
        return;
    localNotif.fireDate = itemDate;// this sets when notification will be called.
    // Notification details
    localNotif.alertBody = [eventText text];// this shows the alert box with message.
    // Set the action button

    localNotif.alertAction = @"View";
    localNotif.soundName = UILocalNotificationDefaultSoundName;
    localNotif.applicationIconBadgeNumber = 1;
    // Specify custom data for the notification

    NSDictionary *infoDict = [NSDictionary dictionaryWithObject:@"someValue" forKey:@"someKey"];
    localNotif.userInfo = infoDict;
    // Schedule the notification
    [[UIApplication sharedApplication] scheduleLocalNotification:localNotif];
    [localNotif release];
}
In this example we set the notification to the text that the user entered into the text field. InfoDict dictionary is our chance to associate some additional information with the alert. When a local notification is triggered, the option is available to play a sound to gain the user’s attention. If such an audio alert is required the corresponding sound file must be added to the application project resources and must be in Linear PCM, MA4 (IMA/ADPCM), uLaw or aLaw format. If no sound file is specified, the default is for the notification to be silent (though the iPhone device will still vibrate). Handling Notifications After They Fire The last thing is to determine what to do when a notification fires. This step is handled inside of the appDelegate. When a notification fires, there are one of two situations. 1. The app is running and 2. The app is not running (or running in the “background”) . Open up your app delegate .m file and add the following code.
- (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.

    [window addSubview:viewController.view];
    [window makeKeyAndVisible];

  // Handle launching from a notification

    UILocalNotification *localNotif =[launchOptions objectForKey:UIApplicationLaunchOptionsLocalNotificationKey];
    if (localNotif) {
        NSLog(@"Recieved Notification %@",localNotif);
    return YES;
                    }
    -(void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
                    {
  // shows badge value on tab bar
       NSString *badgeValue = [NSString stringWithFormat:@"%d",notifyCount];
       [[[[[self tabBarontroller] tabBar] items] objectAtIndex:2] setBadgeValue:badgeValue];

  //  setting badge value of tab bar as shown below.
       application.applicationIconBadgeNumber = 0;
                    }
The method is invoked when a running application receives a local notification. In this method, we create a string named badgeValue,which contains an integer value from notifyCount variable. We set this badgeValue in the tab bar item which is present at index no 02, which is meetings tab in the provided screenshot.

SQLite Datbase connectivity in iPhone Applications

Database integration is often required in case we want to store some sort of persistent information in the application. The other prominent usage is caching the data for example caching the data from web requests in HTTP request driven applications. SQLITE has been the database of choice on mobile platforms because of his light footprint. In this Blog we explore the basics for integrating SQLLITE with iPhone Native application. Fortunately, MacOS X is shipped with SQLite pre-installed, including an interactive environment for issuing.SQL commands from within a Terminal window. Using SQLite3 database in iphone app, for that we will need to add libsqlite framework in application. Right click on frameworks->Add Existing.

In the search bar type “libsql” and it will show you some 4 frameworks with same name.You have to choose libsqllite, the current version as of this document is 3 so i assume libsqlite3.dylib for the purpose of this blog.

Add SQLite to XCode Project

click on add button to add the framework to project. To create a database you can use terminal or you can use firefox extension for sqlite3 i.e sqlite manager 0.7.7. Creating database using terminal: open terminal and set the path where you want to save database. 1. sqlite3 data.sqlite3 instead of “data” you can use any other name. 2. Create the required tables in SQLite
CREATE TABLE users id INTEGER PRIMARY KEY AUTOINCREMENT, user VARCHAR(255) DEFAULT NULL;
After creating tables, typing in .tables will give you tables in data.sqlite3 database.

Command to see tables in SQLite database

3. Lets do a few sample inserts in the SQLite DB:
INSERT INTO users (user , description) VALUES( 'User1', 'Description 1');
INSERT INTO users (user, description ) VALUES( 'User 2', 'Description 2');
4. Lets retrieve the list of records saved in the SQLite DB.
select * from users;

List Records SQLite

Creating database using sqlite manager: SQLiteManager is a firefox extension that eases the operations with SQLite. Open firefox and download and install sqlite manager 0.7.7. Restart firefox after installing, go to tools and you will see the option for SQLiteManager. Clicking the SQLite option will open a tab which will let you create a new database:

Creating SQLite DB with SQLiteManager

Once database is created, you can create new tables in the database.

clicking on the add button will invoke a popup as shown in the screenshot below.

Create table in SQLite iOS

enter the values and click ok. After records been added it looks like above screenshot. Now we will import the database into our project. Right click on Resources->Add->Existing File and select data sqlite3. This will add data.sqlite3 file into Resources folder. The Coding begins Open up the “User.h” file from the “Classes” folder and edit its contents
#import <UIKit/UIKit.h>

@interface User : NSObject {
	NSString *name; // member variable
	NSString *description;// member variable
	NSString *imageURL; // member variable
}

@property (nonatomic, retain) NSString *name;
@property (nonatomic, retain) NSString *description;
@property (nonatomic, retain) NSString *imageURL;

-(id)initWithName:(NSString *)n description:(NSString *)d url:(NSString *)u;

@end
Lets decode this code a bit. initWithName line, this line will allow you to create a new object with the required data, we could have used the default init function, but it will be easier for us to define our own. Now we will actually have to implement the User Object, open up the “User.m” file and edit its contents
#import "User.h"

@implementation User
@synthesize name, description, imageURL;

-(id)initWithName:(NSString *)n description:(NSString *)d url:(NSString *)u {
	self.name = n;
	self.description = d;
	self.imageURL = u;
	return self;
}
@end
The above code basically stores the supplied data from the initWithName function and return the object (self). Open up the “SQLite3TutorialAppDelegate.h”

#import <UIKit/UIKit.h>
#import  // (if this shows error "no such directory" then you can use #import "/usr/include/sqlite3.h"

// Import the SQLite database framework
@interface SQLiteTutorialAppDelegate : NSObject {
UIWindow *window;
UINavigationController *navigationController;

// Database variables
NSString *databaseName;
NSString *databasePath;

// Array to store the user objects
NSMutableArray *users;
}

@property (nonatomic, retain) IBOutlet UIWindow *window;
@property (nonatomic, retain) IBOutlet UINavigationController *navigationController;
@property (nonatomic, retain) NSMutableArray *users;
@end

// Now open up the “SQLiteTutorialAppDelegate.m”
- (void)applicationDidFinishLaunching:(UIApplication *)application {

// Setup some globals
databaseName = @"data.sqlite3";
// Get the path to the documents directory and append the databaseName
NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDir = [documentPaths objectAtIndex:0];
databasePath = [documentsDir stringByAppendingPathComponent:databaseName];

// Execute the "checkAndCreateDatabase" function
[self checkAndCreateDatabase];

// Query the database for all user records and construct the "users" array
[self readUsersFromDatabase];
// Configure and show the window
[window addSubview:[navigationController view]];
[window makeKeyAndVisible];
}

-(void) checkAndCreateDatabase{

// Check if the SQL database has already been saved to the users phone, if not then copy it over
BOOL success;

// Create a FileManager object, we will use this to check the status
// of the database and to copy it over if required
NSFileManager *fileManager = [NSFileManager defaultManager];

// Check if the database has already been created in the users filesystem
success = [fileManager fileExistsAtPath:databasePath];
// If the database already exists then return without doing anything

if(success) return;
// If not then proceed to copy the database from the application to the users filesystem

// Get the path to the database in the application package
NSString *databasePathFromApp = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:databaseName];

// Copy the database from the package to the users filesystem
[fileManager copyItemAtPath:databasePathFromApp toPath:databasePath error:nil];
[fileManager release];
}

-(void) readUsersFromDatabase {
// Setup the database object
	sqlite3 *database;
	// Init the User Array
	users = [[NSMutableArray alloc] init];

	// Open the database from the users filessystem
	if(sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK) {
		// Setup the SQL Statement and compile it for faster access
		const char *sqlStatement = "select * from users";
		sqlite3_stmt *compiledStatement;
		if(sqlite3_prepare_v2(database, sqlStatement, -1, &compiledStatement, NULL) == SQLITE_OK) {
			// Loop through the results and add them to the feeds array
			while(sqlite3_step(compiledStatement) == SQLITE_ROW) {
				// Read the data from the result row
				NSString *aName = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 1)];
				NSString *aDescription = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 2)];
				NSString *aImageUrl = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 3)];

				// Create a new user object with the data from the database
				User *user = [[user alloc] initWithName:aName description:aDescription url:aImageUrl];

				// Add the user object to the users Array
				[users addObject:user];

				[user release];
			}
		}
		// Release the compiled statement from memory
		sqlite3_finalize(compiledStatement);
	}
	sqlite3_close(database);
}
sqlite3_column_text is used if record is varchar You can use sqlite3_column_int for integer type. For more you can read http://www.sqlite.org/keyword_index.html sqlite3_close.The sqlite3_close() routine is the destructor for the sqlite3 object. Calls to sqlite3_close() return SQLITE_OK if the sqlite3object is successfully destroyed and all associated resources are deallocated. readUsersFromDatabase will fetch all records from users table. Thats it for this tutorial, Enjoy integrating your iPhone apps with SQLite.