About Me

My photo
Dhaka, Bangladesh
I am B.S.C Engineer,CSE,SUST and Ex-Cadet of Mirzapur Cadet College.

Friday, May 4, 2012

Launching Native Apps: Phone Call, SMS, Email, Map and Browser

Every iphone application uses the native apps frequently. So, we shall deal with them sooner than later. I am implementing the openURL project from http://appsamuck.com/day3.html in my own way.

We shall deal with phone call, SMS, Email, Map and Browser.  I must say that we can not test phone call and SMS in simulator(Later we shall learn to port an app in iphone).

Let get on to it straight on.

Step1: We shall open up a project in Xcode named "openURL" as a "View-based Application"
Step2: Lets plan how we are going to do it.

We are going to need five buttons "UIButton" and five methods(??) that will implement the button action. As declaring a method with (IBAction) return type we can tell the compiler that it is associated with a button. At the same time, we can send the "sender" as an id so that we can determine from which button the method is been called. This id type object "sender" is sent as a perimeter of the method.  And interface builder shall not recognize it or let us associate a method with a button as long as its return type is NOT IBAction.

We are gonna use the interface builder to place the button. So, we shall let the compiler understand it by declaring the buttons as IBOutlet.

Without using the interface builder, we could declare a UIButton as followed[We are not gonna do it this way in this example project]

//Declared button type as Round Rect Button
UIButton *myButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
//Button position and size defined(x, y, height, width)
myButton.frame = CGRectMake(80, 50, 150, 40);
// We are telling compiler what method should be invoked when the button is Touched up inside.
[myButton addTarget:self action:@selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside];
//The following buttonClicked method shall be called in this case

- (IBAction)buttonClicked:(id)sender
{
    NSLog(@"Hi!");

}

Step3: We are going to add five buttons using interface builder and associate a tag with each one. A tag is an integer value and it will help us to detect from what button the method is being called and do something accordingly. We will also add the titles of the buttons using interface builder.




Step4: We shall open up the Xcode and start writing code on openURLViewContorller files as followed.

openURLViewContorller.h 



@interface openURLViewController : UIViewController
{
IBOutlet UIButton *btnActivatePhoneCall;
IBOutlet UIButton *btnActivateSMS;
IBOutlet UIButton *btnActivateEmail;
IBOutlet UIButton *btnActivateMap;
IBOutlet UIButton *btnActivateBrowser;

}

- (IBAction) activateAction: (id) sender;
@end



openURLViewContorller.m



(IBAction) activateAction: (id) sender
{
if ([sender tag] == 0
{
NSLog(@"Phone Call Button");
}
else if([sender tag] == 1)
{
NSLog(@"SMS Button");
}
else if ([sender tag] == 2)
{
NSLog(@"Email Button");
}
else if([sender tag] == 3)
{
NSLog(@"Map Button");
}
else 
{
//sender== btnActivateBrowser
NSLog(@"Browser Button");
}

}

Remember, we associated tags with those buttons and we are reading them by using [sender tag]. 

We are using NSLog just to verify whether our plan is working or not.

N.B. We are not doing getter/setter or property declaration and synthesizing for the buttons. We must remember that only to those UI Elements must be performed property declaration and synthesizing, who are gonna change its property(i.e. title, font color, text) in run time or by another action(a button action or a method action or something).

Step5: We are going to open the Interface Builder again and associating the buttons with the method activateAction







Step6: SMS and Email needs to implement two delegates MFMessageComposeViewControllerDelegate, MFMailComposeViewControllerDelegate, we need to add a frame work named"MessageUI.framework" as well for Email as well. We need to implement following methods as well in .m file and need add headers (MessageUI/MessageUI.h  and MessageUI/MFMailComposeViewController.h ) as well.

6.1. Declaring Delegates
openURLViewController.h

@interface openURLViewController : UIViewController
{
IBOutlet UIButton *btnActivatePhoneCall;
IBOutlet UIButton *btnActivateSMS;
IBOutlet UIButton *btnActivateEmail;
IBOutlet UIButton *btnActivateMap;
IBOutlet UIButton *btnActivateBrowser;

}

- (IBAction) activateAction: (id) sender;
@end 

6.2. Implement Delegate Methods

openURLViewController.m


- (void)messageComposeViewController:(MFMessageComposeViewController *)controller didFinishWithResult:(MessageComposeResult)result 
{
    [self dismissModalViewControllerAnimated:YES];
}

-(void)mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError*)error 
{
[self dismissModalViewControllerAnimated:YES];
}

6.3. Include Framework







6.4. Declare Header Files

openURLViewController.h



#import
#import

#import


@interface openURLViewController : UIViewController 
{
IBOutlet UIButton *btnActivatePhoneCall;
IBOutlet UIButton *btnActivateSMS;
IBOutlet UIButton *btnActivateEmail;
IBOutlet UIButton *btnActivateMap;
IBOutlet UIButton *btnActivateBrowser;

}

- (IBAction) activateAction: (id) sender;
@end

Step7: Now, to make a phone call to cell number 12125551212 we shall add the following code inside the if statement ([sender tag] == 0)  of activateAction method. 

[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"tel:12125551212"]];


We shall be able to test in iphone, but NOT IN SIMULATOR!!!


Step8: Now, to send SMS we shall add the following code inside the if statement ([sender tag] == 1)  of activateAction method. 

if ([NSClassFromString(@"MFMessageComposeViewController") canSendText]) 
{
      [self presentMessageComposeViewController];

[NSClassFromString(@"MFMessageComposeViewController"canSendTextreturns true if the current device is capable of operating SMS feature and returns false if it doesn't. 

And we need to name the presentMessageComposeViewController method in .h file of the viewController and implement it in .m file.

-(void) presentMessageComposeViewController 
{
     id smsViewController = [[NSClassFromString(@"MFMessageComposeViewController") alloc] init];
     [smsViewController setTitle:NSLocalizedString(@"Your Title",nil)];
     [smsViewController setBody:NSLocalizedString(@"Your Message. urls work too www.example.com",nil)];
     [smsViewController setMessageComposeDelegate: (id)self];
     [self presentModalViewController:smsViewController animated:YES];
     [smsViewController release];
}

We shall be able to test in iphone, but NOT IN SIMULATOR!!!

Step9: 
Now, to send Email we shall add the following code inside the if statement ([sender tag] == 2)  of activateAction method. 



if ([MFMailComposeViewController canSendMail])
{
[self sendEmail];
}
else 
{
        NSLog(@"Device is unable to send email in its current state.");
}


[MFMailComposeViewController canSendMail] returns true if the current device is capable of operating Email feature and returns false if it doesn't. 

And we need to name the sendEmail method in .h file of the viewController and implement it in .m file.

- (void) sendEmail
{
MFMailComposeViewController *mailViewController = [[MFMailComposeViewController alloc] init];
mailViewController.mailComposeDelegate = self;
[mailViewController setSubject:@"Subject Goes Here."];
[mailViewController setMessageBody:@"Your message goes here." isHTML:NO];
[self presentModalViewController:mailViewController animated:YES];
[mailViewController release];
}



If we wanted the app to quit the present app and open up the default Email app we could simply write

[[UIApplication sharedApplication] openURL: @"mailto:john.appleseed@apple.com"];



We shall be able to test in simulator and it should look as followed image.




Step10: Now, to open up the city of "London" in MAP we shall add the following code inside the if statement ([sender tag] == 3)  of activateAction method. 


[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"http://maps.google.com/maps?q=London"]];


We shall be able to test in SIMULATOR and it shall look like as followed image!!!




Step11: Now, to open up the URL "www.google.com" in Browser we shall add the following code inside the else statement of activateAction method. 


[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"http://www.google.com/"]];


We shall be able to test in SIMULATOR and it shall look like as followed image!!!

Adios Amigos!!!


1 comment:

Sajid said...

your tutorial is good
but its 2am in the morning I'm tired i got a 12 hr day at work tomorrow yet u write such good tutorial but did not even think about formatting it correct

seriously ur documentation sucks