<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>iConverged &#187; mobile</title>
	<atom:link href="http://blog.roychowdhury.org/category/mobile/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.roychowdhury.org</link>
	<description></description>
	<lastBuildDate>Thu, 05 Jan 2012 22:06:55 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Thanks Steve</title>
		<link>http://blog.roychowdhury.org/2011/10/07/thanks-steve/</link>
		<comments>http://blog.roychowdhury.org/2011/10/07/thanks-steve/#comments</comments>
		<pubDate>Fri, 07 Oct 2011 12:24:41 +0000</pubDate>
		<dc:creator>Arjun</dc:creator>
				<category><![CDATA[Arjun Roychowdhury]]></category>
		<category><![CDATA[general technology]]></category>
		<category><![CDATA[mobile]]></category>
		<category><![CDATA[osx]]></category>
		<category><![CDATA[world 2.0]]></category>
		<category><![CDATA[iconic]]></category>
		<category><![CDATA[legend]]></category>
		<category><![CDATA[steve jobs]]></category>
		<category><![CDATA[thanks steve]]></category>

		<guid isPermaLink="false">http://blog.roychowdhury.org/?p=648</guid>
		<description><![CDATA[Image tribute designed by Jonathan Mark Even if you never met the man, if his visionary products helped your child to read and write at an early age, let grandparents see their grandchildren across thousands of miles without having to crowd around a computer, led the transformation of the mobile and music industry that pays your salary today, made product companies rethink their priorities towards customers, and most importantly made many of us want to make even a fraction of a dent he has made to this industry and shape our careers accordingly, its not surprising that on his passing you&#8217;d think you knew him very well and to ask yourself &#8216;What do you want to do before you go&#8217;?]]></description>
			<content:encoded><![CDATA[<p><a href="http://blog.roychowdhury.org/wp-content/uploads/2011/10/ht_steve_jobs_apple_jonathan.jpg"><img class="alignnone size-full wp-image-650" title="ht_steve_jobs_apple_jonathan" src="http://blog.roychowdhury.org/wp-content/uploads/2011/10/ht_steve_jobs_apple_jonathan.jpg" alt="" width="478" height="269" /></a></p>
<p><em><span style="color: #888888;">Image tribute designed by <a href="http://jmak.tumblr.com/post/9377189056"> Jonathan Mark</a></span></em></p>
<p>Even if you never met the man, if his visionary products helped your child to read and write at an early age, let grandparents see their grandchildren across thousands of miles without having to crowd around a computer, led the transformation of the mobile and music industry that pays your salary today, made product companies rethink their priorities towards customers, and most importantly made many of us want to make even a fraction of a dent he has made to this industry and shape our careers accordingly, its not surprising that on his passing you&#8217;d think you knew him very well and to ask yourself &#8216;What do you want to do before you go&#8217;?</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.roychowdhury.org/2011/10/07/thanks-steve/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Tutorial: RouteWeather Using Google weather and Driving Directions APIs in your iOS apps</title>
		<link>http://blog.roychowdhury.org/2011/04/06/tutorial-routeweather-using-google-weather-and-driving-directions-apis-in-your-ios-apps/</link>
		<comments>http://blog.roychowdhury.org/2011/04/06/tutorial-routeweather-using-google-weather-and-driving-directions-apis-in-your-ios-apps/#comments</comments>
		<pubDate>Wed, 06 Apr 2011 15:38:01 +0000</pubDate>
		<dc:creator>Arjun</dc:creator>
				<category><![CDATA[Arjun Roychowdhury]]></category>
		<category><![CDATA[general technology]]></category>
		<category><![CDATA[mobile]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[driving directions api]]></category>
		<category><![CDATA[google]]></category>
		<category><![CDATA[ios]]></category>
		<category><![CDATA[route]]></category>
		<category><![CDATA[tutorial]]></category>
		<category><![CDATA[weather api]]></category>

		<guid isPermaLink="false">http://blog.roychowdhury.org/?p=597</guid>
		<description><![CDATA[First off, let me say this: Google&#8217;s terms of service do not allow you to use their APIs for any commercial apps. So it is likely that if you use these APIs, they may never see the light of day in the app store, unless you negotiate a commercial deal with Google. Here is what we will be developing: Let&#8217;s assume you are planning a trip from Bethesda, MD to 90210, CA and you plan to drive (Yeah a road warrior!).  You can get the driving directions from many places, including Google. What you also want is, what &#8220;what is the weather along the route&#8221;. Not only that, you want it for the day you plan to drive (so maybe tomorrow, the day after, or the day after the day after&#8230;) I often need this information. I don&#8217;t drive cross country, but I do drive and knowing the weather along the route and for the day I want to drive is very useful to me. I wish we had an app for that. Well, let&#8217;s not wish, let&#8217;s write one. In the process, you will learn how to: a) Use TBXML for XML parsing b) Use Google Weather and Driving<a href="http://blog.roychowdhury.org/2011/04/06/tutorial-routeweather-using-google-weather-and-driving-directions-apis-in-your-ios-apps/"> <br /><br /> (Read More...)</a>]]></description>
			<content:encoded><![CDATA[<p><em>First off, let me say this: Google&#8217;s terms of service do not allow you to use their APIs for any commercial apps. So it is likely that if you use these APIs, they may never see the light of day in the app store, unless you negotiate a commercial deal with Google.</em></p>
<p>Here is what we will be developing: Let&#8217;s assume you are planning a trip from Bethesda, MD to 90210, CA and you plan to drive (Yeah a road warrior!).  You can get the driving directions from many places, including Google. What you also want is, what &#8220;what is the weather along the route&#8221;. Not only that, you want it for the day you plan to drive (so maybe tomorrow, the day after, or the day after the day after&#8230;)</p>
<p>I often need this information. I don&#8217;t drive cross country, but I do drive and knowing the weather <em> along the route </em>and <em>for the day I want to drive </em>is very useful to me. I wish we had an app for that. Well, let&#8217;s not wish, let&#8217;s write one.</p>
<p>In the process, you will learn how to:</p>
<p>a) Use TBXML for XML parsing</p>
<p>b) Use Google Weather and Driving directions XML data</p>
<p>c) Use segmented controls</p>
<p>d) Use TableViews and custom cells</p>
<p>e) Write an app that brings all of this together</p>
<p><span style="color: #339966;">*** Credits: The fine folks at icodeblog started me off with <a href="http://www.icodeblog.com/2010/09/03/adding-local-weather-conditions-to-your-app-part-12-implementing-corelocation/">this</a> article. ***</span></p>
<p><strong>First the customary screen shots:</strong></p>
<p>First Screen: You enter your from and to and select which day you want the forecast for:</p>
<p><strong><a href="http://blog.roychowdhury.org/wp-content/uploads/2011/04/Screen-shot-2011-04-06-at-11.18.28-AM.png"><img class="alignnone size-full wp-image-598" title="Screen shot 2011-04-06 at 11.18.28 AM" src="http://blog.roychowdhury.org/wp-content/uploads/2011/04/Screen-shot-2011-04-06-at-11.18.28-AM.png" alt="" width="319" height="460" /></a></strong></p>
<p><span id="more-597"></span></p>
<p>Second screen: We use a HUD to tell the user we are doing all the backend magic to get the route weather</p>
<p><strong><a href="http://blog.roychowdhury.org/wp-content/uploads/2011/04/Screen-shot-2011-04-06-at-11.18.45-AM.png"><img class="alignnone size-full wp-image-599" title="Screen shot 2011-04-06 at 11.18.45 AM" src="http://blog.roychowdhury.org/wp-content/uploads/2011/04/Screen-shot-2011-04-06-at-11.18.45-AM.png" alt="" width="318" height="459" /></a></strong></p>
<p>Third screen: We display the results:</p>
<p><a href="http://blog.roychowdhury.org/wp-content/uploads/2011/04/Screen-shot-2011-04-06-at-11.19.11-AM.png"><img class="alignnone size-full wp-image-600" title="Screen shot 2011-04-06 at 11.19.11 AM" src="http://blog.roychowdhury.org/wp-content/uploads/2011/04/Screen-shot-2011-04-06-at-11.19.11-AM.png" alt="" width="319" height="459" /></a></p>
<p><strong>Now lets break up the design and code:</strong></p>
<p>The following files will be explained:</p>
<ul>
<li><strong>DrivingWeatherViewController.h/m</strong>: This is the main program. It is responsible for bringing up the first screen, accept user inputs and then invoke Google&#8217;s secret APIs to get driving directions and weather along the route. It subsequently invokes code in my next bullet point that displays all the retrieved data in a nice, friendly table.</li>
<li><strong>WeatherTable.h/m</strong>: This is responsible for displaying the parsed data in a TableView (The tableview controller is implemented in DrivingWeatherViewController)</li>
<li><strong>CustomCell.h/m</strong>: This is used by WeatherTable to display a custom table cell for each row (if you see the third screen image, you will notice we have 3 sub-rows of data in each TableView Cell along with an image on the right.</li>
<li><strong>WeatherDataClass.h/m</strong>: Just a data structure (wait, they are called Classes) that holds weather information for each location along the driving path. Used by DrivingWeatherViewController</li>
</ul>
<p>I will not be explaining how to use the HUD. For that take a look at my other tutorial <a href="http://blog.roychowdhury.org/2011/04/04/iphone-programming-who-just-called-me/">here</a>.</p>
<p>Now let&#8217;s break up the code. Let&#8217;s target the main code first:</p>
<p><strong>DrivingWeatherViewController.h</strong></p>
<pre class="brush: objc; title: ; notranslate">
//
//  DrivingWeatherViewController.h
//  DrivingWeather
//
//  Created by Arjun on 10/29/10.
//  Copyright 2010 Hughes Systique Corp. All rights reserved.
//

#import &lt;UIKit/UIKit.h&gt;
#import &quot;MBProgressHUD.h&quot;
#import &lt;MapKit/MapKit.h&gt;
</pre>
<p>We are going to use a specific data-structure that is provided by MapKit.h called CLLocationCordinate2D. It is just a convenient structure to store a lat/long value.</p>
<pre class="brush: objc; title: ; notranslate">
@interface DrivingWeatherViewController : UIViewController &lt;MBProgressHUDDelegate&gt;
{

	IBOutlet UITextField *textFrom;
	IBOutlet UITextField *textTo;
	MBProgressHUD *HUD;
	NSString *escapedFrom;
	NSString *escapedTo;
	IBOutlet UIButton *goButton;
	IBOutlet UIButton *tableButton;
	IBOutlet UISegmentedControl *daySegment;
	int day;

}

@property (nonatomic, retain) UITextField *textFrom;
@property (nonatomic, retain) UITextField *textTo;
@property (nonatomic, retain) UIButton *goButton;
@property (nonatomic, retain) UIButton *tableButton;
@property (nonatomic, retain) UISegmentedControl *daySegment;
</pre>
<p>First, since we plan to use MBProgressHUD, we need to implement its Delegate methods. As I indicated earlier, see my tutorial on &#8220;WhoCalledMe&#8221; for more details on MBProgressHUD. Looking at the @interface part, textFrom and textTo are input textfields where the use will enter his source and destination locations. You can be pretty flexible, including adding approximations here. I noticed that the google API is very flexible to abstract input. It accepts all kinds of inputs and also guesses if it can&#8217;t figure out for sure. Fiddle around and test its limits. If the app crashes, then you know that&#8217;s an input Google barfed on :-)</p>
<p>The variable HUD contains the HUD activity indicator. escapedFrom and escapedTo are basically &#8216;sanitized&#8217; versions of the input with properly escaped sequences for special characters. For example, &#8220;Bethesda MD&#8221; needs to become &#8220;Bethesda%20MD&#8221;. This is because we will be passing this as a URI parameter to google and it needs to be properly escaped to be able to do that.</p>
<p>goButton, is, well, when you hit the go Button :-p (sort of like explaining &#8220;i&#8221; in &#8220;for (i=0)&#8221;)</p>
<p>tableButton &#8211; well, as a matter of convenience, I&#8217;ve added a small button at the lower right that displays the last resolved weather condition along a given route. The logic there is that you may want to see it again, and re-computing it everytime is costly. So all you need to do is hit that button, we be show the previous table of weather along the route that was displayed. How thoughtful of me, wouldn&#8217;t you say?</p>
<p>Finally, daySegment (actually day) will contain the day for which you need the weather prediction for. If you notice, I&#8217;ve only allowed for 4 days look ahead. I don&#8217;t remember too well (its been a few months since I wrote this code, and I am positive my brain cells are dying due to which I have memory loss), but I think there may be a limit of how far ahead you can go with the hidden google HTTP API. Maybe I&#8217;ll remember this once I start explaining the .m file.  Or maybe, I just really wanted to use a segmented control because it looked cute and doing more than more made no sense&#8230;</p>
<pre class="brush: objc; title: ; notranslate">

- (IBAction) goPressed: (id)sender;
- (IBAction) tableButtonPressed: (id) sender;
-(IBAction) textFieldDoneEditing:(id)sender;
-(IBAction) backgroundTapped: (id)sender;
- (void) getDrivingWeather;
- (void) displayError: (NSString *)ex;
-(IBAction) segmentedControlIndexChanged;
@end
</pre>
<p>The only explanation I need to put in here are:<br />
a) getDrivingWeather &#8211; the main working function<br />
b) displayError &#8211; just a convenience API to show a Alert message when a parsing error occurs</p>
<p><strong>DrivingWeatherViewController.m</strong></p>
<pre class="brush: objc; title: ; notranslate">
//
//  DrivingWeatherViewController.m
//  DrivingWeather
//
//  Created by Arjun on 10/29/10.
//  Copyright 2010 Hughes Systique Corp. All rights reserved.
//

#import &quot;DrivingWeatherViewController.h&quot;

#import &quot;WeatherTable.h&quot;
#import &quot;DrivingWeatherAppDelegate.h&quot;
#import &quot;WeatherDataClass.h&quot;
#import &quot;MBProgressHUD.h&quot;
#import &quot;TBXML.h&quot;

@implementation DrivingWeatherViewController

@synthesize textFrom, textTo, goButton, tableButton, daySegment;

// MBProgressHUD calls this when the progress bar is over
- (void)hudWasHidden {
	// Remove HUD from screen when the HUD was hidded
	[HUD removeFromSuperview];
	[HUD release];
}
</pre>
<pre class="brush: objc; title: ; notranslate">

// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
	// Set up better looking buttons that the plain white ones that we get by default
	UIImage *buttonImageNormal = [UIImage imageNamed:@&quot;whiteButton.png&quot;];
	UIImage *stretchableButtonImageNormal = [buttonImageNormal stretchableImageWithLeftCapWidth:12  topCapHeight:0];
	[goButton setBackgroundImage:stretchableButtonImageNormal forState:UIControlStateNormal];

	UIImage *buttonImagePressed = [UIImage imageNamed:@&quot;blueButton.png&quot;];
	UIImage *stretchableButtonImagePressed = [buttonImagePressed stretchableImageWithLeftCapWidth:12  topCapHeight:0];
	[goButton setBackgroundImage:stretchableButtonImagePressed forState:UIControlStateHighlighted];

	UIImage *tableButtonNormal = [UIImage imageNamed: @&quot;notepad.png&quot;];
	[tableButton setBackgroundImage:tableButtonNormal forState:UIControlStateNormal];

    [super viewDidLoad];

}
</pre>
<pre class="brush: objc; title: ; notranslate">

-(IBAction) segmentedControlIndexChanged
{
	day = self.daySegment.selectedSegmentIndex;
}

// Just a convenient function to display an alert box

- (void) displayError : (NSString *)ex
{
	UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@&quot;Error&quot; message:[NSString stringWithFormat:@&quot;%@&quot;,ex]
												   delegate:self cancelButtonTitle:@&quot;OK&quot; otherButtonTitles: nil];
	[alert show];
	[alert release];
	return;
}

// This is invoked when the user presses the notepad button on lower right
// Its just a convenient way to re-show the same table that you just saw (incase you want to go back to it)
- (IBAction) tableButtonPressed: (id) sender
{
	WeatherTable *wt = [[WeatherTable alloc] initWithNibName:@&quot;WeatherTable&quot; bundle:[NSBundle mainBundle]];
	[self presentModalViewController:wt animated:YES];
	[wt release];
}
</pre>
<pre class="brush: objc; title: ; notranslate">

// This is invoked when user presses the Go button, which means we need to take the inputs in the text fields
// and process the driving weather parsing
- (IBAction) goPressed: (id)sender
{

	escapedFrom = [[textFrom.text stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding] retain];
	escapedTo = [[textTo.text stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding] retain];
</pre>
<pre class="brush: objc; title: ; notranslate">

	NSLog (@&quot;From:%@ To:%@&quot;,escapedFrom, escapedTo);

	// Now lets show a progress dialog, since parsing all lat/long and geocoding takes time
	HUD = [[MBProgressHUD alloc] initWithWindow:[UIApplication sharedApplication].keyWindow];
	HUD.mode = MBProgressHUDModeDeterminate;

	// Add HUD to screen
	[self.view.window addSubview:HUD];

	// Regisete for HUD callbacks so we can remove it from the window at the right time
	HUD.delegate = self;

	HUD.labelText = @&quot;Working...&quot;;

	// Show the HUD while the provided method executes in a new thread
	NSLog (@&quot;Just before showWhileExecuting&quot;);
	[HUD showWhileExecuting:@selector(getDrivingWeather) onTarget:self withObject:nil animated:YES];

}
</pre>
<pre class="brush: objc; title: ; notranslate">

// This is the main function. goPressed calls this to actually start the entire XML GET/parse etc.
- (void) getDrivingWeather
{

	CLLocationCoordinate2D coord[200]; // This should really be an NSArray...
	NSLog (@&quot;Inside getDrivingWeather&quot;);

	NSString *drivingURI= [[NSString alloc] initWithFormat:@&quot;http://maps.googleapis.com/maps/api/directions/xml?origin=%@&amp;destination=%@&amp;sensor=false&quot;,escapedFrom,escapedTo] ;

	[escapedTo release];
	[escapedFrom release];

	float progress=0.0f;
	float progressincr=0.0f;

	HUD.labelText = @&quot;Getting Directions&quot;;
	NSLog(@&quot;Google Driving URI is %@&quot;,drivingURI);
</pre>
<p>drivingURI is the base URL string that we need to invoke for Google to return the XML response (explained below). So we are setting up here &#8211; we display a HUD saying we are working on it, and then plan to pass the from and to values to this URL and fetch the responses (explained later).</p>
<p><strong> A Diversion: Let&#8217;s first understand the XML format returned by Google&#8217;s driving directions APIs </strong></p>
<p>Let&#8217;s analyze the output of the following REST URL invocation:</p>
<pre class="brush: plain; title: ; notranslate">

http://maps.googleapis.com/maps/api/directions/xml?origin=20876&#038;destination=21704@&#038;sensor=false
</pre>
<p>Here is a fragment of the output:<br />
<a href="http://blog.roychowdhury.org/wp-content/uploads/2011/04/routeXML.png"><img class="alignnone size-full wp-image-606" title="routeXML" src="http://blog.roychowdhury.org/wp-content/uploads/2011/04/routeXML.png" alt="" width="560" height="466" /></a></p>
<p>The output is organized as so:<br />
a) The entire directions is encapsulated in a&lt;route&gt;  tag<br />
b) Each &#8216;via point&#8217; is encapsulated in a  &lt;leg&gt; tag (in our app, there will only be one &#8216;leg&#8217; of the journey &#8211; from start to finish. If you instead did A to B to C, then A-B would be one leg and B-C the other.<br />
c) Next, each leg has many &#8216;steps&#8217;. Each step is one instruction (example, step 1: Take left on &#8216;Foo&#8217;. Step 2: Take right on &#8216;Moo&#8217;)<br />
d) Inside each step, you have a lat/long for the starting and ending point.<br />
e) There other tags, you can explore &#8211; easy to understand</p>
<p>What is our strategy:</p>
<ol>
<li>Iterate through this list and get to the lat/long values</li>
<li>Next, pass the lat/longs to another google API to return weather conditions</li>
<li>Next, convert the lat/longs to city names  so it can be displayed (If you know someone who sees a dump of weather and lat/long and finds it useful, you know a massive nerd)</li>
<li>Next, eliminate repeated cities (for example, there may be 5 steps within a single city or zip code)</li>
<li>Display it all in a nice way, including the weather icon pictorially showing the prediction (part of the weather API output from google)</li>
</ol>
<p>Okay, now that you understand the structure and our strategy, lets get into execution</p>
<pre class="brush: objc; title: ; notranslate">

	DrivingWeatherAppDelegate *appDelegate = (DrivingWeatherAppDelegate *)[[UIApplication sharedApplication] delegate];

	// Each time we call this API, we need to clear the past table. Easy way is to free it and re-alloc it
	// I suppose I really should be just deleting all rows..
	[appDelegate.drivingWeatherArray release];
	appDelegate.drivingWeatherArray = [[NSMutableArray alloc] init];

	// Get the XML document that returns full driving directions
	TBXML *directionsParser = [[TBXML alloc] initWithURL:[NSURL URLWithString:drivingURI]];

	[drivingURI release];

	if (directionsParser == nil)
	{
		[self displayError:@&quot;Error getting driving directions. Try again, or check your input.&quot;];
		return;
	}
</pre>
<p>The appDelegate variable is just a convenient method for us to exchange data between different classes. It may not be a good design practice, but heck, good design requires intelligent thinking and I&#8217;m just slapping code together here. I don&#8217;t claim to be an intelligent thinker. Basically, drivingWeatherArray will contain the parsed weather conditions for the route and it will be shared between this class and the WeatherTable class.</p>
<p>So here, we initialize the array, and then use an excellent open source, fast XML parser for iOS called <a href="http://www.tbxml.co.uk/TBXML/TBXML_Free.html">TBXML</a>. We pass it the driving directions URL that was composed using the base URL and the user input. the TBXML initWithURL instantiates a TBXML object, fetches the data in that URL and returns it to the directionParser variable. We now need to walk the XML chain from here.</p>
<p>TBXML is super easy to use and its instructions are really really simple. If you can&#8217;t figure out how to use it from my code, go to their <a href="http://www.tbxml.co.uk/TBXML/TBXML_Free.html">website</a> and read about it.</p>
<pre class="brush: objc; title: ; notranslate">
	HUD.labelText = @&quot;Parsing locations&quot;;

	TBXMLElement *routeLegStep = directionsParser.rootXMLElement;
	routeLegStep = [TBXML childElementNamed:@&quot;route&quot; parentElement:routeLegStep];
	routeLegStep = [TBXML childElementNamed:@&quot;leg&quot; parentElement:routeLegStep];
	routeLegStep = [TBXML childElementNamed:@&quot;step&quot; parentElement:routeLegStep];
	int cnt=0;

	while (routeLegStep)
	{
		TBXMLElement *start_location = [TBXML childElementNamed:@&quot;start_location&quot; parentElement:routeLegStep];
		TBXMLElement *lat_node = [TBXML childElementNamed:@&quot;lat&quot; parentElement:start_location];
		TBXMLElement *long_node = [TBXML childElementNamed:@&quot;lng&quot; parentElement:start_location];

		NSLog (@&quot;TBXML GOT Lat:%@ Long:%@&quot;, [TBXML textForElement:lat_node], [TBXML textForElement:long_node]);
		coord[cnt].latitude=[[TBXML textForElement:lat_node] doubleValue];
		coord[cnt].longitude=[[TBXML textForElement:long_node] doubleValue];
		cnt++;

		TBXMLElement *end_location = [TBXML childElementNamed:@&quot;end_location&quot; parentElement:routeLegStep];
		lat_node = [TBXML childElementNamed:@&quot;lat&quot; parentElement:end_location];
		long_node = [TBXML childElementNamed:@&quot;lng&quot; parentElement:end_location];
		NSLog (@&quot;TBXML GOT Lat:%@ Long:%@&quot;, [TBXML textForElement:lat_node], [TBXML textForElement:long_node]);

		coord[cnt].latitude=[[TBXML textForElement:lat_node] doubleValue];
		coord[cnt].longitude=[[TBXML textForElement:long_node] doubleValue];
		cnt++;

		routeLegStep =[TBXML nextSiblingNamed:@&quot;step&quot; searchFromElement:routeLegStep];

	}
	[directionsParser release];
</pre>
<p>Next up, now that we have a XML document with the entire driving directions, we need to navigate down to the &#8220;route&#8221; tag, then get to the &#8220;leg&#8221; tag within in and then iterate though each &#8220;step&#8221; tag within it. Note that I&#8217;ve taken shortcuts &#8211; I know for sure there will only be one &#8220;leg&#8221; tag, so I don&#8217;t bother looking for others. I just focus on the series of &#8220;step&#8221; tags inside the one &#8220;leg&#8221; tag. Once I have the starting pointer to the first &#8220;step&#8221;, I iterate till I reach the end. For each iteration, I get the &#8216;lat/long&#8217; for the start location as well as the &#8216;lat/long&#8217; for the end location. Obviously, there will be many lat/longs for one &#8216;city&#8217; or &#8216;zip&#8217; and we need to filter them out. We will do all that later.<br />
For now, we use TBXML to quickly iterate through all the start/stop lat longs and stuff them into a &#8220;coord&#8221; array. That&#8217;s all we need from the directions XML response. A list of lat-longs along the driving route. Now let&#8217;s get to the google weather APIs to work the next part of the magic.</p>
<pre class="brush: objc; title: ; notranslate">
NSLog (@&quot;TOTAL LATLONG %d&quot;, cnt);
NSLog (@&quot;Now getting weather for each LATLONG&quot;);

// This is used to update the progress pie. Basically, for each &quot;cnt&quot; (i.e. total list of lat/long)
// we are doing two network operations (weather, geocode). So we increment progress accordigly so it reaches
// 1 after 2*cnt operations are completed. MBProgressHUD class considers 1 to be complete.
progressincr = 1.0f/(2.0f*cnt);

// For each lat/long, we need to call the google weather API
// and then also call google geocode API
for (int i=0; i&amp;lt; cnt; i++)
{

HUD.labelText=[NSString stringWithFormat:@&quot;Getting Weather (%d of %d)&quot;,i+1,cnt];
NSString *myLatString=[NSString stringWithFormat:@&quot;%f&quot;, coord[i].latitude];
NSString *myLongString=[NSString stringWithFormat:@&quot;%f&quot;, coord[i].longitude];

myLatString = [myLatString stringByReplacingOccurrencesOfString:@&quot;.&quot; withString:@&quot;&quot;];
myLongString = [myLongString stringByReplacingOccurrencesOfString:@&quot;.&quot; withString:@&quot;&quot;];

NSString *weathercoord, *revgeocode;
weathercoord = [NSString stringWithFormat:@&quot;http://www.google.com/ig/api?weather=,,,%@,%@&quot;, myLatString, myLongString];

NSLog(@&quot;Google Weather URI:%@&quot;,weathercoord);
</pre>
<p>For each lat/long in our array, we need to pass that lat/long to the google weather API URL to get its weather. This is a time consuming operation, so we display a HUD. We also use a Pie-chart HUD display that MBProgressHUD offers so the user can visually see how much more of parsing is left (Just as one example, driving from MD to CA involves 84 different steps, which means we have to call the weather API 84 times, plus, reverseGeoCode API (coming up later) another 84 times to get city names.</p>
<p>So really, the pie chart doesn&#8217;t just look cool. It serves a purpose.</p>
<p>The variable weathercoord contains the google weather API URL along with the lat/long we need data for.</p>
<p>Also, the XML URL does not accept &#8220;decimal points&#8221; in the lat/long. All you need to do is remove it and it works fine (discovered by some blogger &#8211; I don&#8217;t have the reference now)</p>
<p><strong>Diversion: Understanding the Weather XML data</strong></p>
<p>Here is an example of the output for http://www.google.com/ig/api?weather=,,,39341250,-77366200</p>
<p><a href="http://blog.roychowdhury.org/wp-content/uploads/2011/04/weather.png"><img class="alignnone size-full wp-image-610" title="weather" src="http://blog.roychowdhury.org/wp-content/uploads/2011/04/weather.png" alt="" width="520" height="751" /></a></p>
<p>Lets understand first on how we need to parse it and then go to the code. It&#8217;s very simple. First there is a &#8220;current_conditions&#8221; tag that tells you what is the current temperature at that lat/long. Next, there are &#8220;forecast_conditions&#8221; tags that tell you what is the expected low and high for the next 4 days (Aha! so that explains why I only let you select upto 4 days ahead. My ailing memory came back). Simple! One more thing &#8211; it also gives you a link to an image that pictorially shows the weather condition too. Now that&#8217;s some jazz that would look good&#8230;</p>
<p><strong>Okay back to the code:</strong></p>
<pre class="brush: objc; title: ; notranslate">
TBXML *weatherParser = [[TBXML alloc] initWithURL:[NSURL URLWithString:weathercoord]];
if (weatherParser == nil)
{
NSLog(@&quot;Error parsing Weather URL for lat:%f, long:%f&quot;,coord[i].latitude, coord[i].longitude);
continue;
}

progress += progressincr;
HUD.progress = progress;

WeatherDataClass *wdc;
wdc = [[WeatherDataClass alloc] init]; // just alloc wdc object. member functions will retain memory from NSString below
</pre>
<p><span style="font-family: Consolas, Monaco, 'Courier New', Courier, monospace; line-height: 18px; white-space: pre;"> </span></p>
<pre class="brush: objc; title: ; notranslate">&lt;/span&gt;
&lt;pre&gt;@try
{

wdc.longitude = [[NSString stringWithFormat:@&quot;%f&quot;, coord[i].longitude] retain];
wdc.latitude = [[NSString stringWithFormat:@&quot;%f&quot;, coord[i].latitude] retain];

TBXMLElement *myElement = weatherParser.rootXMLElement;
TBXMLElement *myChild;

myElement = [TBXML childElementNamed:@&quot;weather&quot;  parentElement:myElement];

// first check if there is a tag called problem_cause_data. If it is, there was an error in the XML

TBXMLElement *problemData = [TBXML childElementNamed:@&quot;problem_cause_data&quot; parentElement:myElement];

if (problemData) // yes it found it
{
NSLog(@&quot;(Problem_cause reported) Error parsing Weather URL for lat:%f, long:%f&quot;,coord[i].latitude, coord[i].longitude);
continue;

}
</pre>
<p>Like before, we use the trusty TBXML class to walk though the XML API we explained before. A minor nit &#8211; before you parse, look for a tag called &#8220;problem_cause_data&#8221; &#8211; if it is part of the XML, parsing failed. So before we burn and crash, check it first. If it was returned, something got foo bar&#8217;d.</p>
<pre class="brush: objc; title: ; notranslate">

// if it comes here, I think the XML should have everything

// now check what is the value of day. If it is 0, then look at current_conditions
// else iterate forecast_conditions

// Now get the date as well
NSString *forecast_day=@&quot;Unknown&quot;;
if (day==0)
{
myElement = [TBXML childElementNamed:@&quot;current_conditions&quot;  parentElement:myElement];
//[forecast_day release];
forecast_day=@&quot;Today&quot;;
//forecast_day=[[NSString alloc] initWthString:@&quot;Today&quot;];
NSLog(@&quot;Today&quot;);
}
else
{
myElement = [TBXML childElementNamed:@&quot;forecast_conditions&quot;  parentElement:myElement];
NSLog(@&quot;Next Day&quot;);
for (int i=0; i&amp;lt;day-1; i++)

{
NSLog(@&quot;Next Day&quot;);
if (myElement) {myElement =[TBXML nextSiblingNamed:@&quot;forecast_conditions&quot; searchFromElement:myElement];}

}
if (i==0)
{
TBXMLElement *mDayOfWeek = [TBXML childElementNamed:@&quot;day_of_week&quot; parentElement:myElement];
if (mDayOfWeek)
{
//[forecast_day release];
forecast_day = [[TBXML valueOfAttributeNamed:@&quot;data&quot; forElement:mDayOfWeek] retain];
}
} // i==0
} //else
</pre>
<p>Now we need to figure out which weather data is of interest to us. That depends on what day the user selected in the segmented control (day variable). If the user selected &#8220;Today&#8221; then we need to parse the &#8220;current_conditions&#8221; tag. If not, then we need to walk through the &#8220;forecast_conditions&#8221; tags, once for each day ahead chosen.</p>
<pre class="brush: objc; title: ; notranslate">
if (i==0)
{
[appDelegate.drivingWeatherArray addObject:[NSString stringWithFormat:@&quot;Weather Forecast is for %@&quot;, forecast_day]];
}
//[forecast_day release];

myChild = [TBXML childElementNamed:@&quot;condition&quot;  parentElement:myElement];
if (myChild) {wdc.condition = [[TBXML valueOfAttributeNamed:@&quot;data&quot; forElement:myChild] retain];}
NSLog(@&quot;TBXML GOT condition:%@&quot;,wdc.condition);

myChild = [TBXML childElementNamed:@&quot;temp_f&quot;  parentElement:myElement];
if (myChild) {wdc.curtemp = [[TBXML valueOfAttributeNamed:@&quot;data&quot; forElement:myChild] retain];}
NSLog(@&quot;TBXML GOT curtemp:%@&quot;,wdc.curtemp);

myChild = [TBXML childElementNamed:@&quot;low&quot;  parentElement:myElement];
if (myChild) {wdc.lowtemp = [[TBXML valueOfAttributeNamed:@&quot;data&quot; forElement:myChild] retain];}
NSLog(@&quot;TBXML GOT lowtemp:%@&quot;,wdc.lowtemp);

myChild = [TBXML childElementNamed:@&quot;high&quot;  parentElement:myElement];
if (myChild) {wdc.hitemp = [[TBXML valueOfAttributeNamed:@&quot;data&quot; forElement:myChild] retain];}
NSLog(@&quot;TBXML GOT hitemp:%@&quot;,wdc.hitemp);

myChild = [TBXML childElementNamed:@&quot;icon&quot;  parentElement:myElement];
if (myChild) {wdc.url = [[NSString stringWithFormat:@&quot;http://www.google.com%@&quot;, [TBXML valueOfAttributeNamed:@&quot;data&quot; forElement:myChild]]retain]   ;}
NSLog(@&quot;TBXML GOT url:%@&quot;,wdc.url);
}
@catch (NSException *ex)
{
[self displayError:@&quot;Error parsing Weather. Try again or check input&quot;];
NSLog(@&quot;Error:%@&quot;,ex);
return;
}
</pre>
<p>Right, so  the code above walks through the XML and picks up the current temperature ( if current day is chosen), or, the forecast high and low for a forecast day. We also pick up the image URL (its in the &#8220;icon&#8221; tag in the XML output). All of this goes into a data structure (wdc) for use later.</p>
<pre class="brush: objc; title: ; notranslate">

revgeocode = [NSString stringWithFormat:@&quot;http://maps.google.com/maps/api/geocode/xml?latlng=%f,%f&amp;amp;amp;sensor=true&quot;, coord[i].latitude, coord[i].longitude];
NSLog (@&quot;GOOGLE GEOCODE URI:%@&quot;,revgeocode);
</pre>
<p>Finished! Now lets populate the table! Oh wait. One more thing. Our last operation is to convert all the lat/longs to cities and zipcodes, and then filter our repeating zip codes (I could have chosen to remove repeating cities, but my assumption is if zip changes, it may be far enough for weather to change). So here, we use the google geocode API, pass it a lat long and hope to get some human understandable city/zip in return</p>
<p>For this one, I am not going to explain the XML output in detail. It is a little voluminous. Take a look at the output for</p>
<pre class="brush: plain; title: ; notranslate">

http://maps.google.com/maps/api/geocode/xml?latlng=39.341250,-77.366200&#038;sensor=true
</pre>
<p>as an example. Suffice to say, what we are looking for is the &#8220;postal_code&#8221; tag with a &#8220;formatted_address&#8221; tag inside it. Thats the value we want to display. So the next piece of code walks this chain and looks for it.</p>
<pre class="brush: objc; title: ; notranslate">

TBXML *geocodeParser;
@try
{
geocodeParser = [[TBXML alloc] initWithURL:[NSURL URLWithString:revgeocode]];

if (!geocodeParser) { [self displayError:@&quot;Failed to get Google GeoCode XML!&quot;]; [wdc release]; continue; }

TBXMLElement * rootXMLElement = geocodeParser.rootXMLElement;
if (!rootXMLElement) { NSLog(@&quot;Error:Failed to get Root of Google GeoCode XML!&quot;); [geocodeParser release];[wdc release]; continue; }

TBXMLElement *resultElement = [TBXML childElementNamed:@&quot;result&quot;  parentElement:rootXMLElement];
if (!resultElement) { NSLog(@&quot;Error:Failed to get result tag. Continuing.&quot;); [geocodeParser release]; [wdc release];continue; }

TBXMLElement *typeElement = [TBXML childElementNamed:@&quot;type&quot; parentElement:resultElement];
if (!typeElement) { NSLog(@&quot;Error:Failed to get type tag&quot;); [geocodeParser release]; [wdc release]; continue; }

NSString *type_text = [TBXML textForElement:typeElement];
if (!type_text) { NSLog(@&quot;Error:Failed to get text of type tag (odd)&quot;); [geocodeParser release]; [wdc release]; continue; }

while (  (resultElement) &amp;amp;&amp;amp;  ( !([type_text isEqualToString:@&quot;postal_code&quot;]) ) )
{
resultElement = [TBXML nextSiblingNamed:@&quot;result&quot; searchFromElement:resultElement];
if (resultElement)
{
typeElement = [TBXML childElementNamed:@&quot;type&quot; parentElement:resultElement];
type_text = [TBXML textForElement:typeElement];
}
else
{
typeElement=nil;
type_text=nil;
}

NSLog(@&quot;TYPE IS:%@&quot;,type_text);
}

if (resultElement) // you got to the area which has address
{
TBXMLElement *address=[TBXML childElementNamed:@&quot;formatted_address&quot; parentElement:resultElement];
if (address) { wdc.city = [TBXML textForElement:address]; NSLog (@&quot;GOT Geocode %@&quot;,wdc.city);}
}
progress += progressincr;
HUD.progress = progress;
[geocodeParser release];
}
@catch (NSException *ex)
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@&quot;TBXML Error&quot; message:[NSString stringWithFormat:@&quot;%@&quot;,ex]
delegate:self cancelButtonTitle:@&quot;OK&quot; otherButtonTitles: nil];
[alert show];
[alert release];
return;
}
</pre>
<p>Right, now we have the city and zip for that lat long.</p>
<pre class="brush: objc; title: ; notranslate">

/* Now, iterate through the weather array and and check if city was already added. We can't do it before because different lat/longs map
to the same cities. So we first need to get all the latlongs and then compare the resultant city returned by the google geocode api */

int match=0;

if (wdc.city)
{
NSLog(@&quot;**********************************************************&quot;);
for (int ndx=1; ndx&amp;lt;[appDelegate.drivingWeatherArray count]; ndx++) // start at 1, as 0 has header info
{
WeatherDataClass *w = [appDelegate.drivingWeatherArray objectAtIndex:ndx];

if ([w.city isEqualToString:wdc.city])
{
match=1;
}

} // for array match
if (!match)
{
[appDelegate.drivingWeatherArray addObject:wdc];
}
[wdc release];
}
} // for

HUD.progress=1;

WeatherTable *wt = [[WeatherTable alloc] initWithNibName:@&quot;WeatherTable&quot; bundle:[NSBundle mainBundle]];
[self presentModalViewController:wt animated:YES];
[wt release];

}
</pre>
<p>What we now do here is check the drivingWeatherArray object to see if this city+zip is already part of our list. If it is, its a repeat, so just skip and don&#8217;t add, else add to the object array.</p>
<p>And finally, display all of that data in a nice TableView. Done!</p>
<pre class="brush: objc; title: ; notranslate">

// used to make keyboard disappear

-(IBAction) textFieldDoneEditing:(id)sender
{
[sender resignFirstResponder];
}

-(IBAction) backgroundTapped:(id)sender;
{
[textTo resignFirstResponder];
[textFrom resignFirstResponder];
}

/*
// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
*/

- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
NSLog (@&quot;******MEMORY WARNING***********&quot;);
[super didReceiveMemoryWarning];

// Release any cached data, images, etc that aren't in use.
}

- (void)viewDidUnload {
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}

- (void)dealloc {

[textFrom release];
[textTo release];
[escapedFrom release];
[escapedTo release];
[tableButton release];
[daySegment release];

[super dealloc];
}

@end
</pre>
<p>The &#8220;remaining tail&#8221; of the main code &#8211; usual iphone skeleton code.</p>
<p><strong> WeatherTable.h</strong></p>
<pre class="brush: objc; title: ; notranslate">
//
//  WeatherTable.h
//  DrivingWeather
//
//  Created by Arjun on 10/31/10.
//  Copyright 2010 Hughes Systique Corp. All rights reserved.
//

#import &lt;UIKit/UIKit.h&gt;
@interface WeatherTable : UIViewController &lt;UITableViewDataSource, UITableViewDelegate&gt;{
	IBOutlet UITableView *weatherTableView;
	IBOutlet UIButton *doneButton;

}

@property (nonatomic, retain) UITableView *weatherTableView;
@property (nonatomic, retain) UIButton *doneButton;

-(IBAction) done: (id) sender;

@end
</pre>
<p>Nothing much &#8211; a standard TableView implementation&#8230;</p>
<p><strong>WeatherTable.m</strong></p>
<p>This class displays the parsed weather along your driving route in a nice table</p>
<pre class="brush: objc; title: ; notranslate">
//
//  WeatherTable.m
//  DrivingWeather
//
//  Created by Arjun on 10/31/10.
//  Copyright 2010 Hughes Systique Corp. All rights reserved.
//

#import &quot;WeatherTable.h&quot;
#import &quot;CustomCell.h&quot;
#import &quot;DrivingWeatherAppDelegate.h&quot;
#import &quot;WeatherDataClass.h&quot;

@implementation WeatherTable

@synthesize weatherTableView;
@synthesize doneButton;

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
	DrivingWeatherAppDelegate *appDelegate = (DrivingWeatherAppDelegate *)[[UIApplication sharedApplication] delegate];
	return [appDelegate.drivingWeatherArray count];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
	DrivingWeatherAppDelegate *appDelegate = (DrivingWeatherAppDelegate *)[[UIApplication sharedApplication] delegate];
	static NSString *CustomCellIdentifier=@&quot;CustomCellIdentifier&quot;;
		NSUInteger row = [indexPath row];
CustomCell *cell;
</pre>
<p>We are using a pointer to the appDelegate class to share the driving list Array between the two classes as explained earlier.<br />
Also, each row of the Table will be filled with a custom cell which will accomodate an image and two rows of data.</p>
<pre class="brush: objc; title: ; notranslate">
	/* First row is special - I display forecast day, copyrights etc, so handle differently */
	if (row==0)
	{
		cell=(CustomCell *) [tableView dequeueReusableCellWithIdentifier:@&quot;HeaderCell&quot;];
		if (cell==nil)
		{
			NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@&quot;CustomCell&quot; owner:self options:nil];
			cell = [nib objectAtIndex:0];
		}

		cell.cityLabel.text = [appDelegate.drivingWeatherArray objectAtIndex:row];
		cell.forecastLabel.text=@&quot;All data \u00A9 Google,inc.&quot;;
		//[cell.forecastLabel setFont:[UIFont fontWithName:@&quot;Arial-BoldMT&quot; size:18]];
		cell.imageView.image = [UIImage imageNamed:@&quot;icon.png&quot;];

	}
	else
	{

		cell=(CustomCell *) [tableView dequeueReusableCellWithIdentifier:CustomCellIdentifier];
		if (cell==nil)
		{
			NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@&quot;CustomCell&quot; owner:self options:nil];
			cell = [nib objectAtIndex:0];
		}
</pre>
<p>If you look at my sample screenshot for the results screen, the first row is &#8220;special&#8221; &#8211; it displays a copyright message attributing the data to google and my app icon. So we need to ensure that we use a different identifier in &#8220;dequeueReusableCellWithIdentifier&#8221;. If we did not, then iphone will start sharing memory of that row with other rows. that will mess up formatting the moment you scroll around because it will overwrite formatting data of the header row with the other rows (since you told it that it can be reused if needed)  &#8211; try it out. So we keep them separate.</p>
<pre class="brush: objc; title: ; notranslate">

		WeatherDataClass *wdc= [appDelegate.drivingWeatherArray objectAtIndex:row];
		NSString *weathertext;
		NSString *nowtext, *lowtext, *hitext;
		nowtext=@&quot;&quot;;
		lowtext=@&quot;&quot;;
		hitext=@&quot;&quot;;

		/* When you get weather from google, it shows current temperature for &quot;today&quot; but no high and low
		   Similarly, if you ask for temperature for other days (+1 to +4 days from today), it shows high and low
		   but current does not make sense, as it is future. So here, I just present stuff I get while keeping the null
		   values from being displayed. \xC2\xB0 is hex for the degree symbol
		*/

		if (wdc.curtemp) { nowtext = [NSString stringWithFormat:@&quot;Now:%@\xC2\xB0 F&quot;,wdc.curtemp];}
		if (wdc.lowtemp) { lowtext = [NSString stringWithFormat:@&quot;Low:%@\xC2\xB0 F&quot;,wdc.lowtemp];}
		if (wdc.hitemp)  { hitext = [NSString stringWithFormat:@&quot;High:%@\xC2\xB0 F&quot;,wdc.hitemp];}

		weathertext= [NSString stringWithFormat:@&quot;%@ %@ %@&quot;,nowtext,lowtext,hitext];
		cell.cityLabel.text = wdc.city;
		cell.temperatureLabel.text = weathertext;
		cell.forecastLabel.text = wdc.condition;

		NSString* imageURL = wdc.url;
		NSLog(@&quot;IMAGE URL:%@&quot;,wdc.url);
		NSData* imageData = [[NSData alloc]initWithContentsOfURL:[NSURL URLWithString:imageURL]];

		UIImage* image = [[UIImage alloc] initWithData:imageData];
		[cell.imageView setImage:image];
		[imageData release];
		[image release];
	}
	return cell;

}
</pre>
<p>Next up, we iterate through the drivingWeather Array and set the table cell fields to the right values. Loose explanation, but I think its pretty simple what is going on up here.</p>
<pre class="brush: objc; title: ; notranslate">

// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
	UIImage *buttonImageNormal = [UIImage imageNamed:@&quot;whiteButton.png&quot;];
	UIImage *stretchableButtonImageNormal = [buttonImageNormal stretchableImageWithLeftCapWidth:12  topCapHeight:0];
	[doneButton setBackgroundImage:stretchableButtonImageNormal forState:UIControlStateNormal];

	UIImage *buttonImagePressed = [UIImage imageNamed:@&quot;blueButton.png&quot;];
	UIImage *stretchableButtonImagePressed = [buttonImagePressed stretchableImageWithLeftCapWidth:12  topCapHeight:0];
	[doneButton setBackgroundImage:stretchableButtonImagePressed forState:UIControlStateHighlighted];

    [super viewDidLoad];

}

-(IBAction) done:(id) sender {
	[self.parentViewController dismissModalViewControllerAnimated:YES];
}

- (void)didReceiveMemoryWarning {
    // Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];

    // Release any cached data, images, etc that aren't in use.
}

- (void)viewDidUnload {
    [super viewDidUnload];
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
}

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

@end
</pre>
<p>No explanation needed above -standard stuff.</p>
<p><strong> CustomCell.h and .m </strong></p>
<p>.h:</p>
<pre class="brush: objc; title: ; notranslate">
//
//  CustomCell.h
//
//
//  Created by Arjun on 9/29/10.
//  Copyright 2010 Hughes Systique Corp. All rights reserved.
//

#import &lt;UIKit/UIKit.h&gt;

// This defines how each cell of the table will look

@interface CustomCell : UITableViewCell {
	IBOutlet UILabel *cityLabel;
	IBOutlet UILabel *forecastLabel;
	IBOutlet UILabel *temperatureLabel;
	IBOutlet UIImageView *imageView;

}
@property (nonatomic, retain) UILabel *cityLabel;
@property (nonatomic, retain) UILabel *forecastLabel;
@property (nonatomic, retain) UILabel *temperatureLabel;
@property (nonatomic, retain) UIImageView *imageView;

@end
</pre>
<p>CustomCell is a XIB file I created in Interface Builder. It has a label to display the city, forecast, temperature and an imageview to show the weather icon.</p>
<p>.m:</p>
<pre class="brush: objc; title: ; notranslate">
//
//  CustomCell.m
//  ViewSwitcher
//
//  Created by Arjun on 9/29/10.
//  Copyright 2010 Hughes Systique Corp. All rights reserved.
//

#import &quot;CustomCell.h&quot;

@implementation CustomCell

@synthesize cityLabel;
@synthesize forecastLabel;
@synthesize temperatureLabel;
@synthesize imageView;

- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
    if ((self = [super initWithStyle:style reuseIdentifier:reuseIdentifier])) {
        // Initialization code
    }
    return self;
}

- (void)setSelected:(BOOL)selected animated:(BOOL)animated {

    [super setSelected:selected animated:animated];

    // Configure the view for the selected state
}

- (void)dealloc {
	[cityLabel release];
	[forecastLabel release];
	[temperatureLabel release];
	[super dealloc];
}

@end
</pre>
<p><strong> Download Project Source </strong></p>
<p><strong> </strong>Grab it from <a href="http://blog.roychowdhury.org/downloads/DrivingWeather.zip">HERE</a>. Hope it helps you.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.roychowdhury.org/2011/04/06/tutorial-routeweather-using-google-weather-and-driving-directions-apis-in-your-ios-apps/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>iPhone Programming: Who Just Called Me?</title>
		<link>http://blog.roychowdhury.org/2011/04/04/iphone-programming-who-just-called-me/</link>
		<comments>http://blog.roychowdhury.org/2011/04/04/iphone-programming-who-just-called-me/#comments</comments>
		<pubDate>Mon, 04 Apr 2011 21:07:51 +0000</pubDate>
		<dc:creator>Arjun</dc:creator>
				<category><![CDATA[Arjun Roychowdhury]]></category>
		<category><![CDATA[mobile]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[address book]]></category>
		<category><![CDATA[ios]]></category>
		<category><![CDATA[iphone]]></category>
		<category><![CDATA[tutorial]]></category>

		<guid isPermaLink="false">http://blog.roychowdhury.org/?p=583</guid>
		<description><![CDATA[The best way to learn programming is to solve tasks that irk you. Well, here is something that irked the heck out of me. I often receive calls from outside of the US (India, Korea, Japan etc.). Very often, the incoming caller id leaves out the prefix. Example, instead of &#8220;+91 981234 5678&#8243;  I get just &#8220;9812345678&#8243;, or, instead of &#8220;+82 111 11111&#8243; I just get &#8220;82 111 11111&#8243;. The irritating part is that the iPhone cannot map it to my address book. Fine. But there is the additional irritant &#8211; If I search the iPhone address book, I can&#8217;t search by phone number :-( Damn. So now I am left guessing who just called me. It happened so often, I finally decided to do something about it. Or, I decided to solve the damn problem. So I had to learn how to: 1. Access the call log, so I could check my recent call list and select the number I wanted to check 2. Access my address book and search for that number (substring search) Well, as it turns out, &#8220;1&#8243; is impossible, unless the phone is jailbroken. There are no APIs to access call log. Well, not much<a href="http://blog.roychowdhury.org/2011/04/04/iphone-programming-who-just-called-me/"> <br /><br /> (Read More...)</a>]]></description>
			<content:encoded><![CDATA[<p>The best way to learn programming is to solve tasks that irk you. Well, here is something that irked the heck out of me. I often receive calls from outside of the US (India, Korea, Japan etc.). Very often, the incoming caller id leaves out the prefix. Example, instead of &#8220;+91 981234 5678&#8243;  I get just &#8220;9812345678&#8243;, or, instead of &#8220;+82 111 11111&#8243; I just get &#8220;82 111 11111&#8243;. The irritating part is that the iPhone cannot map it to my address book. Fine. But there is the additional irritant &#8211; If I search the iPhone address book, I can&#8217;t search by phone number :-(</p>
<p>Damn. So now I am left guessing who just called me. It happened so often, I finally decided to do something about it. Or, I decided to solve the damn problem.</p>
<p><span id="more-583"></span></p>
<p>So I had to learn how to:</p>
<p>1. Access the call log, so I could check my recent call list and select the number I wanted to check</p>
<p>2. Access my address book and search for that number (substring search)</p>
<p>Well, as it turns out, &#8220;1&#8243; is impossible, unless the phone is jailbroken. There are no APIs to access call log. Well, not much harm done &#8211; you can always enter the number in the app.</p>
<p>So here is what I came up with: (I&#8217;ve blurred the numbers)</p>
<p><a href="http://blog.roychowdhury.org/wp-content/uploads/2011/04/photo.png"><img class="alignnone size-full wp-image-584" title="photo" src="http://blog.roychowdhury.org/wp-content/uploads/2011/04/photo.png" alt="" width="300" height="450" /></a></p>
<p>And now, an explanation of the code:</p>
<p><span style="color: #800000;">Note: I am just going to explain the main parts of the program, the &#8220;WhoCalledMeViewController&#8221; .m and .h files. The rest are standard stuff. You can download my sources and explore.</span></p>
<p><strong>WhoCalledMeViewController.h</strong></p>
<pre class="brush: objc; title: ; notranslate">
//
//  WhoCalledMeViewController.h
//  WhoCalledMe
//
//  Created by Arjun on 4/1/11.
//  Copyright 2011 Hughes Systique Corp. All rights reserved.
//

#import &lt;UIKit/UIKit.h&gt;
#import &lt;AddressBook/AddressBook.h&gt;
#import &lt;AddressBookUI/AddressbookUI.h&gt;
#import &quot;MBProgressHUD.h&quot;
</pre>
<p>A few notes here: You need to include the AddressBook headers as well as add the AddressBook framework to your project. I don&#8217;t really think you need the AddressBookUI framework as we are not using the address book contact picker UI here. You can try removing it. Finally, <a href="https://github.com/jdg/MBProgressHUD">MBProgressHUD</a> is a great 3rd party activity indicator that is really easy to use. All you need to do is drop MBProgressHUD.h/m into your project and use away.</p>
<pre class="brush: objc; title: ; notranslate">
@interface WhoCalledMeViewController : UIViewController &lt;MBProgressHUDDelegate&gt;  {

    IBOutlet UITextView  *listOfMatches;    // will contain all the names &amp; phones that match
    IBOutlet UITextField *number;           // holds the number you enter
    NSMutableArray* _addressBookNames;      // holds a list of all the address book names
    NSMutableArray* _addressBookPhones;     // holds a list of all the phone #s (there is a 1:1 between _addressBookPhones and Names)
    MBProgressHUD *HUD;                     // used to display an activity indicator

}

@property (nonatomic, retain) UITextView *listOfMatches;
@property (nonatomic, retain) UITextField *number;
@property(nonatomic, retain)NSMutableArray *_addressBook;

- (IBAction) bkgrndClick:(id)sender;        // make sure keyboard disappears on tap
- (IBAction) findPhone:(id)sender;          // the function that searches your address book for the number
-(void)loadAddressBook;                     // called at the start to load the contact book into an array for faster search
-(IBAction)initHudAndAB;                    // loadAddressBook is called by this function, actually

@end
</pre>
<p>I think the comments in the header file are clear. the bkgrndClick function is a typical trick people use to make keyboards disappear when you tap on the screen. Basically it involves add a custom button equal to the size of the screen behind everything and then detect when the user taps it &#8211; when tapped, we will have the keyboard disappear.</p>
<p>One quick note: When you use MBProgressHUD, you need to implement some of its required methods in your file. The &lt;MBProgressHUDDelegate&gt; instruction tells iOS that this file will implement these methods.</p>
<p>Okay, now lets get into the implementation:</p>
<p><strong>WhoCalledMeViewController.m</strong></p>
<pre class="brush: objc; title: ; notranslate">

//
//  WhoCalledMeViewController.m
//  WhoCalledMe
//
//  Created by Arjun on 4/1/11.
//  Copyright 2011 Hughes Systique Corp. All rights reserved.
//

#import &quot;WhoCalledMeViewController.h&quot;

@implementation WhoCalledMeViewController

@synthesize number;
@synthesize listOfMatches;
@synthesize _addressBook;

// This takes care of the keypad disappearing if you tap outside of it
-(IBAction) bkgrndClick:(id) sender
{
	[number resignFirstResponder];
}
</pre>
<p>Gee. I just explained this. The &#8216;tap in the background to make the keyboard go away&#8217; trick.</p>
<pre class="brush: objc; title: ; notranslate">

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

- (void)didReceiveMemoryWarning
{
    // Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];

    // Release any cached data, images, etc that aren't in use.
}

// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad
{
        [super viewDidLoad];
}

- (void)viewDidUnload
{
    [super viewDidUnload];
    [_addressBookPhones release];
    [_addressBookNames release];
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    // Return YES for supported orientations
    return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
</pre>
<p>Standard callbacks. Just making sure we release the global arrays on exit, and we only support portrait mode.</p>
<pre class="brush: objc; title: ; notranslate">

// MBProgressHUD calls this when the progress bar is over
- (void)hudWasHidden {
	// Remove HUD from screen when the HUD was hidded
	[HUD removeFromSuperview];
	[HUD release];
}
</pre>
<p>MBProgressHUD has some mandatory callbacks. This one is called when the HUD activity completes. the HUD is removed from the view and deallocated.</p>
<pre class="brush: objc; title: ; notranslate">

// this is called when you press the address book button
// it is also called by initHudAndAB for the first time
// the goal of this function is to iterate through the address book
// and suck out ALL phone #s associated to a ALL names
-(void)loadAddressBook
{
    // remember this function will be called each time you refresh the address book
    // by pressing the address book button, so make sure you release before alloc again
    if ( _addressBookNames) { [_addressBookNames release]; }
    if ( _addressBookPhones) { [_addressBookPhones release]; }

    HUD.labelText = @&quot;Loading Address Book...&quot;;
    ABAddressBookRef _addressBookRef = ABAddressBookCreate();
    NSArray* allPeople = (NSArray *)ABAddressBookCopyArrayOfAllPeople(_addressBookRef);
    _addressBookNames = [[NSMutableArray alloc] initWithCapacity:[allPeople count]];
    _addressBookPhones = [[NSMutableArray alloc] initWithCapacity:[allPeople count]];

    HUD.labelText=[NSString stringWithFormat:@&quot;Loading %d records&quot;,[allPeople count]];

    // now iterate though all the records and suck out phone numbers
    for (id record in allPeople) {
        CFTypeRef phoneProperty = ABRecordCopyValue((ABRecordRef)record, kABPersonPhoneProperty);
        NSArray *phones = (NSArray *)ABMultiValueCopyArrayOfAllValues(phoneProperty);
        CFRelease(phoneProperty);
        for (NSString *phone in phones) {
            NSString* compositeName = (NSString *)ABRecordCopyCompositeName((ABRecordRef)record);

            //so, if a name has multiple phone numbers, we create duplicate records
            // of the name and each phone #

            [_addressBookNames addObject:compositeName];
            [_addressBookPhones addObject:phone];

            [compositeName release];

        }
        [phones release];
    }
    CFRelease(_addressBookRef);
    [allPeople release];
    allPeople = nil;

}
</pre>
<p>Okay, so what we do is that when the app first loads, we read the entire address book and copy it into two global arrays. The first one contains the names and the second contains the phone numbers. We ensure they both have the same # of entries. In other words, if &#8216;Bob&#8217; has 3 numbers, we populate the Names array with 3 &#8216;Bobs&#8217; each with a single number.<br />
You need to use the ABxxx (AddressBook) APIs of iOS to read/manipulate the address book. Also,<br />
kABPersonPhoneProperty is used to retrieve _all_ the phone numbers associated to an entry. Note that a single records can have many phone numbers. So first, we iterate the address book and get each records, and then iterate each record to retrieve the phone #s associated to it. As we get each phone#, we populate our global arrays appropriately.</p>
<pre class="brush: objc; title: ; notranslate">

// This is called when you press the address book icon. Basically, it shows and activity indicator
// and loads the address book in a separate thread. It calls loadAddressBook
-(IBAction)initHudAndAB
{
    // Now lets show a progress dialog
	HUD = [[MBProgressHUD alloc] initWithWindow:[UIApplication sharedApplication].keyWindow];
	HUD.mode = MBProgressHUDModeIndeterminate;

	// Add HUD to screen
	[self.view.window addSubview:HUD];

	// Regisete for HUD callbacks so we can remove it from the window at the right time
	HUD.delegate = self;

	HUD.labelText = @&quot;Working...&quot;;

	// Show the HUD while the provided method executes in a new thread
	[HUD showWhileExecuting:@selector(loadAddressBook) onTarget:self withObject:nil animated:YES];

}
</pre>
<p>Note however that we don&#8217;t directly call loadAddressBook when the app starts. This is because we want to display a HUD while the contact book is loading (because it may take some time). MBProgressHUD requires that we display the indicator, and then launch the &#8216;time consuming operation&#8217; in a separate thread. So instead, when the user starts the app, we call initHudAndAB, which basically displays a progressHUD and then launches a thread which calls loadAddressBook. Caution: Make sure you don&#8217;t do an UI updates directly in a background thread &#8211; you will face all sorts of data sync and mutex lock problems. Google around if you want to know more.</p>
<pre class="brush: objc; title: ; notranslate">
// This function is called when you press the phone icon. It searches the address book (actually, array that
// was preloaded) for any substring match of the phone number you entered

-(IBAction)findPhone:(id) sender
{
    NSString *foundNames=@&quot;&quot;;
    listOfMatches.text = @&quot;Searching for Matches...&quot;;

    int maxCount=0;
    for (int i=0; i&lt;[_addressBookPhones count];i++)
    {

            NSString *item = [_addressBookPhones objectAtIndex:i];

            // nifty  trick to remove all other characters in a phone #
            // remember 3015271111 can be stored in many ways using +, (, ), . etc characters.
            // we want to eliminate all characters that are not digits and them compare

            NSCharacterSet* nonDigits = [[NSCharacterSet decimalDigitCharacterSet] invertedSet]; // all characters that are not digits
            NSString *strippedPhone = [[item componentsSeparatedByCharactersInSet: nonDigits] componentsJoinedByString: @&quot;&quot;]; // take them off

            NSRange textRange = [strippedPhone rangeOfString:number.text]; // substring search

            if(textRange.location != NSNotFound) // means found
            {
                foundNames = [foundNames stringByAppendingString:@&quot;\n&quot;];
                foundNames = [NSString stringWithFormat:@&quot;%@%@ :%@&quot;,foundNames, [_addressBookNames objectAtIndex:i], item];
                maxCount++;
            }

        if (maxCount &gt;1000) { i = [_addressBookPhones count]; } // just take the first 1000 matches

    } //for
    listOfMatches.text = foundNames;

}
@end
</pre>
<p>Okay, and this function does the job of searching the address book for the number you entered in the text box. Basically, it iterates through the global phone list array that was populated when the app started and checks if the number entered occurs anywhere as a substring. This is a further detail to this: the iPhone can store numbers in various formats like +1 (240) 1112222 or 1 (240) (111) (22) 22 or 1.240.111.222 or whatever else. Obviously, if the user enters 1222 we want it to match these records. So to do that, we strip the phone # of all non digits using a cute NSCharacter operation and then compare.</p>
<p>Finally, I took another short cut &#8211; I just used a UITextView to display the results &#8211; it is very convenient because it allows us to have a scrollable list display of data. If you prefer, convert this to a TableView yourself. Its a little more work.</p>
<p><strong>Get the Source</strong></p>
<p>Download the project <a href="http://blog.roychowdhury.org/downloads/WhoCalledMe.zip">HERE</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.roychowdhury.org/2011/04/04/iphone-programming-who-just-called-me/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>(Book Review) Cocos2D – Its raining books, Hallelujah!</title>
		<link>http://blog.roychowdhury.org/2011/01/17/cocos2d-its-raining-books-hallelujah/</link>
		<comments>http://blog.roychowdhury.org/2011/01/17/cocos2d-its-raining-books-hallelujah/#comments</comments>
		<pubDate>Mon, 17 Jan 2011 10:19:17 +0000</pubDate>
		<dc:creator>Arjun</dc:creator>
				<category><![CDATA[Arjun Roychowdhury]]></category>
		<category><![CDATA[Gaming]]></category>
		<category><![CDATA[mobile]]></category>
		<category><![CDATA[world 2.0]]></category>
		<category><![CDATA[book review]]></category>
		<category><![CDATA[cocos2d]]></category>
		<category><![CDATA[guide]]></category>
		<category><![CDATA[tutorial]]></category>

		<guid isPermaLink="false">http://blog.roychowdhury.org/?p=553</guid>
		<description><![CDATA[Till just a few weeks ago, there were no real books one could read on Cocos2D game programming. While there are an almost infinite number of web tutorials, a book has a different charm &#8211; it is usually more structured and hopefully better researched. A few weeks ago, the first book on Cocos2D surfaced, &#8220;Learn iPhone and iPad cocos2D game development&#8221; by Steffen Itterheim. I bought it on day 1 of its release, and posted my review here. In short, it was well written and, well, the very first book for cocos2D, so it had that first mover advantage. The other book I am eagerly waiting for is Rod Strougo and Ray Wenderlich&#8217;s book &#8220;Learning Cocos2D&#8220;. The book is yet to be released, but I get the feeling it will be more &#8216;advanced&#8217; than the other available books. In the mean time, I was contacted by another company, Packt Publishing who sent me an email to review a new book from them: Cocos 2D for iPhone 0.99 &#8211; Beginners Guide by Pablo Ruiz. Here is the introduction of the book, in the Preface: &#8220;This book will teach you the fundamentals of how to write games with this framework. As this<a href="http://blog.roychowdhury.org/2011/01/17/cocos2d-its-raining-books-hallelujah/"> <br /><br /> (Read More...)</a>]]></description>
			<content:encoded><![CDATA[<p><a href="https://www.packtpub.com/cocos2d-games-for-iphone-0-99-beginners-guide/book"><img class="alignleft size-full wp-image-559" title="Screen shot 2011-01-17 at 4.04.16 PM" src="http://blog.roychowdhury.org/wp-content/uploads/2011/01/Screen-shot-2011-01-17-at-4.04.16-PM.png" alt="" width="200" height="260" /></a>Till just a few weeks ago, there were no real books one could read on Cocos2D game programming. While there are an almost infinite number of web tutorials, a book has a different charm &#8211; it is usually more structured and hopefully better researched. A few weeks ago, the first book on Cocos2D surfaced, &#8220;<a href="http://www.amazon.com/Learn-iPhone-iPad-Cocos2D-Development/dp/1430233036">Learn iPhone and iPad cocos2D game development</a>&#8221; by Steffen Itterheim. I bought it on day 1 of its release, and posted my review <a href="http://www.amazon.com/review/R2SJL7ABLJS76P/ref=cm_cr_pr_viewpnt#R2SJL7ABLJS76P">here</a>. In short, it was well written and, well, the very first book for cocos2D, so it had that first mover advantage.</p>
<p>The other book I am eagerly waiting for is Rod Strougo and Ray Wenderlich&#8217;s book &#8220;<a href="http://www.amazon.com/gp/product/0321735625/ref=pd_lpo_k2_dp_sr_1?pf_rd_p=486539851&amp;pf_rd_s=lpo-top-stripe-1&amp;pf_rd_t=201&amp;pf_rd_i=1430233036&amp;pf_rd_m=ATVPDKIKX0DER&amp;pf_rd_r=1YCAE9GQ0CRD32H0WJ3N">Learning Cocos2D</a>&#8220;. The book is yet to be released, but I get the feeling it will be more &#8216;advanced&#8217; than the other available books.</p>
<p>In the mean time, I was contacted by another company, Packt Publishing who sent me an email to review a new book from them: <a href="https://www.packtpub.com/cocos2d-games-for-iphone-0-99-beginners-guide/book">Cocos 2D for iPhone 0.99</a> &#8211; Beginners Guide by Pablo Ruiz.</p>
<p><span id="more-553"></span></p>
<p>Here is the introduction of the book, in the Preface:</p>
<p><em>&#8220;This book will teach you the fundamentals of how to write games with this framework. As this book is meant to give you a basic knowledge of the most important aspects of Cocos2d, it will cover a lot of subjects very quickly. However, do not worry! Almost every chapter will include tasks for you to complete and examples for you to practice. Throughout this book, we&#8217;ll make three different games and each chapter will build on the previous one, but can also be considered independently, so feel free to skip to any chapter that interests you.&#8221;</em></p>
<p>So this post is a review of this new book by Pablo.</p>
<p><em>Full Disclosure:</em> I was contacted by the company to review their book &#8211; they gave me a free e-copy so I could read and comment. Beyond this, I have no monetary or any other form of profit/benefit from this post. In other words, if I thought this book is crap, I can call it crap. If I think its good, I can call it good.</p>
<p><strong>So how is Pablo Ruiz&#8217;s </strong>&#8220;<strong>Cocos2D for iPhone 0.99&#8243; ?</strong></p>
<p><em>The Good</em></p>
<ol>
<li>Its 350 pages of relevant content. The author dives into topics quickly and gets to code examples very soon.</li>
<li>It covers the usual topics like fiddling with sprites, more details on actions, scene and menu management, particle systems, cocosdenshion</li>
<li>I liked the fact that the examples Pablo chose of games are better than &#8216;stupid games that only prove a concept&#8217;. For example, &#8220;Chapter 2:Playing with Sprites&#8221; is a 54 (approx) page chapter which incrementally goes about building a board game where you align stones based on color by swapping them around and then when you align them, the stones destroy themselves. In this 50 page chapter, he goes through the basics of CCSprite, using CCTouchDispatcher for touch management, using Zwoptex to create Sprite Sheets,using CCTextureCache to pre load images for faster response time and even a few lines of OpenGL (basic stuff like drawing a box around an item you select)</li>
<li>He continues the same board game across Chapters 3&amp;4 (another 55 odd pages), where he embellished the game with actions (the usual CC actions along with the ease in action effects). There is a nice page in his book that shows the animation path of each ease action. It looks like it was copy pasted from some standards reference &#8211; if so, then you may already know about it &#8211; but to me, it was nice to see the easein/out effects on one page. Finally, in Chapter 4, he shows us how to add fonts and text labels to the game and goes through the basics on how to create your own font with CCBitmapFontAtlas.</li>
<li>While the board game was interesting, I was getting bored. Fortunately, at Chapter 5, Pablo stars a new game that basically is called &#8220;Aerial Gun&#8221; which is a shooting game. You control an airplane while enemies approach you &#8211; you have to kill em. In this chapter his focus is on the basics of the game &#8211; sprite movement, handling accelerometer based movements, how to fire bullets (bullets stored in an array so you see a spurt of them), collision detection</li>
<li>Then, in chapter 6, he adds options and other menus to the game, including telling us how to use the basis NSUserDefault class to store preferences</li>
<li>Finally, in chapter 7,he integrates the Cocos2D particle system into his game to give explosion effects. One thing I liked was it covers the meaning of all the attributes of a particle system (again at a cursory level). Specifically, I liked the section where he covers how to give an explosion effect when your enemy is hit including telling us how to make the particles move correctly. All of this is directly by manipulating the particle parameters he briefly explained earlier. And then he finishes off with using ParticleDesigner, which is pretty much the defacto particle design tool, it seems</li>
<li>In Chapter 8, he covers background panning using tilemaps. Nothing new or unique here. But if you don&#8217;t know tilemaps, here it is.</li>
<li>Chapter 9 covers the CC Sound engine. He covers both SimpleAudioEngine and CDSoundEngine</li>
<li>What stands out from the others in this book is the chapter on Chipmunk.  Chipmunk is a physics engine that can add realism to your games (like the toppling monuments in angry birds).  Most tutorials and books cover Box2D (even Steffen&#8217;s book I reviewed  earlier). Box2D seems more able, but is reasonably more complicated. And  I really wanted a good reference to chipmunk (as a beginner). I was  very happy to see Pablo cover chipmunk. Just for that, I&#8217;d give him  kudos. And also, he goes through several pages in building a relevant game &#8211; a totem block, that rests on top of various blocks of different shapes. Your goal is to remove the blocks without the totem falling on the floor.</li>
<li>There is also a chapter on <a href="http://www.openfeint.com/">OpenFeint</a> &#8211; I liked it. Frankly, I never knew about it. OpenFeint  is a software library you can link your code with that allows your game  to become &#8220;social&#8221;. In other words, you get access to leader boards,  get notifications on new scores from your buddies in your network,  connect and post messages to Face Book and more. Yep, you guessed it. It  can also become a nightmarish tool if you choose to abuse it (remember  those beyond irritating messages from all your friends in facebook about  some idiotic occurrence in some mafia game they were playing etc.) Used properly, OpenFeint looks like a very nice tool and Pablo covers it well.</li>
</ol>
<p><em>The Bad</em></p>
<ol>
<li>The book is hurried. Just too hurried. When you start focusing on a topic into the next level of detail, you feel like the author is trying to complete a race in record time. While at first glance, it looks like he has spent time with details, when you really want to understand something new, you feel he should have spent more time with details.</li>
<li>Code level commentary is high-level and has errors. Consider for example, the chapter on Chipmunk. This was my first point of interest, so I decided to actually try out his examples. I was not given his resource file zips, so I had to type them in myself. The instructions were cursory at best:
<ol>
<li>Example, he just says &#8220;rename HelloWorld&#8221; to &#8220;GameScene&#8221; (no further instructions, and it is not just renaming &#8211; you have to rename more than one part, and refactoring was a better approach as far as I feel)</li>
<li>He says &#8220;in init method of GameLayer class, change space gravity to 0,-200&#8243; without saying where that line would be and what are we looking for. Again, basic stuff &#8211; if you know your stuff, you don&#8217;t have an issue. But if you are a beginner, you are left wondering</li>
<li>Finally, he asks us to introduce a line declaring a totem variable, which never compiles because the instructions forgot to tell us to declare it first (and there too, he says in another example &#8220;declare an ivar&#8221; &#8211; thats all). Again, not an issue for those who know, but if you are really a beginner, you will feel lost at his pace and choice to ignore details.</li>
<li>So basically, you either describe it well enough and the reader can figure out errors on their own, or, you describe it at a high level but make sure the code has no errors. <em>Again, like I said &#8211; I did not get enough time to actually try his other examples. Unfortunately, the first chapter I did try to get into details (chipmunk) left me floundering (remember I am a beginner to cocos2d, and am supposed to be a target audience for his book as per the preface)</em></li>
</ol>
</li>
<li>There may be other issues, I am on travel, so I could not do a thorough read.</li>
</ol>
<p><strong>Verdict &#8211; Better than Steffen Itterheims Cocos2d book?</strong></p>
<p>Frankly, from what I read so far, I don&#8217;t think so. While Pablo&#8217;s book covers more topics, the one chapter I actually decided to dive into came out with several errors.  Steffen&#8217;s book is more thought out and not hurried at all. And I&#8217;d say there i around 60-70% intersection of topics between the books. And unless  I try out more of Pablo&#8217;s code in the book, I can&#8217;t honestly say it is <em>the book </em> for beginners.</p>
<p>But besides that, it covers enough topics to be of interest. I think if Pablo spent more time with details on the book, it would be a treasure trove. Also, there is limited (or no) handling of the more advanced Cocos2D functions like isometric tilemaps, Cocos2D Camera, Parallax scrolling etc.</p>
<p>Having said all of the above, I think the author will likely improve the quality of the book in future versions.</p>
<p><strong>Should you buy it?</strong></p>
<p>Well, if it was the first book, I would buy it. Since I already have one book and I will surely buy the one by Rod  &amp; Ray (just because of the reputation), it makes buying this book a not-so-easy-choice. For those who choose to buy it, it will give you lots of help and a great head start. But be expected to be rushed and brace yourselves for errors in code.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.roychowdhury.org/2011/01/17/cocos2d-its-raining-books-hallelujah/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Embracing digital tools for early development &#8211; all in 45 minutes a day.</title>
		<link>http://blog.roychowdhury.org/2010/12/10/embracing-digital-tools-for-infant-toddler-development-all-in-45-minutes-a-day/</link>
		<comments>http://blog.roychowdhury.org/2010/12/10/embracing-digital-tools-for-infant-toddler-development-all-in-45-minutes-a-day/#comments</comments>
		<pubDate>Fri, 10 Dec 2010 17:59:09 +0000</pubDate>
		<dc:creator>Arjun</dc:creator>
				<category><![CDATA[Arjun Roychowdhury]]></category>
		<category><![CDATA[general technology]]></category>
		<category><![CDATA[mobile]]></category>
		<category><![CDATA[apps for children]]></category>
		<category><![CDATA[children]]></category>
		<category><![CDATA[digital growth]]></category>
		<category><![CDATA[mental growth]]></category>
		<category><![CDATA[preschool]]></category>
		<category><![CDATA[toddler]]></category>

		<guid isPermaLink="false">http://blog.roychowdhury.org/2010/12/10/embracing-digital-tools-for-infant-toddler-development-all-in-45-minutes-a-day/</guid>
		<description><![CDATA[When I grew up, it was common for parents (including mine) to assume that making your child watch TV, or play video games at an early age was not the right thing to do. Anything to do with TV or video gaming was assumed to &#8216;corrupt young minds&#8217; and the general thought process was to ensure your child grows up on traditional things (like real physical toys, pen and paper, chalk boards and educational books).There was a valid reason for this &#8211; in old days, content in such mediums was purely for entertainment and little was done for conscious education for children. Interestingly, that notion persists very strongly even today. I have lots of friends who have brought up their children pretty much devoid of TV and digital tools. When I say devoid, I don&#8217;t mean a total ban. They let them use these objects once in a while, but not in a &#8216;let it help you grow&#8217; mode. It is treated as pure entertainment and curtailed often to just one show, played over and over again, or just one game, played over and over again. It is impossible to state what is right and what is wrong when it<a href="http://blog.roychowdhury.org/2010/12/10/embracing-digital-tools-for-infant-toddler-development-all-in-45-minutes-a-day/"> <br /><br /> (Read More...)</a>]]></description>
			<content:encoded><![CDATA[<p><a href="http://blog.roychowdhury.org/wp-content/uploads/2010/12/dad-son-ios.png"><img class="alignleft size-full wp-image-515" title="dad son ios" src="http://blog.roychowdhury.org/wp-content/uploads/2010/12/dad-son-ios.png" alt="" width="341" height="345" /></a>When I grew up, it was common for parents (including mine) to assume that making your child watch TV, or play video games at an early age was not the right thing to do. Anything to do with TV or video gaming was assumed to &#8216;corrupt young minds&#8217; and the general thought process was to ensure your child grows up on traditional things (like real physical toys, pen and paper, chalk boards and educational books).There was a valid reason for this &#8211; in old days, content in such mediums was purely for entertainment and little was done for conscious education for children. Interestingly, that notion persists very strongly even today. I have lots of friends who have brought up their children pretty much devoid of TV and digital tools. When I say devoid, I don&#8217;t mean a total ban. They let them use these objects once in a while, but not in a &#8216;let it help you grow&#8217; mode. It is treated as pure entertainment and curtailed often to just one show, played over and over again, or just one game, played over and over again.</p>
<p>It is impossible to state what is right and what is wrong when it comes to bringing up a child, because the final decision is yours, as a parent. All  I can say is parents who are able access such new mediums should give it a serious look as times have changed. There is a slew of fantastic learning tools available that offer a level of interactivity and immersive-ness (is that a word?) that never existed before.</p>
<p>In general, I am a technologist. My work, my hobby and my passion all converge to one word: technology. I am totally for adopting digital tools where necessary if I feel it improves mental or physical growth as long as I am convinced that it is not also harming my child in any significant way. So in this post, I&#8217;d like to talk about how we  leveraged technology to help in our child&#8217;s growth.</p>
<p>As a general rule, we as parents subscribe to the rule of limiting the time our son had his hands on these tools (we typically allow a 45 minute window at most each day for this, with weekends getting a little more digital time) and ensure that he mixes his digital tools with a lot of physical activity (the usual running, playing, reading books at night, board games, etc.), but the focus of this post is how we chose to maximize those 45 minutes each day in selecting the right digital/enterta</p>
<p>nment tools that help his mind grow.</p>
<p><strong>Scope of this post</strong></p>
<p>The rest of the post will talk about several key applications that I think have contributed greatly to reading, writing, music and social skills of our son at an early age. To you, I am not going to talk about  what is right/wrong, how much TV they should or should not watch, whether it is wise to let them play games or not (of the digital kind) etc. That is your choice. Should you choose to expose your little ones to the digital era at an early age, I will simply list tools and applications that we used and felt were of  significant help.</p>
<p>Each attribute mentioned later in the post are attributes that I&#8217;ve seen grow rapidly with him by the time he turned 3 and a half, so the results are obvious to me (i.e. ability for music, reading, writing, social skills, visual and problem solving skills)</p>
<p><span id="more-498"></span></p>
<p><strong>The Devices</strong></p>
<p>His digital assistance tools centered around 3 primary devices:</p>
<p>a) An iPhone: greatly helped in his: visual skills (puzzle solving etc.),</p>
<p>b) A TV: Specifically, PBS and NetFlix (I&#8217;ll talk about this later): Greatly helped him in his musical skills, responsibility and other soft skills</p>
<p>c) An iPAD: greatly helped his: all of the above for iphone PLUS reading and writing skills.</p>
<p>Realistically speaking, the iphone and ipad could really be grouped into one category, but the area that the iPAD stood out was how it helped his reading and writing skills.</p>
<p><strong>Education as a Game</strong></p>
<p>I am also a strong believer in converting education into a game-like format. I&#8217;ve observed that kids love it when they are playing a game. If you introduce a concept as a game and not as a formal education point, they adapt easily to it, and may appreciate it (if they like it). A Game format, or an interactive format helps them consider this as fun. Once the fundaments are set in a &#8216;fun way&#8217; you can proceed to adopt more formal ways to enhance it, if you wish.</p>
<p><strong>The Applicability of TV</strong></p>
<p>There are some great TV serials, I think, that can greatly help child growth. A key criteria for my selection was they must be educational, should use good spoken English (specifically should be a clean accent) and should not have any violence in any form.</p>
<p>(image credit: Where not mentioned explicitly, images are those provided by Wikipedia)</p>
<p><img class="alignnone" src="http://upload.wikimedia.org/wikipedia/en/2/25/LittleEinsteinsLogo.png" alt="" width="220" height="100" /></p>
<p>a)  <strong>The Art of Music:</strong> <a href="http://en.wikipedia.org/wiki/Little_Einsteins">Little Einstein</a>s: Little Einstein is a Disney series, that features 4 children who essentially travel the world in their spaceship (&#8216;Rocket&#8217;) solving cute problems of their friends. The focus of this show, to me, is education through music. Each problem has a musical solution Example, conducting a cresendo to help Rocket jump a high mountain, or dropping down to diminuendo while tiptoeing past a sleeping giant. The music is well selected. Each episode selects music from a well known Classical music composer. I am a huge fan of classical music as I think the construction of the music lends itself immensely in building an appreciation of fine arts in a person. So in short, this show contributes to your child&#8217;s ability to appreciate and understand music.</p>
<p><a href="http://blog.roychowdhury.org/wp-content/uploads/2010/12/word-world.jpg"><img class="alignleft size-medium wp-image-522" title="word-world" src="http://blog.roychowdhury.org/wp-content/uploads/2010/12/word-world-300x197.jpg" alt="" width="300" height="197" /></a><img class="alignnone" src="http://upload.wikimedia.org/wikipedia/en/a/ae/Superwhylogo.jpg" alt="" width="250" height="200" /></p>
<p>(word world image:http://tvtropes.org/pmwiki/pmwiki.php/Main/WordWorld)</p>
<p>b) <strong>Reading: </strong><a href="http://en.wikipedia.org/wiki/Word_World">World World</a> and <a href="http://en.wikipedia.org/wiki/Super_why">Super Why</a> are two excellent animated shows that help in your child&#8217;s reading abilities. Word World, specifically, is a fantastic concept. Basically, this world comprises of letters and words. Every object you see, be it a Pig, and Ant, a Pie, a Bed etc. are all made up of letters. When you press letters together, they bounce into the shape of the object the word spells. Example, B-A-L-L when put together forms a ball and bounces around. This show involves the characters solving problems by either creating new words (example, searching for L-I-G-H-T at night to create a NIGHTLIGHT to that it helps allay fear of the dark) and is a super interactive way to help kids understand how letters form words and how words decompose to letters.</p>
<p>SuperWhy is yet another reading ability animated show. It differs from World world in that I think it focusses more on the phonics part than Word World does, which is also critical for your child to understand how to decompose complex words for pronunciation. SuperWhy is a show where a group of kids face real life problems (example, Dad angry because you did something naughty) and they turn into super heroes and dive into well known story books to live the story and use word power to solve problems in in turn, realizing there is a moral to the story which helps them solve real life issues.</p>
<p><img class="alignnone" src="http://upload.wikimedia.org/wikipedia/en/9/96/Backyardigans.jpg" alt="" width="249" height="250" /></p>
<p>c) <strong>Imagination: </strong>Having a good imagination is such a wonderful thing. It helps you think out of the box, be creative and so much more. In recent months, I&#8217;ve been very impressed with an animated show that we found on NetFlix called &#8216;<a href="http://en.wikipedia.org/wiki/Backyardigans">The Backyardigans</a>&#8216;. I understand it is of Canadian origin and centers around 4 or 5 cute animal-kids (a hippo, a duck and some others), who, in each episode use their imagination to make believe they are in a new world, or a new place as new characters and help in solving cute problems. The episode starts with the characters playing in their backyard and then using their imagination, they transform the backyard into a &#8220;new place&#8221; and proceed to solve the problem of the day there. The score is excellent and these little darlings do an excellent dance in their imagined world. I was later told that The Backyardigans is also great for Autistic children who can learn how to more effectively use their imagination. Again, I have no first-hand knowledge on whether it is applicable or not &#8211; this is just something that a colleague told me, and I thought I&#8217;d mention. Another series, though not as imaginative as Backyardigans, and probably more towards <strong>visual problem solving</strong> skills, but is also imaginative is &#8220;<a href="http://en.wikipedia.org/wiki/Blues_Clues">Blues Clues</a>&#8221; (Again, on netflix) which is an excellent show where the main character has an animated dog called &#8216;Blue&#8217; who leaves clues around the episode that tell you what he wants or is feeling that day, which you solve.</p>
<p><img class="alignnone" src="http://upload.wikimedia.org/wikipedia/en/4/42/Caillou.gif" alt="" width="262" height="258" /></p>
<p>d) <strong>Respect,Responsibility and &#8220;Just Like Daddy&#8221;</strong>: While all of the above also indirectly talk about Responsibility, another PBS show, to me, translates the merits of being responsible in practical terms in a way that a child can understand. That is <a href="http://en.wikipedia.org/wiki/Caillou">Caillou</a>. This one is really meant for pre-schoolers. I think it is important for your child to first learn how to speak and converse to a reasonable amount before you will see the benefits of this. Caillou is a pre-schooler who is a normal kid. He misbehaves at times, throws a fit at times, etc. etc. But in each episode, the creators impress upon the child the value of &#8216;respecting others&#8217; and being &#8216;responsible&#8217;.  I was initially on the fence for this one. I watched a couple of them with my son, and noticed that Caillou would throw a fit, not play with his sister, speak angrily to someone (all the attributes you want your child to know is not right, eventually). I wondered if my son would mimic that. I noticed that he closely identified with the character. But interestingly, one of the key undertones of the episode is that Caillou, after making mistakes, learns they are wrong (on his own, typically) and corrects himself and I found my son to understand, via this, the meaning of key concepts like &#8220;listen to your parents&#8221;, &#8220;they want your good, even if they are strict&#8221;, &#8220;it pays to be nice to people&#8221; etc. Another key thing in this episode is it establishes a great bond between Caillou and his Dad. In almost each episode, Caillou works with his Dad, helps him, learns from him etc. and as he says all the time &#8220;Just like Daddy&#8221;. While this serial also shows a great relationship with his mother, sister, grandmother and other folks, I don&#8217;t think I&#8217;d be wrong in saying that the strongest bond is with the Dad. Naturally, this is great for me &#8211; as it just serves as just another great push into making him believe in his Dad more (Yes, this is a self-serving part for me, but practically speaking, I&#8217;ve seen his sense of responsibility grow tremendously)</p>
<p><a href="http://blog.roychowdhury.org/wp-content/uploads/2010/12/Sidthesciencekid-logo.jpg"><img class="aligncenter size-medium wp-image-521" title="Sidthesciencekid-logo" src="http://blog.roychowdhury.org/wp-content/uploads/2010/12/Sidthesciencekid-logo-300x223.jpg" alt="" width="300" height="223" /></a>(image from http://muppet.wikia.com/wiki/Sid_the_Science_Kid)</p>
<p>e) Another show that our son has started enjoying a lot is PBS&#8217; &#8220;<a href="http://en.wikipedia.org/wiki/Sid_The_Science_Kid">Sid the Science Kid</a>&#8220;. Its a show where basic science questions are answered and explored in a fun way by &#8220;Sid&#8221; (like why does a banana rot, what is inertia etc). I personally think its an advanced show, but for some reason my son loves watching it. Its well animated and fun.</p>
<p><strong>iPhone and iPad applications</strong></p>
<p><a href="http://blog.roychowdhury.org/wp-content/uploads/2010/12/iphoneipad.jpeg"><img class="aligncenter size-full wp-image-519" title="iphoneipad" src="http://blog.roychowdhury.org/wp-content/uploads/2010/12/iphoneipad.jpeg" alt="" width="407" height="124" /></a></p>
<p><strong>An Ode to Apple&#8217;s simplicity of design</strong></p>
<p>I strongly believe that an intuitive User Interface is one that you just know how to use. You don&#8217;t need to read a manual, <em>and if you make a mistake, you immediately know how to rectify it.</em> This is the beauty of apple products. Admittedly, toddlers are surprisingly smart. In the early days of his growth (its odd to say this since he is only 3.7 yrs old, but in context of this post means when he was 2 or so), he would often want to sit in front of our home computer, but being able to navigate the mouse, differentiate between right and left click and general tool usage was hard for him. He has now mastered our home computer as well, but, the point is, that I would see that he would spend more time getting the mechanics (how to use it) right rather than spending time on the intent (what to use and learn). When I exposed him to the iOS products (Iphone first, as the iPad was released much later), it was amazing how intuitive it was. In a matter of minutes, this little child figured out the natural finger swipes and its effects. He also quickly figured out the &#8220;Home Button&#8221;. If anything goes wrong in an app, hit &#8220;Home&#8221;. (Infact, hilariously, when he first started talking and something went wrong in anything, he would say &#8220;Daddy, can you please press the Home button?&#8221;). Simply put, the iphone took out the complexity of usage and let him to fully focus on the intent (the app). It was amazing to me, looking at such a little guy navigate this little device with so much ease. Naturally, therefore, when the iPAD was released, I bought it on day one. I absolutely knew its larger form factor would only be better for him learning several other things. On an unrelated note, I was also amazed at how our parents used the iPAD. Both my wife&#8217;s parents and my parents are completely computer illiterate. To a point, that when my mom wants to send an email, she asks someone else to send it, and even check if they have new emails. When she visited us, in just a matter of days, she embraced the iPAD and being a prolific reader, thoroughly enjoyed researching random stuff on wikipedia (she never knew it existed). No confusion. Amazing &#8211; these devices are truly revolutionary &#8211; in the simple fact that they, I think have bridged the gap between technology and usability. Any way, I digress. Let&#8217;s get back, now to the applications.</p>
<p>The iOS devices have a good selection of educational games that you can download, some free, some for a fee that help enhancing various aspects of a child&#8217;s education. The problem with the appstore is that there is no &#8216;try before you buy&#8217;. Even though many apps are cheap ($0.99 or $1.99) you will find that children&#8217;s education apps are always more costly than other apps (I guess people know parents will spend for their children) and I&#8217;ve often found bogus reviews. I&#8217;ve downloaded and paid for several apps, deleted many in minutes and have even paid $15 for an app that only displays static flash-cards but had great reviews (what a waste). Anyway, here are my list of the apps that I&#8217;d consider my top few:</p>
<p><strong>IT IS ENTIRELY POSSIBLE I&#8217;VE MISSED SOME KEY APPS HERE: THIS IS PURELY BASED ON MEMORY OF APPS THAT WERE USEFUL OVER THE LAST 2-3 YEARS</strong></p>
<p><em>(All images from the iTunes catalog)</em></p>
<table>
<tbody>
<tr>
<td><a href="http://itunes.apple.com/us/app/iwritewords-handwriting-game/id307025309?mt=8"><img class="alignleft size-thumbnail wp-image-529" title="iwritewords" src="http://blog.roychowdhury.org/wp-content/uploads/2010/12/iwritewords-150x150.png" alt="" width="150" height="150" /></a></td>
<td>a) <a href="http://itunes.apple.com/us/app/iwritewords-handwriting-game/id307025309?mt=8">iWriteWords</a>: I&#8217;ve tried many apps that <strong>help you write</strong>, but I think iWrite words is simply the best. It converts writing into a fun game and puts in a bit of fun in between as well to keep your child busy.</td>
</tr>
<tr>
<td><a href="http://itunes.apple.com/us/app/shape-builder-preschool-learning/id306572986?mt=8"><img class="alignleft size-thumbnail wp-image-530" title="shape builder" src="http://blog.roychowdhury.org/wp-content/uploads/2010/12/shape-builder-150x150.png" alt="" width="150" height="150" /></a></td>
<td>b) <a href="http://itunes.apple.com/us/app/shape-builder-preschool-learning/id306572986?mt=8">ShapeBuilder</a>: Simply the best puzzle solver for small kids. Clean graphics, intuitive and helped immensely with his <strong>visual problem solving </strong>skills. In this category, I also found <a href="http://www.google.com/url?sa=t&amp;source=web&amp;cd=1&amp;ved=0CBYQFjAA&amp;url=http%3A%2F%2Fitunes.apple.com%2Fus%2Fapp%2Fpreschool-connect-dots-game%2Fid353386972%3Fmt%3D8&amp;ei=q2cCTcnFHIO8lQeJ7pDdCQ&amp;usg=AFQjCNGNIts4rzXtD0wjCVLEpBup4Lha2g&amp;sig2=WC7jdCILn1iDcneLY0x9aQ">ConnectDots</a> to be a very nice app that in addition to being a good visual/cognitive app also helps you learn letters and numbers.</td>
</tr>
<tr>
<td><a href="http://itunes.apple.com/us/app/learn-to-talk/id321584042?mt=8"><img class="alignleft size-thumbnail wp-image-531" title="learntotalk" src="http://blog.roychowdhury.org/wp-content/uploads/2010/12/learntotalk-150x150.png" alt="" width="150" height="150" /></a></td>
<td>c) <a href="http://itunes.apple.com/us/app/learn-to-talk/id321584042?mt=8">Learn To Talk</a>: When my son was <strong>learning to talk</strong>, I downloaded many apps to help him from flash cards, to other mechanisms. I landed up deleting most, but this one still exists in my iphone. Its a nice flash card based game that lets you select world complexity (one word, two words,  high impact etc).</td>
</tr>
<tr>
<td><a href="http://itunes.apple.com/us/app/giraffes-matching-zoo/id320105340?mt=8"><img class="alignleft size-thumbnail wp-image-532" title="matchingzoo" src="http://blog.roychowdhury.org/wp-content/uploads/2010/12/matchingzoo-150x150.png" alt="" width="150" height="150" /></a></td>
<td>d) <a href="http://www.google.com/url?sa=t&amp;source=web&amp;cd=1&amp;ved=0CBMQFjAA&amp;url=http%3A%2F%2Fitunes.apple.com%2Fus%2Fapp%2Fgiraffes-matching-zoo%2Fid320105340%3Fmt%3D8&amp;ei=LmcCTZWaEMKBlAfqjf3KCQ&amp;usg=AFQjCNH-uUlteEV_AYDLZukwGcH6hkUirg&amp;sig2=C9r7gN4DgOsDJ6eOUzuzOg">Matching Zoo</a>: In the category of <strong>Memory Builders, </strong>you will find many apps that help your child in building his memory. Matching Zoo is one of them &#8211; its the traditional memory game that requires you to remember the position of various objects in a 2&#215;2 grid and try to match a pair. There are many like this. My son outgrew it pretty soon, but I do think it helped.</td>
</tr>
<tr>
<td><a href="http://itunes.apple.com/us/app/word-cub-letters-sounds/id335597350?mt=8"><img class="alignleft size-thumbnail wp-image-533" title="wordcub" src="http://blog.roychowdhury.org/wp-content/uploads/2010/12/wordcub-150x150.png" alt="" width="150" height="150" /></a></td>
<td>e) <a href="http://itunes.apple.com/us/app/word-cub-letters-sounds/id335597350?mt=8">Word Cub</a> and <a href="http://itunes.apple.com/us/app/build-a-word/id329397984?mt=8">Build a Word</a> are two good apps that my son enjoyed a lot in helping him with an <strong>understanding of phonics</strong>. I&#8217;d give more points to word cub. There are many other cute phonics apps, one being <a href="http://itunes.apple.com/us/app/abc-phonics-animals-free-lite/id335670787?mt=8">ABC Phonics</a>. I downloaded the free version and my son quite liked it &#8211; phonics in a pop the balloon game fashion.</td>
</tr>
<tr>
<td><a href="http://blog.roychowdhury.org/wp-content/uploads/2010/12/reading-icons1.png"><img class="alignleft size-full wp-image-543" title="reading-icons" src="http://blog.roychowdhury.org/wp-content/uploads/2010/12/reading-icons1.png" alt="" width="150" height="50" /></a></td>
<td>f) On <strong>Reading Skills</strong>, I think the iPad stands head and shoulders above the iphone. Due to its form factor, it is just so much more immersive and my son actually treats it as a book. There are a lot of good e-book apps for children, but when it comes to super interactivity and graphics I thought <a href="http://itunes.apple.com/us/app/jack-beanstalk-childrens-interactive/id364871348?mt=8">Jack and the BeanStalk</a> and <a href="http://www.google.com/url?sa=t&amp;source=web&amp;cd=1&amp;ved=0CBsQFjAA&amp;url=http%3A%2F%2Fitunes.apple.com%2Fus%2Fapp%2Ftoy-story-read-along%2Fid364376920%3Fmt%3D8&amp;ei=YmkCTYylFIO8lQfhkuGBCA&amp;usg=AFQjCNGrHHPNVzV9al7XUSxLCeGtuUlQrQ&amp;sig2=wSlrpGqTy9exxlDgkSE7Mg">Toy Story read along</a> were great. But when it came to a  good variety of books, <a href="http://www.google.com/url?sa=t&amp;source=web&amp;cd=1&amp;ved=0CBsQFjAA&amp;url=http%3A%2F%2Fwww.padgadget.com%2F2010%2F05%2F21%2Fmeegenius-ipad-app%2F&amp;ei=jWkCTZjCIIGglAfuucy5CQ&amp;usg=AFQjCNGt3v158Xq3_XSftShxQzioDviknw&amp;sig2=9-eMg0YomYqBD1Y04UsWPA">MeeGenius</a> is excellent. All these apps let your child follow a book by highlighting and pronouncing each world clearly.</td>
</tr>
<tr>
<td><a href="http://itunes.apple.com/us/app/doodle-buddy/id313232441?mt=8"><img class="alignleft size-thumbnail wp-image-535" title="doodle" src="http://blog.roychowdhury.org/wp-content/uploads/2010/12/doodle-150x150.png" alt="" width="150" height="150" /></a></td>
<td>g) <a href="http://itunes.apple.com/us/app/doodle-buddy/id313232441?mt=8">Doodle Buddy </a>is a simple, drawing app for the iPhone/iPad. It presents a blank screen. You can draw by touching on the screen and change colors and brush sizes. I found my son using this a lot, learning <strong>how to draw</strong>, how to differentiate between <strong>colors</strong> and also <strong>refine his fine motor skills </strong>(of his, umm fingers). Frankly, there may be better apps out there &#8211; just that I had this one (FYI, <a href="http://itunes.apple.com/us/app/brushes-iphone-edition/id288230264?mt=8">Brushes</a> is too complex for a toddler)</td>
</tr>
<tr>
<td><a href="http://itunes.apple.com/us/app/math-series/id301019765?mt=8"><img class="alignleft size-thumbnail wp-image-536" title="math" src="http://blog.roychowdhury.org/wp-content/uploads/2010/12/math-150x150.png" alt="" width="150" height="150" /></a></td>
<td>h) Once he understood numbers and began counting, I found <a href="http://itunes.apple.com/us/app/math-series/id301019765?mt=8">Math Series</a> to be a nice app that brought forward concepts such as <strong>number series </strong>and other number related simple concepts forward.</td>
</tr>
<tr>
<td><a href="http://itunes.apple.com/us/app/virtuoso-piano-free-2-hd/id304075989?mt=8"><img class="alignleft size-thumbnail wp-image-537" title="virtuoso" src="http://blog.roychowdhury.org/wp-content/uploads/2010/12/virtuoso-150x150.png" alt="" width="150" height="150" /></a></td>
<td>i) When it comes to music playing skills, the iPad outshines the iPhone. There are many free piano apps. I happened to use <a href="http://itunes.apple.com/us/app/virtuoso-piano-free-2-hd/id304075989?mt=8">Virtuoso</a>. My son was fascinated that he could play tunes here (well, he would just bang, but try to make music). Interestingly, after I saw his interest in this digital app, I actually bought a piano for him (which he uses a LOT these days). In a way, it was an easy investment before buying a real piano.</td>
</tr>
<tr>
<td><a href="http://itunes.apple.com/us/app/adams-game-toddler-voice-flash/id294433305?mt=8"><img class="alignleft size-thumbnail wp-image-538" title="adam" src="http://blog.roychowdhury.org/wp-content/uploads/2010/12/adam-150x150.png" alt="" width="150" height="150" /></a></td>
<td>j) Finally, in the early days of the appstore, I downloaded a game called &#8216;<a href="http://itunes.apple.com/us/app/adams-game-toddler-voice-flash/id294433305?mt=8">Adam&#8217;s Game</a>&#8216; which was a cute flashcard game, but not with a good voice though (accent was hard to understand), but it was pretty nice &#8211; it asked you to identify objects, basically (flash-cards). This was one of the first games my son liked and actually played it often in the first few months.</td>
</tr>
</tbody>
</table>
<p>There are others that many talk about like LunchBox, PreSchool, Adventure, preschoolTap etc. They are all nice too &#8211; they mix some sort of creativity with fun. But I don&#8217;t think they were an essential part of what I saw in my specific instance.</p>
<p><strong>There you have it. My thoughts on digital tools focussed on children.</strong></p>
<p><strong><br />
</strong></p>
<p><strong><br />
</strong></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.roychowdhury.org/2010/12/10/embracing-digital-tools-for-infant-toddler-development-all-in-45-minutes-a-day/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>

