ios MFMessageComposeViewController ipod crash - ios

Hi I am using MFMessageComposeViewController for messaging in an iPhone app.
As this is an iPhone app it also supports iPod. And when clicking on the message button the app crashes as messaging is not available on iPod. So is there a way to check whether the device is an iPod so that i can hide the message button so that the user may not click on message in iPod and crash.
This is the code I have used for messaging.
- (IBAction)Message:(id)sender
{
MFMessageComposeViewController *messaging=[[MFMessageComposeViewController alloc]init];
messaging.messageComposeDelegate=self;
[messaging setBody:#"Will of the People""\n""http://bit.ly/1gZhZye"];
[self presentViewController:messaging animated:YES completion:nil];
}
- (void)messageComposeViewController:(MFMessageComposeViewController *)controller didFinishWithResult:(MessageComposeResult)result
{
[self dismissViewControllerAnimated:YES completion:^{UIAlertView *alert=[[UIAlertView alloc]initWithTitle:#"Done" message:nil delegate:self cancelButtonTitle:#"Close" otherButtonTitles:nil];
[alert show];
}];
}
And this seems to be working fine in iPhone. I need a way to disable this button when the user is using iPod.

You can use the canSendText class method for doing this:
- (IBAction)Message:(id)sender
{
if ([MFMessageComposeViewController canSendText])
{
MFMessageComposeViewController *messaging=[[MFMessageComposeViewController alloc]init];
messaging.messageComposeDelegate=self;
[messaging setBody:#"Will of the People""\n""http://bit.ly/1gZhZye"];
[self presentViewController:messaging animated:YES completion:nil];
}
}
Reference :
canSendText
Returns a Boolean value indicating whether the current device is
capable of sending text messages.
+ (BOOL)canSendText
Return Value
YES if the device can send text messages or NO if it cannot.
Discussion
Always call this method before attempting to present the message
compose view controller. A device may be unable to send messages if it
does not support messaging or if it is not currently configured to
send messages. This method applies only to the ability to send text
messages via iMessage, SMS, and MMS.
To be notified of changes in the availability of sending text
messages, register as an observer of the
MFMessageComposeViewControllerTextMessageAvailabilityDidChangeNotification
notification. Availability
Available in iOS 4.0 and later.
Declared In MFMessageComposeViewController.h

There's a method on MFMEssageComposeViewController:
if ([MFMessageComposeViewController canSendText]) {
}
else {
NSLog(#"Cannot send text");
}

NSString *deviceType = [UIDevice currentDevice].model;
if ([deviceType hasPrefix:#"iPod"])
{
//It's iPod;
//Disable button
}

First detect device by using following way and if device does not support messenger than show alert.
Form here you can get more idea about different device detection :
Determine device (iPhone, iPod Touch) with iPhone SDK
- (IBAction)Message:(id)sender
{
NSString *deviceType = [UIDevice currentDevice].model;
if([deviceType isEqualToString:#"iPod Touch 5G"]) {
// here your alert view to show msg
} else {
if ([MFMessageComposeViewController canSendText])
{
MFMessageComposeViewController *messaging=[[MFMessageComposeViewController alloc]init];
messaging.messageComposeDelegate=self;
[messaging setBody:#"Will of the People""\n""http://bit.ly/1gZhZye"];
[self presentViewController:messaging animated:YES completion:nil];
}
}
}

You can use the UIDevice class to check the device type
NSString *deviceType = [UIDevice currentDevice].model;
if([deviceType hasPrefix:#"iPod"])
// it's an iPod
or you can use [MFMessageComposeViewController canSendText] to check the message can be send from the device or not

-(IBAction)btnByEmailPressed:(id)sender
{
if ([MFMailComposeViewController canSendMail] == NO)
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:nil message:#"This device is not able to send mail or Email account is not configured." delegate:self cancelButtonTitle:#"Close" otherButtonTitles:nil];
[alert show];
return;
}
else
{
MFMailComposeViewController *controller = [[MFMailComposeViewController alloc] init];
controller.mailComposeDelegate = self;
[controller setTitle:#"Invitation"];
[controller setSubject:#"My Subject"];
[controller setMessageBody:#"Your Text" isHTML:YES];
[self presentViewController:controller animated:YES completion:nil];
}
}
- (void)mailComposeController:(MFMailComposeViewController*)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError*)error
{
[self becomeFirstResponder];
NSString *strMailResult;
switch (result)
{
case MFMailComposeResultCancelled:
strMailResult = NSLocalizedString(#"E-Mail Cancelled",#"");
break;
case MFMailComposeResultSaved:
strMailResult = NSLocalizedString(#"E-Mail Saved",#"");
break;
case MFMailComposeResultSent:
strMailResult = NSLocalizedString(#"E-Mail Sent",#"");
break;
case MFMailComposeResultFailed:
strMailResult = NSLocalizedString(#"E-Mail Failed",#"");
break;
default:
strMailResult = NSLocalizedString(#"E-Mail Not Sent",#"");
break;
}
UIAlertView* alertView = [[UIAlertView alloc] initWithTitle:NSLocalizedString(#"STEP-BY-STEP-STORY",#"") message:strMailResult delegate:self cancelButtonTitle:NSLocalizedString(#"OK",#"") otherButtonTitles:nil];
[alertView show];
[self dismissViewControllerAnimated:YES completion:nil];
}

Related

send a message through Xcode programmatically

I am trying to send a message through Xcode programmatically but when I click the send button it opens the message sending box. But I want to send message directly without opening message box. Is this possible in iOS Xcode or not? Please help me.
but don't want open sending message box.
the code is
- (IBAction)sendSMS:(id)sender
{
MFMessageComposeViewController *controller = [[MFMessageComposeViewController alloc] init];
if([MFMessageComposeViewController canSendText])
{
controller.body = #"Hello this is anup";
controller.recipients = [NSArray arrayWithObjects:#"7026144009", nil];
controller.messageComposeDelegate = self;
[self presentModalViewController:controller animated:YES];
}
}
- (void)messageComposeViewController:(MFMessageComposeViewController *)controller didFinishWithResult:(MessageComposeResult)result
{
switch (result)
{
case MessageComposeResultCancelled:
NSLog(#"Cancelled");
break;
case MessageComposeResultFailed:
{
NSLog(#"faild");
UIAlertController *alrt=[UIAlertController alertControllerWithTitle:#"my apps" message:#"unknown error" preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *okAction = [UIAlertAction actionWithTitle:#"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action){
//do something when click button
}];
[alrt addAction:okAction];
break;
}
case MessageComposeResultSent:
break;
default:
break;
}
[self dismissModalViewControllerAnimated:YES];
}
ya it is possible on that your scenario no need of MFMessageComposeViewController, just one webservice is enough, send the two (#"Hello this is anup",#"7026144009") to your backend , the backend developer send the SMS to that particular number using SMTP Server option.
Choice -2
if you want to handle in your own use some thirdparty SDK like skpsmtpmessage, it work like same SMTP.
You can't programatically send a message without the user's content.
The most you can do is open the messages app and if the user decides to send it, he can send it.
You can't programatically send a message without the user's consent. The most you can do, is open the messages app and if the user decides to send it, he can send it.
(IBAction)sendingMessage:(id)sender {
MFMessageComposeViewController *controller = [[MFMessageComposeViewController alloc] init];
if([MFMessageComposeViewController canSendText])
{
controller.body = #"SMS message here";
controller.recipients = [NSArray arrayWithObjects:#"+919015156562", nil];
controller.messageComposeDelegate = self;
[self presentModalViewController:controller animated:YES];
}
}
And:
(void)messageComposeViewController:(MFMessageComposeViewController *)controller
didFinishWithResult:(MessageComposeResult)result {
[self dismissViewControllerAnimated:YES completion:nil];
}

Detecting that SMS failed to be sent on iOS

In my app, it is very important to know whether SMS has been sent or not. For checking, I am using this delegate method:
- (void)messageComposeViewController:(MFMessageComposeViewController *)controller didFinishWithResult:(MessageComposeResult)result{
switch (result) {
case MessageComposeResultCancelled: {
[NSThread detachNewThreadSelector:#selector(SMScancelled) toTarget:self withObject:nil];
}
break;
case MessageComposeResultSent: {
[NSThread detachNewThreadSelector:#selector(SMSsent) toTarget:self withObject:nil];
}
break;
case MessageComposeResultFailed: {
[NSThread detachNewThreadSelector:#selector(SMSfailed) toTarget:self withObject:nil];
}
break;
default:
break;
}
[self dismissViewControllerAnimated:YES completion:nil];
}
My problem is, that when testing, I turn on Airplane mode in settings (to test what will happen) and then I am trying to send SMS (using my app). Naturally, iOS fails to send it and system informs me about that. In message app, it is also shown, that I have failed to send it. But delegate method still returns MessageComposeResultSent instead of MessageComposeResultFailed. This situation also happens when I test on another phone that has no SIM card.
I am testing this on iOS 7 and iOS 8.
In documentation, there is written, that MessageComposeResultSent means "The user successfully queued or sent the message". This means, behaviour I am expecting is correct.
So how to know, whether my last SMS has been succesfully sent, or that sending has failed?
You can verify if the device is allowed to send text message by using the canSendText method of the MFMessageComposeViewController.
Add this below code when you care sending the message (This method detects of your device does not support SMS)
if(![MFMessageComposeViewController canSendText]) {
UIAlertView *warningAlert = [[UIAlertView alloc] initWithTitle:#"Error" message:#"Your device doesn't support SMS!" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[warningAlert show];
return;
}
You can check Message failed by using delegate method of MFMessageComposeViewController
- (void)messageComposeViewController:(MFMessageComposeViewController *)controller didFinishWithResult:(MessageComposeResult) result
{
switch (result) {
case MessageComposeResultCancelled:
break;
case MessageComposeResultFailed:
{
UIAlertView *warningAlert = [[UIAlertView alloc] initWithTitle:#"Error" message:#"Failed to send SMS!" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[warningAlert show];
break;
}
case MessageComposeResultSent:
break;
default:
break;
}
[self dismissViewControllerAnimated:YES completion:nil];
}

Can you send sms without using the native ios application?

I have seen several tutorials to send SMS messages but all open the native iOS message application and what I want is that my application send it without changing application that is sending something invisible to the user.
This is the code I'm using but opens the native application:
#pragma mark - IBAction methods
-(IBAction)sendSMS:(id)sender {
//check if the device can send text messages
if(![MFMessageComposeViewController canSendText]) {
UIAlertView * alert = [[UIAlertView alloc] initWithTitle:#"Advertencia" message:#"Su dispositivo no permite el envio de mensajes SMS" delegate:nil cancelButtonTitle:#"Aceptar" otherButtonTitles:nil];
[alert show];
return;
}
//set receipients - telefonos
NSArray *recipients = [NSArray arrayWithObjects:textNumero.text, nil];
NSLog(#"telefono: %#",recipients);
//set message text
NSString * message = textMensaje.text;
NSLog(#"mensaje: %#",recipients);
MFMessageComposeViewController *messageController = [[MFMessageComposeViewController alloc] init];
messageController.messageComposeDelegate = self;
[messageController setRecipients:recipients];
[messageController setBody:message];
// Present message view controller on screen
[self presentViewController:messageController animated:YES completion:nil];
}
#pragma mark - MFMailComposeViewControllerDelegate methods
- (void)messageComposeViewController:(MFMessageComposeViewController *)controller didFinishWithResult:(MessageComposeResult) result
{
switch (result) {
case MessageComposeResultCancelled:
break;
case MessageComposeResultFailed:
{
UIAlertView *warningAlert = [[UIAlertView alloc] initWithTitle:#"Advertencia" message:#"Ha ocurrido un error en el envio del mensaje" delegate:nil cancelButtonTitle:#"Aceptar" otherButtonTitles:nil];
[warningAlert show];
break;
}
case MessageComposeResultSent:
break;
default:
break;
}
[self dismissViewControllerAnimated:YES completion:nil];
}

iPhone not sending text programmatically

I made a basic app that for now just has a button that you click, and it brings up the sms composer (ios7 and xcode 5). I think I've handled everything well. The simulator doesn't support sending messages, so I tried on my phone, but the message never actually sends. You can click the send button and cancel button fine, but again, the message never sends. Any ideas? Here is my code:
- (IBAction)text:(UIButton *)sender {
MFMessageComposeViewController *messageVC = [[MFMessageComposeViewController alloc] init];
[messageVC setMessageComposeDelegate:self];
if ([MFMessageComposeViewController canSendText]) {
NSString *smsString = [NSString stringWithFormat:#"message to send"];
messageVC.body = smsString;
messageVC.recipients = #[#"number to send to..."];
messageVC.messageComposeDelegate = self;
[self presentViewController:messageVC animated:YES completion:nil];
}
}
- (void)messageComposeViewController:(MFMessageComposeViewController *)controller didFinishWithResult:(MessageComposeResult)result
{
switch (result) {
case MessageComposeResultCancelled:
NSLog(#"Message was cancelled");
[self dismissViewControllerAnimated:YES completion:NULL]; break;
case MessageComposeResultFailed:
NSLog(#"Message failed");
[self dismissViewControllerAnimated:YES completion:NULL]; break;
case MessageComposeResultSent:
NSLog(#"Message was sent");
[self dismissViewControllerAnimated:YES completion:NULL]; break;
default:
break;
}
}
EDIT: So I tried it this morning (I did nothing to it overnight) and it worked. Not sure what the issue was. Thanks though!
I assume the messageVC.recipients is in correct format (array of numbers)?
Try:
//check if the device can send text messages
if(![MFMessageComposeViewController canSendText]) {
UIAlertView * alert = [[UIAlertView alloc] initWithTitle:#"Error" message:#"Your device cannot send text messages" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
return;
}
//set receipients
NSArray *recipients = [NSArray arrayWithObjects:#"0912345679",#"0923456790",#"0934567901", nil];
//set message text
NSString * message = #"this is a test sms message.";
MFMessageComposeViewController *messageController = [[MFMessageComposeViewController alloc] init];
messageController.messageComposeDelegate = self;
[messageController setRecipients:recipients];
[messageController setBody:message];
// Present message view controller on screen
[self presentViewController:messageController animated:YES completion:nil];
Try This In Your MessageCompose Delegate:
(void)messageComposeViewController:(MFMessageComposeViewController *)controller didFinishWithResult:(MessageComposeResult)result
{
switch (result)
{
case MessageComposeResultCancelled:
NSLog(#"Message was cancelled");
break;
case MessageComposeResultFailed:
NSLog(#"Message failed");
break;
case MessageComposeResultSent:
NSLog(#"Message was sent");
break;
default:
break;
}
[controller dismissViewControllerAnimated:YES completion:nil];
}

Texting contacts within an app

I've developed an app that allows the user to text contacts that they add in the app. The problem I'm having is it seems that if the user already exists in the person's native iOS address book, the text will send no problem. But if the contact exists only within the app, the text will not go through. Has anyone else experienced something like this before?
EDIT: Code below
if([MFMessageComposeViewController canSendText])
{
controller.body = #"";
controller.recipients = arrayContactMobileStrings;
controller.messageComposeDelegate = self;
[self presentViewController:controller animated:YES completion:nil];
}
- (void)messageComposeViewController:(MFMessageComposeViewController *)controller didFinishWithResult:(MessageComposeResult)result
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:NSLocalizedString(#"Message not sent", #"") message:NSLocalizedString(#"Error sending message", #"")
delegate:self cancelButtonTitle:NSLocalizedString(#"OK", #"") otherButtonTitles: nil];
switch (result)
{
case MessageComposeResultCancelled:
[alert show];
break;
case MessageComposeResultFailed:
[alert show];
break;
case MessageComposeResultSent:
break;
default:
break;
}
[self dismissViewControllerAnimated:YES completion:nil];
}

Resources