如何以编程方式在iPhone上发送短信?

时间:2008-08-14 09:51:06

标签: ios objective-c cocoa-touch sms

是否有人知道是否有可能,以及如何通过官方SDK / Cocoa Touch以编程方式从iPhone发送短信

18 个答案:

答案 0 :(得分:397)

限制

如果您可以在iPhone上的程序中发送短信,您将能够编写在后台垃圾邮件的游戏。我确定你真的想要从你的朋友那里得到垃圾邮件,“试试这款新游戏吧!它会让我的箱子变得更好,而你的箱子也会出现!roxxersboxxers.com !!!!如果你现在注册,你将获得3,200 RB点!!“

Apple对自动(甚至部分自动化)短信和拨号操作有限制。 (想象一下,如果游戏在一天的特定时间拨打了911)

您最好的办法是在互联网上设置一个使用在线短信发送服务的中间服务器,如果您需要完全自动化,则通过该路由发送短信。 (即,您在iPhone上的程序将UDP数据包发送到您的服务器,发送真实的短信)

iOS 4更新

但是,iOS 4现在提供了一个viewController,您可以将其导入到您的应用程序中。您预填充SMS字段,然后用户可以在控制器内启动SMS发送。与使用“SMS:...”url格式不同,这允许您的应用程序保持打开状态,并允许您填充正文字段。您甚至可以指定多个收件人。

这可以防止应用程序在用户没有明确意识到的情况下发送自动SMS。您仍然无法从iPhone本身发送完全自动化的短信,它需要一些用户互动。但这至少允许您填充所有内容,并避免关闭应用程序。

MFMessageComposeViewController类已有详细记录,tutorials表示实施起来非常简单。

iOS 5更新

iOS 5包含iPod touch和iPad设备的消息,因此虽然我自己尚未对此进行测试,但可能是所有iOS设备都可以通过MFMessageComposeViewController发送短信。如果是这种情况,那么Apple正在运行一个SMS服务器,它代表没有蜂窝调制解调器的设备发送消息。

iOS 6更新

此课程没有变化。

iOS 7更新

您现在可以检查您使用的消息媒体是否接受主题或附件,以及它将接受哪种附件。您可以编辑主题并在媒体允许的位置添加消息附件。

iOS 8更新

此课程没有变化。

iOS 9更新

此课程没有变化。

iOS 10更新

此课程没有变化。

iOS 11更新

No significant changes to this class

此课程的限制

请记住,这不适用于没有iOS 4的手机,除了iOS 5之外,它无法在iPod touch或iPad上运行。您必须先检测设备和iOS限制使用此控制器,或将您的应用程序限制为最近升级的3G,3GS和4个iPhone的风险。

然而,发送短信的中间服务器将允许任何和所有这些iOS设备发送短信,只要他们可以访问互联网,因此它可能仍然是许多应用程序的更好的解决方案。或者,使用两者,并且只有在设备不支持时才会回退到在线SMS服务。

答案 1 :(得分:142)

答案 2 :(得分:99)

  1. 您必须将MessageUI.framework添加到您的Xcode项目
  2. 在您的标头文件中加入#import <MessageUI/MessageUI.h>
  3. 将这些代理人添加到您的标题文件MFMessageComposeViewControllerDelegate&amp; UINavigationControllerDelegate
  4. 在您的IBAction方法声明MFMessageComposeViewController实例中说messageInstance
  5. 要检查您的设备是否可以在if条件下使用[MFMessageComposeViewController canSendText]发送文本,它将返回是/否
  6. if条件下执行以下操作:

    1. 首先将messageInstance的正文设为:

      messageInstance.body = @"Hello from Shah";
      
    2. 然后将邮件的收件人确定为:

      messageInstance.recipients = [NSArray arrayWithObjects:@"12345678", @"87654321",         nil];
      
    3. 将您的messageInstance的委托设置为:

      messageInstance.messageComposeDelegate = self;
      
    4. 在最后一行中执行此操作:

      [self presentModalViewController:messageInstance animated:YES];
      

答案 3 :(得分:50)

您可以使用sms:[target phone number]网址打开SMS应用程序,但没有迹象表明如何使用文本预填充SMS正文(请参阅Apple Developer论坛上的this post)。

答案 4 :(得分:25)

MacOS中的进程间通信系统之一是XPC。该系统层是基于使用libSystem和launchd传输plist结构而开发的用于进程间通信的。实际上,它是一个允许通过交换诸如字典之类的结构来管理进程的接口。由于遗传,iOS 5也拥有这种机制。

您可能已经理解了这个介绍的含义。是的,iOS中有一些系统服务,包括用于XPC通信的工具。我想用一个用于短信发送的守护进程来举例说明这项工作。但是,应该提到的是,这种能力在iOS 6中已得到修复,但与iOS 5.0-5.1.1相关。其利用不需要越狱,私人框架和其他非法工具。只需要目录/ usr / include / xpc / *中的头文件集。

iOS中发送短信的一个要素是系统服务com.apple.chatkit,其任务包括生成,管理和发送短文本消息。为了便于控制,它具有公共可用的通信端口com.apple.chatkit.clientcomposeserver.xpc。使用XPC子系统,您可以在未经用户批准的情况下生成和发送消息。

好吧,让我们尝试创建一个连接。

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);

现在我们将XPC连接myConnection设置为SMS发送服务。但是,XPC配置提供了挂起连接的创建 - 我们需要再激活一步。

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);

连接已激活。此时iOS 6将在电话日志中显示禁止此类通信的消息。现在我们需要生成一个类似于xpc_dictionary的字典,其中包含发送消息所需的数据。

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!");

剩下的很少:将消息发送到XPC端口并确保它已交付。

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

这就是全部。发送短信。

答案 5 :(得分:23)

添加MessageUI.Framework并使用以下代码

#import <MessageUI/MessageUI.h> 

然后:

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];
}

和委托方法 -

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

答案 6 :(得分:21)

您可以使用此方法:

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


iOS将自动从您的应用导航到消息应用的消息撰写页面。由于URL的方案以sms:开头,因此它被识别为消息应用程序识别并启动它的类型。

答案 7 :(得分: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]; 
}

答案 8 :(得分:12)

请按照以下步骤

1.将MessageUI.Framework添加到项目enter image description here

2。在.h文件中导入#import <MessageUI/MessageUI.h>

3。复制此代码以发送消息

 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。如果您愿意,请实施delegate方法。

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


   ///your stuff here 

    [self dismissViewControllerAnimated:YES completion:nil];
}

跑步去吧!

答案 9 :(得分:5)

以下是在iOS中发送短信的Swift版代码。请注意,它仅适用于实际设备。在iOS 7+中进行了代码测试。您可以阅读更多here

1)创建一个继承MFMessageComposeViewControllerDelegate和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)如何使用这个课程:

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.")
    }
}

答案 10 :(得分:3)

iOS 4中有一个类支持从应用程序发送带有正文和配方的消息。它与发送邮件的工作方式相同。您可以在此处找到文档:link text

答案 11 :(得分: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:"]];
}

答案 12 :(得分:3)

//使用姓名和号码调用方法。

-(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"];
}

}

//发送消息的方法

- (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];
 }
}

答案 13 :(得分:2)

如果需要,可以使用名为CoreTelephony类的私有框架CTMessageCenter。有几种方法可以发送短信。

答案 14 :(得分:1)

使用此:

- (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];
}

答案 15 :(得分:1)

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

这将是最好和最短的方式。

答案 16 :(得分:1)

你可以提供MFMessageComposeViewController,它可以发送短信,但有用户提示(他点击发送按钮)。没有用户许可,无法做到这一点。在iOS 11上,您可以进行扩展,这可以像对传入消息进行过滤,告诉iOS是否为垃圾邮件。没有更多的短信无法完成

答案 17 :(得分:0)

如果您想在自己的应用中显示创建和发送消息,则需要使用 MFMessageComposeViewController

否则,您可以使用 sharedApplication 方法。