Thursday, February 10, 2011

Sending In-App SMS

With the release of iPhone OS 3, a new feature to allow sending of in-app email was introduced. And now in iOS 4, a similar way of sending in-app SMS is introduced.

Prior to iOS 4, developers have to depend on:
[[UIApplication sharedApplication] openURL: @"sms:99999999"];

It has various limitations. First, it just closes your app (or sends it in background) and opens the default SMS application. Secondly, there was no way to specify the body content of the SMS. Then, it also restricts you to send the SMS to only one person.

However, with the new MessageUI SMS Controller, users can send SMS without quitting the app.

Step 1
Import the MessageUI Framework into your project and #import the header file into the “.h” file of your controller where you want to open the In-App SMS sheet.

Step 2
You would need a button handler IBAction where you want to send the SMS. If you don't have it, create a Button on your XIB file and write IBActions for it.

Step 3
Now connect the above button to this method to fire this action on "On Touch Up" event.
-(IBAction) sendInAppSMS:(id) sender
MFMessageComposeViewController *controller = [[[MFMessageComposeViewController alloc] init] autorelease];
if([MFMessageComposeViewController canSendText])
controller.body = @"Test message for in-app SMS";
controller.recipients = [NSArray arrayWithObjects:@"98765432", @"19283746", nil];
controller.messageComposeDelegate = self;
[self presentModalViewController:controller animated:YES];

The above block of code is self-explanatory. The most important part here is the line [MFMessageComposeViewController canSendText].
Before trying to send an in-app SMS you would always need to make sure that the device is capable to do it or not. For eample, iPhone OS 3 devices and iPod touch don't have the ability to send in-app SMS.
In this case, I have used a if condition to send the SMS. Practically speaking, you should enable/disable the button the user taps to send the sms based on this. You can add the code that does this in your viewDidLoad method.

Secondly, you have to set the messageComposeDelegate to self and not delegate. If you set the controller.delegate to self, you will not get the didFinishWithResult callback and the In-App SMS sheet will not close.

Step 4
Implement Delegate Callbacks.
In your header file, implement the callbacks, MFMessageComposeViewControllerDelegate and UINavigationControllerDelegate. If you don’t you will get a warning at the line,
controller.delegate = self;

You have to handle a callback method of MFMessageComposeViewControllerDelegate so as to dismiss the modal view controller.
- (void)messageComposeViewController:(MFMessageComposeViewController *)controller didFinishWithResult:(MessageComposeResult)result
switch (result) {
case MessageComposeResultCancelled:
case MessageComposeResultFailed:
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"IN-app SMS" message:@"Some Error occurred"
delegate:self cancelButtonTitle:@”OK” otherButtonTitles: nil];
[alert show];
[alert release];
case MessageComposeResultSent:
NSLog(@"Message sent successfully");

[self dismissModalViewControllerAnimated:YES];

That’s it. Your app should now be able to send SMS using the new Message UI sheet.

Note: As of today, the MFMessageComposeViewController doesn't support sending MMS. The controller.body is a NSString and setting a NSData pointer obviously crashes the app. Hopefully, one day, Apple will allow sending In-App MMS. Happy Coding till then...