As specified in our plugin.xml
file's platform section for iOS, the implementation of our plugin in iOS is located at the src/ios/Sms.h
and src/ios/Sms.m
Objective-C files. The following code snippet shows the Sms.h
file (the header file):
#import <Cordova/CDV.h> #import <MessageUI/MFMessageComposeViewController.h> @interface Sms : CDVPlugin <MFMessageComposeViewControllerDelegate> { } @property(strong) NSString* callbackID; - (void)sendMessage:(CDVInvokedUrlCommand*)command; @end
The preceding code declares an Sms
class that extends CDVPlugin
. It is important to note that in order to create a Cordova iOS plugin class, our Objective-C plugin class must extend the CDVPlugin
class. In our Sms
class declaration, there is a declared callbackID
property of the NSString
type and a declared sendMessage
method, which returns void
and takes CDVInvokedUrlCommand
as a parameter. Now, let's move on to the Sms
class implementation. The following code snippet shows the first part of the Sms.m
file:
#import "Sms.h" @implementation Sms - (void)sendMessage:(CDVInvokedUrlCommand*)command { CDVPluginResult* pluginResult = nil; NSString* phoneNumber = [command.arguments objectAtIndex:0]; NSString* textMessage = [command.arguments objectAtIndex:1]; self.callbackID = command.callbackId; if (![MFMessageComposeViewController canSendText]) { NSMutableDictionary* returnInfo = [NSMutableDictionary dictionaryWithCapacity:2]; [returnInfo setObject:@"SMS_FEATURE_NOT_SUPPORTED" forKey:@"code"]; [returnInfo setObject:@"SMS feature is not supported on this device" forKey:@"message"]; pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:returnInfo]; [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; return; } MFMessageComposeViewController *composeViewController = [[MFMessageComposeViewController alloc] init]; composeViewController.messageComposeDelegate = self; NSMutableArray *recipients = [[NSMutableArray alloc] init]; [recipients addObject:phoneNumber]; [composeViewController setBody:textMessage]; [composeViewController setRecipients:recipients]; [self.viewController presentViewController:composeViewController animated:YES completion:nil]; } // Code is omitted from here for simplicity @end
In our Sms
class implementation, we have the Objective-C instance method,- (void)sendMessage:(CDVInvokedUrlCommand*)command
, which maps to the action parameter in the cordova.exec()
JavaScript API.
In the sendMessage()
method of our Sms
class, the phoneNumber
and message
parameters are retrieved from the command.arguments
parameter (phoneNumber
is located at index 0
and message
is located at index 1
).
The MFMessageComposeViewController
class provides a standard system user interface to compose text messages. Unlike Android, we cannot send SMS messages directly in iOS devices from our plugin code without using the default device's (iPhone or iPad) SMS application. In iOS, all we can do from our plugin code is use the MFMessageComposeViewController
class to launch the SMS application with the SMS recipient and SMS message and listen for the user actions to know if the user sent or, cancelled, or failed to send the message. However, before interacting with the MFMessageComposeViewController
class, we need to check whether the current iOS device is capable of sending text messages. This can be done using the canSendText
method of MFMessageComposeViewController
as [MFMessageComposeViewController canSendText]
.
If the iOS device does not have the feature to send text messages (which means that [MFMessageComposeViewController canSendText]
returns NO
), we will create a returnInfo
object (that is of the NSMutableDictionary
type), which contains two entries: one for the error code and the other one for the error message that tells the plugin user that the SMS feature is not supported on this device. Our plugin tells the JavaScript caller that the operation failed by calling the sendPluginResult
method (of self.commandDelegate
), which has the following signature:
- (void)sendPluginResult:(CDVPluginResult*)result callbackId:(NSString*)callbackId;
To this method, we pass a CDVPluginResult
object (whose status
is CDVCommandStatus
_ERROR
, and message
is returnInfo
) and callbackId
, which is set to command.callbackId
.
If your iOS device supports sending SMS messages, then a composeViewController
object (of the MFMessageComposeViewController
type) is created and initialized with recipients
as the message recipients and textMessage
as the message body. Then, we present composeViewController
modally using the presentModalViewController
method of self.viewController
. It is important to highlight this line:
composeViewController.messageComposeDelegate = self;
This line tells composeViewController
to send the message-related notifications to our Sms
class. In order to receive these notifications, our Sms
class needs to implement the messageComposeViewController
method that has the following signature:
- (void)messageComposeViewController:(MFMessageComposeViewController *)controller didFinishWithResult:(MessageComposeResult)result
The messageComposeViewController
class has the following parameters:
The following code snippet shows the implementation of messageComposeViewController
in our Sms
class:
- (void)messageComposeViewController:(MFMessageComposeViewController *)controller didFinishWithResult:(MessageComposeResult)result { BOOL succeeded = NO; NSString* errorCode = @""; NSString* message = @""; switch(result) { case MessageComposeResultSent: succeeded = YES; message = @"Message sent"; break; case MessageComposeResultCancelled: message = @"Message cancelled"; errorCode = @"SMS_MESSAGE_CANCELLED"; break; case MessageComposeResultFailed: message = @"Message Compose Result failed"; errorCode = @"SMS_MESSAGE_COMPOSE_FAILED"; break; default: message = @"Sms General error"; errorCode = @"SMS_GENERAL_ERROR"; break; } [self.viewController dismissViewControllerAnimated:YES completion:nil]; if (succeeded == YES) { [super writeJavascript:[[CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:message] toSuccessCallbackString:self.callbackID]]; } else { NSMutableDictionary* returnInfo = [NSMutableDictionary dictionaryWithCapacity:2]; [returnInfo setObject:errorCode forKey:@"code"]; [returnInfo setObject:message forKey:@"message"]; [super writeJavascript:[[CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:returnInfo] toErrorCallbackString:self.callbackID]]; } }
The
messageComposeViewController
method is called when the user taps on one of the buttons to dismiss the message composition interface. In the implementation of the messageComposeViewController
method, the following two actions are performed:
dismissViewControllerAnimated
method of self.viewController
.result
parameter is equal to MessageComposeResultSent
(which means that the user sent the message successfully) in order to send a CDVPluginResult
with status = CDVCommandStatus_OK
and message = "Message sent"
to the plugin client. If the result is not equal to MessageComposeResultSent
, then a CDVPluginResult
is sent with status = CDVCommandStatus_ERROR
and message = returnInfo
(which contains two entries: one entry for the error code and the other one for the error message that contains the error details such as "Message cancelled"
or "Message Compose Result failed"
) to the plugin client.These are the details of our SMS plugin implementation in iOS platform. Next, let's move to the Windows Phone 8 implementation of our plugin.
3.15.29.119