How to programmatically send SMS on the iPhone?
Asked Answered
D

18

546

Does anybody know if it's possible, and how, to programmatically send a SMS from the iPhone, with the official SDK / Cocoa Touch?

Distemper answered 14/8, 2008 at 9:51 Comment(3)
in Ios 4 You can send sms with code but problem is your application will be closedMatusow
If using the official SDK is not a requirement for others, I wrote this post to show how to do this using Twilio: twilio.com/blog/2016/11/…Quinquepartite
you can create a google spreadsheet off of your gmail, make the fields you want, then do tools->script editor and in a POST request use MailApp.sendEmail api to send email to a phone number. att's is [email protected], tmobile's is [email protected] I think (ALL FREE)Surcease
C
418

Restrictions

If you could send an SMS within a program on the iPhone, you'll be able to write games that spam people in the background. I'm sure you really want to have spams from your friends, "Try out this new game! It roxxers my boxxers, and yours will be too! roxxersboxxers.com!!!! If you sign up now you'll get 3,200 RB points!!"

Apple has restrictions for automated (or even partially automated) SMS and dialing operations. (Imagine if the game instead dialed 911 at a particular time of day)

Your best bet is to set up an intermediate server on the internet that uses an online SMS sending service and send the SMS via that route if you need complete automation. (ie, your program on the iPhone sends a UDP packet to your server, which sends the real SMS)

iOS 4 Update

iOS 4, however, now provides a viewController you can import into your application. You prepopulate the SMS fields, then the user can initiate the SMS send within the controller. Unlike using the "SMS:..." url format, this allows your application to stay open, and allows you to populate both the to and the body fields. You can even specify multiple recipients.

This prevents applications from sending automated SMS without the user explicitly aware of it. You still cannot send fully automated SMS from the iPhone itself, it requires some user interaction. But this at least allows you to populate everything, and avoids closing the application.

The MFMessageComposeViewController class is well documented, and tutorials show how easy it is to implement.

iOS 5 Update

iOS 5 includes messaging for iPod touch and iPad devices, so while I've not yet tested this myself, it may be that all iOS devices will be able to send SMS via MFMessageComposeViewController. If this is the case, then Apple is running an SMS server that sends messages on behalf of devices that don't have a cellular modem.

iOS 6 Update

No changes to this class.

iOS 7 Update

You can now check to see if the message medium you are using will accept a subject or attachments, and what kind of attachments it will accept. You can edit the subject and add attachments to the message, where the medium allows it.

iOS 8 Update

No changes to this class.

iOS 9 Update

No changes to this class.

iOS 10 Update

No changes to this class.

iOS 11 Update

No significant changes to this class

Limitations to this class

Keep in mind that this won't work on phones without iOS 4, and it won't work on the iPod touch or the iPad, except, perhaps, under iOS 5. You must either detect the device and iOS limitations prior to using this controller, or risk restricting your app to recently upgraded 3G, 3GS, and 4 iPhones.

However, an intermediate server that sends SMS will allow any and all of these iOS devices to send SMS as long as they have internet access, so it may still be a better solution for many applications. Alternately, use both, and only fall back to an online SMS service when the device doesn't support it.

Cartomancy answered 12/9, 2008 at 15:0 Comment(9)
And if you purchase that domain I will never be able to look at you the same way again.Cartomancy
I think it's ironic that somebody flagged this post as spam. Read between the lines, peoples!Wily
-1 because this reads as speculation. Also, see Jus' Wondrin''s and rydgaze's answers on how to send in-app SMSes.Thundercloud
@Frank - Updated my writeup to reflect the new iOS 4 features. Removed wishy-washy wording.Cartomancy
I know this is very late but is it possible to send a message with a photo as an attachment?Inness
Added to this could be, that in iOS5 Apple don't send SMS as Adam is speculating, they use iMessage with devices that is not inherently a phone.Bolivar
@edhedges, yours should be a new question, not a comment.Alisonalissa
I really appreciate that you keep this post updated for new iOS versions. :)Hartzke
I need to send an sms to a specific number but with predefined (prefill) body text. Thos body text should be the manual selection from 4 possible options. E.g. The app opens and pop-ups "select reason". Then 4 options are available. Next the user selects one of these 4 options and then an automatic SMS is sent having as body text the choice of the user. Any tip?Chor
F
146

Here is a tutorial which does exactly what you are looking for: the MFMessageComposeViewController.

http://blog.mugunthkumar.com/coding/iphone-tutorial-how-to-send-in-app-sms/

Essentially:

MFMessageComposeViewController *controller = [[[MFMessageComposeViewController alloc] init] autorelease];
if([MFMessageComposeViewController canSendText])
{
    controller.body = @"SMS message here";
    controller.recipients = [NSArray arrayWithObjects:@"1(234)567-8910", nil];
    controller.messageComposeDelegate = self;
    [self presentModalViewController:controller animated:YES];
}

And a link to the docs.

https://developer.apple.com/documentation/messageui/mfmessagecomposeviewcontroller

Fortification answered 24/7, 2010 at 19:9 Comment(4)
still, the SMS form has to pop up. Any way to send in background?Goaltender
You can certainly send SMS in the background using a service such as Twilio, but if you want to send it from the user's phone number, they have to approve the message via the above method.Fortification
anyone using the above code may wish to consider putting the MFMessageComposeViewController *controller = ... inside the if block. (the class method does not need to have an instance to do the test)Weld
The link http://blog.mugunthkumar.com/coding/iphone-tutorial-how-to-send-in-app-sms/ says "502 Bad Gateway" on my laptop. Maybe the link is broken.Hyacinthie
R
100
  1. You must add the MessageUI.framework to your Xcode project
  2. Include an #import <MessageUI/MessageUI.h> in your header file
  3. Add these delegates to your header file MFMessageComposeViewControllerDelegate & UINavigationControllerDelegate
  4. In your IBAction method declare instance of MFMessageComposeViewController say messageInstance
  5. To check whether your device can send text use [MFMessageComposeViewController canSendText] in an if condition, it'll return Yes/No
  6. In the if condition do these:

    1. First set body for your messageInstance as:

      messageInstance.body = @"Hello from Shah";
      
    2. Then decide the recipients for the message as:

      messageInstance.recipients = [NSArray arrayWithObjects:@"12345678", @"87654321",         nil];
      
    3. Set a delegate to your messageInstance as:

      messageInstance.messageComposeDelegate = self;
      
    4. In the last line do this:

      [self presentModalViewController:messageInstance animated:YES];
      
Rickirickie answered 7/12, 2011 at 16:50 Comment(2)
Version note: presentModalViewController:animated: is deprecated; use presentViewController:animated:completion: instead. Also, remember to define the delegate method - (void)messageComposeViewController:(MFMessageComposeViewController *)controller didFinishWithResult:(MessageComposeResult)result if you want to know the results.Goaltender
Please put the code for test. @Najeebullah Shah here or in github.Asperity
E
49

You can use a sms:[target phone number] URL to open the SMS application, but there are no indications on how to prefill a SMS body with text.

Elsa answered 12/9, 2008 at 14:41 Comment(3)
react-native-communications uses the &body= parameter to prefill the text when opening the sms:targetphonenumber&body=textyouwanttoprefillwith for iOSIrreparable
I just tried this on my iphone 8, and it worked great... thanks!Mediative
I need to send an sms to a specific number but with predefined (prefill) body text. Thos body text should be the manual selection from 4 possible options. E.g. The app opens and pop-ups "select reason". Then 4 options are available. Next the user selects one of these 4 options and then an automatic SMS is sent having as body text the choice of the user. any tip?Chor
P
25

One of the systems of inter-process communication in MacOS is XPC. This system layer has been developed for inter-process communication based on the transfer of plist structures using libSystem and launchd. In fact, it is an interface that allows managing processes via the exchange of such structures as dictionaries. Due to heredity, iOS 5 possesses this mechanism as well.

You might already understand what I mean by this introduction. Yep, there are system services in iOS that include tools for XPC communication. And I want to exemplify the work with a daemon for SMS sending. However, it should be mentioned that this ability is fixed in iOS 6, but is relevant for iOS 5.0—5.1.1. Jailbreak, Private Framework, and other illegal tools are not required for its exploitation. Only the set of header files from the directory /usr/include/xpc/* are needed.

One of the elements for SMS sending in iOS is the system service com.apple.chatkit, the tasks of which include generation, management, and sending of short text messages. For the ease of control, it has the publicly available communication port com.apple.chatkit.clientcomposeserver.xpc. Using the XPC subsystem, you can generate and send messages without user's approval. 

Well, let's try to create a connection.

xpc_connection_t myConnection;

dispatch_queue_t queue = dispatch_queue_create("com.apple.chatkit.clientcomposeserver.xpc", DISPATCH_QUEUE_CONCURRENT);

myConnection = xpc_connection_create_mach_service("com.apple.chatkit.clientcomposeserver.xpc", queue, XPC_CONNECTION_MACH_SERVICE_PRIVILEGED);

Now we have the XPC connection myConnection set to the service of SMS sending. However, XPC configuration provides for creation of suspended connections —we need to take one more step for the activation.

xpc_connection_set_event_handler(myConnection, ^(xpc_object_t event){
xpc_type_t xtype = xpc_get_type(event);
if(XPC_TYPE_ERROR == xtype)
{
NSLog(@"XPC sandbox connection error: %s\n", xpc_dictionary_get_string(event, XPC_ERROR_KEY_DESCRIPTION));
}
// Always set an event handler. More on this later.

NSLog(@"Received a message event!");

});

xpc_connection_resume(myConnection);

The connection is activated. Right at this moment iOS 6 will display a message in the telephone log that this type of communication is forbidden. Now we need to generate a dictionary similar to xpc_dictionary with the data required for the message sending.

NSArray *recipient = [NSArray arrayWithObjects:@"+7 (90*) 000-00-00", nil];

NSData *ser_rec = [NSPropertyListSerialization dataWithPropertyList:recipient format:200 options:0 error:NULL];

xpc_object_t mydict = xpc_dictionary_create(0, 0, 0);
xpc_dictionary_set_int64(mydict, "message-type", 0);
xpc_dictionary_set_data(mydict, "recipients", [ser_rec bytes], [ser_rec length]);
xpc_dictionary_set_string(mydict, "text", "hello from your application!");

Little is left: send the message to the XPC port and make sure it is delivered.

xpc_connection_send_message(myConnection, mydict);
xpc_connection_send_barrier(myConnection, ^{
NSLog(@"The message has been successfully delivered");
});

That's all. SMS sent.

Peremptory answered 25/10, 2012 at 7:17 Comment(3)
You shouldn't use XPC to send SMS. The App produced won't be approved by Apple. Use MessageUI Framework insteadGoaltender
If you are using this techinique for app that you use for your organisation, and app is not going through app store, you have no worries.Trilogy
Getting "XPC sandbox connection error: Connection invalid" on iOS 12Trilogy
A
24

Add the MessageUI.Framework and use the following code

#import <MessageUI/MessageUI.h> 

And then:

if ([MFMessageComposeViewController canSendText]) {
  MFMessageComposeViewController *messageComposer =
  [[MFMessageComposeViewController alloc] init];
  NSString *message = @"Your Message here";
  [messageComposer setBody:message];
  messageComposer.messageComposeDelegate = self;
  [self presentViewController:messageComposer animated:YES completion:nil];
}

and the delegate method -

- (void)messageComposeViewController:(MFMessageComposeViewController *)controller
             didFinishWithResult:(MessageComposeResult)result {
      [self dismissViewControllerAnimated:YES completion:nil];
 }
Approach answered 10/5, 2013 at 21:38 Comment(2)
hey thats great , but can we do this functionality from background?Notch
Apple will not allow you to send message without users approval. He has to send message/mail by manually pressing the button. Alternatively, you can use a custom service by sending emails/numbers to your backend and then sending. Though you cannot do this directly on iPhoneApproach
T
21

You can use this approach:

[[UIApplication sharedApplication]openURL:[NSURL URLWithString:@"sms:MobileNumber"]]


iOS will automatically navigate from your app to the messages app's message composing page. Since the URL's scheme starts with sms:, this is identified as a type that is recognized by the messages app and launches it.

Tile answered 26/2, 2014 at 7:13 Comment(0)
E
14

Follow this procedures

1 .Add MessageUI.Framework to projectenter image description here

2 . Import #import <MessageUI/MessageUI.h> in .h file.

3 . Copy this code for sending message

 if ([MFMessageComposeViewController canSendText]) {
    MFMessageComposeViewController *messageComposer =
    [[MFMessageComposeViewController alloc] init];
    NSString *message = @"Message!!!";
    [messageComposer setBody:message];
    messageComposer.messageComposeDelegate = self;
    [self presentViewController:messageComposer animated:YES completion:nil];
}

4 . Implement delegate method if you want to.

- (void)messageComposeViewController:(MFMessageComposeViewController *)controller didFinishWithResult:(MessageComposeResult)result{


   ///your stuff here 

    [self dismissViewControllerAnimated:YES completion:nil];
}

Run And GO!

Export answered 29/7, 2014 at 10:32 Comment(1)
worth mentioning that you'll probably want to run [self dismissViewControllerAnimated:YES completion:nil]; inside messageComposeViewController: didFinishWithResult: callback method. Else it will just hang there.Civilly
D
12
//Add the Framework in .h file

#import <MessageUI/MessageUI.h>
#import <MessageUI/MFMailComposeViewController.h>

//Set the delegate methods

UIViewController<UINavigationControllerDelegate,MFMessageComposeViewControllerDelegate>

//add the below code in .m file


- (void)viewDidAppear:(BOOL)animated{
    [super viewDidAppear:animated];

    MFMessageComposeViewController *controller = 
    [[[MFMessageComposeViewController alloc] init] autorelease];

    if([MFMessageComposeViewController canSendText])
    { 
        NSString *str= @"Hello";
        controller.body = str;
        controller.recipients = [NSArray arrayWithObjects:
                                 @"", nil];
        controller.delegate = self;
        [self presentModalViewController:controller animated:YES];  
    }


}

- (void)messageComposeViewController:
(MFMessageComposeViewController *)controller
                 didFinishWithResult:(MessageComposeResult)result 
{
    switch (result)
    {
        case MessageComposeResultCancelled:  
            NSLog(@"Cancelled");    
            break; 
        case MessageComposeResultFailed:
            NSLog(@"Failed");
            break;   
        case MessageComposeResultSent:      
            break; 
        default:  
            break;  
    }  
    [self dismissModalViewControllerAnimated:YES]; 
}
Danonorwegian answered 27/8, 2012 at 12:33 Comment(1)
you should see this link: blog.mugunthkumar.com/coding/… it will help youKabuki
G
6

Here is the Swift version of code to send SMS in iOS. Please noted that it only works in real devices. Code tested in iOS 7+. You can read more here.

1) Create a new Class which inherits MFMessageComposeViewControllerDelegate and NSObject:

import Foundation
import MessageUI

class MessageComposer: NSObject, MFMessageComposeViewControllerDelegate {
    // A wrapper function to indicate whether or not a text message can be sent from the user's device
    func canSendText() -> Bool {
        return MFMessageComposeViewController.canSendText()
    }

    // Configures and returns a MFMessageComposeViewController instance
    func configuredMessageComposeViewController(textMessageRecipients:[String] ,textBody body:String) -> MFMessageComposeViewController {
        let messageComposeVC = MFMessageComposeViewController()
        messageComposeVC.messageComposeDelegate = self  //  Make sure to set this property to self, so that the controller can be dismissed!
        messageComposeVC.recipients = textMessageRecipients
        messageComposeVC.body = body
        return messageComposeVC
    }

    // MFMessageComposeViewControllerDelegate callback - dismisses the view controller when the user is finished with it
    func messageComposeViewController(controller: MFMessageComposeViewController!, didFinishWithResult result: MessageComposeResult) {
        controller.dismissViewControllerAnimated(true, completion: nil)
        }
}

2) How to use this class:

func openMessageComposerHelper(sender:AnyObject ,withIndexPath indexPath: NSIndexPath) {
    var recipients = [String]()

    //modify your recipients here

    if (messageComposer.canSendText()) {
        println("can send text")
        // Obtain a configured MFMessageComposeViewController
        let body = Utility.createInvitationMessageText()

        let messageComposeVC = messageComposer.configuredMessageComposeViewController(recipients, textBody: body)

        // Present the configured MFMessageComposeViewController instance
        // Note that the dismissal of the VC will be handled by the messageComposer instance,
        // since it implements the appropriate delegate call-back
        presentViewController(messageComposeVC, animated: true, completion: nil)
    } else {
        // Let the user know if his/her device isn't able to send text messages
        self.displayAlerViewWithTitle("Cannot Send Text Message", andMessage: "Your device is not able to send text messages.")
    }
}
Greatcoat answered 23/5, 2015 at 7:40 Comment(0)
M
3

There is a class in iOS 4 which supports sending messages with body and recipents from your application. It works the same as sending mail. You can find the documentation here: link text

Matusow answered 10/9, 2010 at 8:32 Comment(0)
S
3
- (void)sendSMS:(NSString *)bodyOfMessage recipientList:(NSArray *)recipients
{
    UIPasteboard *pasteboard = [UIPasteboard generalPasteboard];
    UIImage *ui =resultimg.image;
    pasteboard.image = ui;
    [[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"sms:"]];
}
Stambaugh answered 9/9, 2013 at 11:17 Comment(2)
how useful are your parameters ?School
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"sms:"]];Seringa
D
3

//call method with name and number.

-(void)openMessageViewWithName:(NSString*)contactName withPhone:(NSString *)phone{

CTTelephonyNetworkInfo *networkInfo=[[CTTelephonyNetworkInfo alloc]init];

CTCarrier *carrier=networkInfo.subscriberCellularProvider;

NSString *Countrycode = carrier.isoCountryCode;

if ([Countrycode length]>0)     //Check If Sim Inserted
{

    [self sendSMS:msg recipientList:[NSMutableArray arrayWithObject:phone]];
}
else
{

    [AlertHelper showAlert:@"Message" withMessage:@"No sim card inserted"];
}

}

//Method for sending message

- (void)sendSMS:(NSString *)bodyOfMessage recipientList:(NSMutableArray *)recipients{  
 MFMessageComposeViewController *controller1 = [[MFMessageComposeViewController alloc] init] ;
 controller1 = [[MFMessageComposeViewController alloc] init] ;
 if([MFMessageComposeViewController canSendText])
{
    controller1.body = bodyOfMessage;
    controller1.recipients = recipients;
    controller1.messageComposeDelegate = self;
    [self presentViewController:controller1 animated:YES completion:Nil];
 }
}
Dharma answered 10/3, 2015 at 12:48 Comment(0)
A
2

If you want, you can use the private framework CoreTelephony which called CTMessageCenter class. There are a few methods to send sms.

Antivenin answered 29/1, 2010 at 2:15 Comment(2)
He specifically asked if this were possible using the official SDK.Orthotropic
Can you provide more information about the private api? I have no problem to use private framework because I don't need to publish it to App Store.Donnydonnybrook
A
1

Use this:

- (void)showSMSPicker
{
    Class messageClass = (NSClassFromString(@"MFMessageComposeViewController"));

    if (messageClass != nil) {          
        // Check whether the current device is configured for sending SMS messages
        if ([messageClass canSendText]) {
           [self displaySMSComposerSheet];
        }   
    }
}

- (void)messageComposeViewController:(MFMessageComposeViewController *)controller didFinishWithResult:(MessageComposeResult)result
{       
    //feedbackMsg.hidden = NO;
    // Notifies users about errors associated with the interface
    switch (result)
    {
        case MessageComposeResultCancelled:
        {   
            UIAlertView *alert1 = [[UIAlertView alloc] initWithTitle:@"Message" message:@"SMS sending canceled!!!" delegate:self cancelButtonTitle:nil otherButtonTitles:@"OK", nil];
            [alert1 show];
            [alert1 release];
        }   

        // feedbackMsg.text = @"Result: SMS sending canceled";
        break;

        case MessageComposeResultSent:
        {
            UIAlertView *alert2 = [[UIAlertView alloc] initWithTitle:@"Message" message:@"SMS sent!!!" delegate:self cancelButtonTitle:nil otherButtonTitles:@"OK", nil];
            [alert2 show];
            [alert2 release];
        }   

        // feedbackMsg.text = @"Result: SMS sent";
        break;

        case MessageComposeResultFailed:
        {   
            UIAlertView *alert3 = [[UIAlertView alloc] initWithTitle:@"Message" message:@"SMS sending failed!!!" delegate:self cancelButtonTitle:nil otherButtonTitles:@"OK", nil];
            [alert3 show];
            [alert3 release];
        }   

        // feedbackMsg.text = @"Result: SMS sending failed";
        break;

        default:
        {   
            UIAlertView *alert4 = [[UIAlertView alloc] initWithTitle:@"Message" message:@"SMS not sent!!!" delegate:self cancelButtonTitle:nil otherButtonTitles:@"OK", nil];
            [alert4 show];
            [alert4 release];
        }   

        // feedbackMsg.text = @"Result: SMS not sent";
        break;
    }

    [self dismissModalViewControllerAnimated: YES];
}
Arther answered 18/5, 2012 at 5:47 Comment(0)
M
1
[[UIApplication sharedApplication]openURL:[NSURL URLWithString:@"sms:number"]] 

This would be the best and short way to do it.

Mcglynn answered 4/8, 2014 at 12:36 Comment(0)
E
1

You can present MFMessageComposeViewController, which can send SMS, but with user prompt(he taps send button). No way to do that without user permission. On iOS 11, you can make extension, that can be like filter for incoming messages , telling iOS either its spam or not. Nothing more with SMS cannot be done

Expression answered 26/11, 2017 at 1:33 Comment(0)
C
0

You need to use the MFMessageComposeViewController if you want to show creating and sending the message in your own app.

Otherwise, you can use the sharedApplication method.

Cutie answered 30/3, 2015 at 6:31 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.