Saturday, November 20, 2010

Sorting NSMutableArray of NSDictionary

NSString * NAME = @"name";
NSString * ADDRESS = @"address";
NSString * FREQUENCY = @"frequency";
NSString * TYPE = @"type";

NSMutableArray * array = [NSMutableArray array];

NSDictionary * dict;

dict = [NSDictionary dictionaryWithObjectsAndKeys:
@"Alehandro", NAME, @"Sydney", ADDRESS,
[NSNumber numberWithInt:100], FREQUENCY,
@"T", TYPE, nil];
[array addObject:dict];

dict = [NSDictionary dictionaryWithObjectsAndKeys:
@"Xentro", NAME, @"Melbourne", ADDRESS,
[NSNumber numberWithInt:50], FREQUENCY,
@"X", TYPE, nil];
[array addObject:dict];

dict = [NSDictionary dictionaryWithObjectsAndKeys:
@"John", NAME, @"Perth", ADDRESS,
[NSNumber numberWithInt:75],
FREQUENCY, @"A", TYPE, nil];
[array addObject:dict];

dict = [NSDictionary dictionaryWithObjectsAndKeys:
@"Fjord", NAME, @"Brisbane", ADDRESS,
[NSNumber numberWithInt:20], FREQUENCY,
@"B", TYPE, nil];
[array addObject:dict];


Sorting part using descriptors with the Frequency field which is NSNumber:

NSSortDescriptor * frequencyDescriptor =
[[[NSSortDescriptor alloc] initWithKey:FREQUENCY
ascending:YES] autorelease];

id obj;
NSEnumerator * enumerator = [array objectEnumerator];
while ((obj = [enumerator nextObject])) NSLog(@"%@", obj);

NSArray * descriptors =
[NSArray arrayWithObjects:frequencyDescriptor, nil];
NSArray * sortedArray =
[array sortedArrayUsingDescriptors:descriptors];

NSLog(@"\nSorted Array ..");

enumerator = [sortedArray objectEnumerator];
while ((obj = [enumerator nextObject])) NSLog(@"%@", obj);


OUTPUT - sorted by Frequency field
2009-12-04 x[1] {address = Sydney; frequency = 100; name = Alehandro; type = T; }
x[1] {address = Melbourne; frequency = 50; name = Xentro; type = X; }
x[1] {address = Perth; frequency = 75; name = John; type = A; }
x[1] {address = Brisbane; frequency = 20; name = Fjord; type = B; }
Sorted Array ..
x[1] {address = Brisbane; frequency = 20; name = Fjord; type = B; }
x[1] {address = Melbourne; frequency = 50; name = Xentro; type = X; }
x[1] {address = Perth; frequency = 75; name = John; type = A; }
x[1] {address = Sydney; frequency = 100; name = Alehandro; type = T; }

Friday, November 5, 2010

Launching Your Own Application via a Custom URL Scheme

How to open other applications like phone dialer, SMS, Safari, Google Maps, iTunes or AppStore or any other iPhone application?

“openURL” is the API to use to achieve any of the above and many more.
Examples of some of the key applications that you can launch via URL are:
1. Launch the Browser
2. Launch Google Maps
3. Dial a Phone Number
4. Launch the SMS Application
5. Launch Apple Mail
6. Launch the AppStore

Launch the Browser
Here is a simple example of how to open Safari with a specific URL:
NSURL *url = [NSURL URLWithString:@"http://anuragsolanki.com"];
[[UIApplication sharedApplication] openURL:url];


Launch Google Maps
The URL string for launching Google Maps with a particular keyword follows this structure:
http://maps.google.com/maps?q=${QUERY_STRING}

The only trick to this is to ensure that the value for the ${QUERY_STRING} is properly URL encoded. Here is a quick example of how you would launch Google Maps for a specific address:
// Create your query ...
NSString* searchQuery = @"1 Infinite Loop, Cupertino, CA 95014";

// Be careful to always URL encode things like spaces and other symbols that aren't URL friendly
searchQuery = [addressText stringByAddingPercentEscapesUsingEncoding: NSUTF8StringEncoding];

// Now create the URL string ...
NSString* urlString = [NSString stringWithFormat:@"http://maps.google.com/maps?q=%@", searchQuery];

// An the final magic ... openURL!
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:urlText]];


Dial a Phone Number (available in iPhone only)
You can use openURL: to dial a phone number. One advantage this has over other URLs that launch applications, is that the dialer will return control back to the application when the user hits the “End Call” button.
The URL scheme for this is:
tel://${PHONE_NUMBER}

Here is an example of how we would dial the number (800) 846-6802:
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"tel://8008466802"]];


NOTE: Country code also needs to be including while dialing an international number

Launch the SMS Application (iPhone only)
It provides the ability to quickly setup the SMS client so that your users can quickly send a text message.

The format looks like this:
sms:${PHONENUMBER_OR_SHORTCODE}

Here is an example which shows to send an SMS. Note that an SMS url doesn't use the "//" syntax.
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"sms:55555"]];


Launch Apple Mail
Also very useful, is the ability to enable a user to quickly send an email by launching the email client in compose mode and the address already filled out. The format of this URI should be familiar to anyone that has done any work with HTML and looks like this:

mailto://${EMAIL_ADDRESS}

For example, here we are opening the email application and filling the “to:” address with anurag@apple.com :
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"mailto://anurag@apple.com"]];


Launching the AppStore
Initially, it is worth noting that you can launch the AppStore and have the "buy" page of a specific application appear. To do this, there is no special URL scheme. All you need to do is open up iTunes to the application you want to launch; right-click on the application icon at the top left of the page; and select Copy iTunes Store URL.

The URL will look something like this:
http://itunes.apple.com/in/app/mystockcomp/id358765855?mt=8

Launching the AppStore URL is exactly the same as you would launch the browser. Using the link above, here is an example of how we would launch the AppStore:
NSURL *appStoreUrl = [NSURL URLWithString:@"http://itunes.apple.com/in/app/mystockcomp/id358765855?mt=8"];
[[UIApplication sharedApplication] openURL:appStoreUrl];

Friday, October 29, 2010

Code Snippet: Prevent The iPhone From Sleeping

The code below will prevent the iPhone from dimming its screen and ultimately going to sleep. Use it wisely as you don’t want your application becoming notorious for being a battery hog

[UIApplication sharedApplication].idleTimerDisabled = YES;

Wednesday, July 28, 2010

How to Save the Contents of an Array to the iPhone’s Filesystem


The simplest way to save user preference/data on iPhone is using NSUserDefaults. Here comes another easy way to save data in filesystem.

In this example, we are going to create an array, fill it with values and then save the contents of the array to the documents directory of our app.

Then, after stopping the program and putting in code, we will retrieve the array from the filesystem. Finally, to prove that it all worked we will use an alert box to inform the user of what is in the array that we stored.

First, in the applicationDidFinishLaunching method put in this code:
//get the documents directory:
NSArray *paths = NSSearchPathForDirectoriesInDomains
(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];

//make a file name to write the data to using the
//documents directory:
NSString *fullFileName = [NSString stringWithFormat:@"%@/newFileArray", documentsDirectory];

//create an array and add values to it:
NSMutableArray *array = [[NSMutableArray alloc] init];
[array addObject:@"First string"];
[array addObject:@"Second string"];
[array addObject:@"Third string"];

//this statement is what actually writes out the array
//to the file system:
[array writeToFile:fullFileName atomically:NO];

Now, your information has been saved to the iPhone’s file system in the documents directory of your app. Here is how you would retrieve the information that you saved:
//get the documents directory:
NSArray *paths = NSSearchPathForDirectoriesInDomains
(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];

//make a file name to write the data to using the
//documents directory:
NSString *fullFileName = [NSString stringWithFormat:@"%@/newFileArray", documentsDirectory];

//retrieve your array by using initWithContentsOfFile while passing
//the name of the file where you saved the array contents.
NSMutableArray *array = [[NSMutableArray alloc] initWithContentsOfFile:fullFileName];
NSLog(@"%@", array);

That's it – a quick and easy way to save information on the iPhone. The array is easily saved and retrieved from iPhone filesystem.

Tuesday, July 13, 2010

UIAlertView with a TextField within it

Every iphone developer would have seen default alert view with a title, a message and buttons to dismiss the alert view. Today I will show an option to insert an UITextField inside a UIAlerView.

We will basically call a UIAlertView and then add the UITextField programmatically.

UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@”Enter Your Name” message:@”message hidden by text field” delegate:self cancelButtonTitle:@”Dismiss” otherButtonTitles:@”OK!”, nil];
UITextField *textField = [[UITextField alloc] initWithFrame:CGRectMake(12, 45, 260, 25)];
CGAffineTransform myTransform = CGAffineTransformMakeTranslation(0, 60);
[alert setTransform:myTransform];
[myTextField setBackgroundColor:[UIColor whiteColor]];
[alert addSubview:myTextField];
[alert show];
[alert release];
[myTextField release];


We are including a dummy message in the alert view because it's position will be occupied by our textfield. If we didn’t put that sentence then the alerts buttons would go up more and the UITextField will be messed up.

Next thing that we have used is CGAffineTransform. It is used because on focusing on the textfield, keyboard appears and covers some part of our UITextField. Hence this transform ensures that keyboard doesn't covers it up.

Now build and Run the application. You will get a screen as below.

Thursday, May 13, 2010

iPhone: How to Open the Mail App With a Pre-Composed HTML Email

Have you ever wanted to open the Mail app with a pre-composed email? Then today’s iPhone development tip is the one for you! This has many uses, but a common one is a tell-a-friend feature in apps. If you attach the code from this tip to a button, you can give your users a way to promote your app to their friends via the iPhone’s built in Mail app.

A Handy Function
The sendEmailTo function, seen below, can be included in any view controller of your app. This function gives you a simple interface to send emails. It allows you to define “to” addresses, “cc” addresses, “bcc” addresses, a subject and a body. The body supports HTML tags.

- (void)sendEmailTo:(NSString*)to withCC:(NSString*)cc withBCC:(NSString*)bcc withSubject:(NSString*)subject withBody:(NSString*)body {
NSString * url = [NSString stringWithFormat:@"mailto:?to=%@&cc=%@&bcc=%@&subject=%@&body=%@",
[to stringByAddingPercentEscapesUsingEncoding:NSASCIIStringEncoding],
[cc stringByAddingPercentEscapesUsingEncoding:NSASCIIStringEncoding],
[bcc stringByAddingPercentEscapesUsingEncoding:NSASCIIStringEncoding],
[subject stringByAddingPercentEscapesUsingEncoding:NSASCIIStringEncoding],
[body stringByAddingPercentEscapesUsingEncoding:NSASCIIStringEncoding]];

[[UIApplication sharedApplication] openURL:[NSURL URLWithString:url]];
}


PS: Running this function in the iPhone Simulator will have no effect because the simulator does not include the iPhone’s Mail app. To see the effects of this function, it must be run on a device.

Example
The following example opens the Mail app and pre-populates the to, cc, bcc and other fields in it.
[self sendEmailTo:@"friend@example.com"
withCC:@"relative@example.com"
withBCC:@"secret-friend@example.com"
withSubject:@"Blog"
withBody:@"Check out my new blog, here."];


You could also leave some of these fields blank if you want user to specify and fill those.
[self sendEmailTo:@""
withCC:@""
withBCC:@""
withSubject:@"Blog"
withBody:@"Check out my new blog, here"];

Wednesday, March 17, 2010

Sound Format Conversion in iPhone

Since iPhone supports only following data formats for audion files:

* linear PCM
* MA4 (IMA/ADPCM)
* µLaw
* aLaw

You may use the afconvert tool to convert sounds. For example, to convert the 16-bit linear PCM system sound Submarine.aiff to IMA4 audio in a CAF file, use the following command in the Terminal application:

afconvert /System/Library/Sounds/Submarine.aiff ~/Desktop/sub.caf -d ima4 -f caff -v

You can inspect a sound to determine its data format by opening it in QuickTime Player and choosing Show Movie Inspector from the Movie menu.

Getting a screenshot of any View Programmatically

Place the code shown here in the main file of your view controller
-(IBAction)captureScreen:(id)sender
{
UIGraphicsBeginImageContext(foobar.frame.size);
[self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIImageWriteToSavedPhotosAlbum(viewImage, nil, nil, nil);
}

Here foobar is considered the UIView subclass which has the screen to be captured in the screenshot.

Save UIImage Object as a PNG or JPEG File

UIKit includes two C functions, UIImageJPEGRepresentation and UIImagePNGRepresentation which will return an NSData object that represents an image in JPEG or PNG format, respectively. With this information in hand, you can then use the writeToFile method of the NSData object to write the image data to a specified path.

// Create paths to output images
NSString *pngPath = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents/TestImage.png"];
NSString *jpgPath = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents/TestImage.jpg"];

// Write a UIImage to JPEG with minimum compression (best quality)
// The value 'image' must be a UIImage object
// The value '1.0' represents image compression quality as value from 0.0 to 1.0
[UIImageJPEGRepresentation(image, 1.0) writeToFile:jpgPath atomically:YES];

// Write image to PNG
[UIImagePNGRepresentation(image) writeToFile:pngPath atomically:YES];

// Let's check to see if files were successfully written...

// Create file manager
NSError *error;
NSFileManager *fileMgr = [NSFileManager defaultManager];

// Point to Document directory
NSString *documentsDirectory = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents"];

// Write out the contents of home directory to console
NSLog(@"Documents directory: %@", [fileMgr contentsOfDirectoryAtPath:documentsDirectory error:&error]);


One last note, this application will only run on an actual device as the simulator does not have camera support.