The Telephony SDK can handle sending of SMS and MMS messages. Sending messages requires a provisioned phone number, discussed in the phone numbers section of the documentation.
Refer to the Telephony Simulator page for details on sending messages from simulated phone numbers.
SMS Messages
SMS messages can be sent using the sendSMSMessage() method. This method takes a local number, which must be a PhoneNumber, an E.164 formatted remote number and a message body.
let localNumber: PhoneNumbertry! telephonyClient.sendSMSMessage(localNumber: localNumber, remoteNumber:"+442071838750" , body:"Hi there") { result inswitch result {case .success(let message):// message: PhoneMessage (see details below)case .failure(let error):// error: SudoTelephonyClientError }}
// val phoneNumber: PhoneNumber// val destinationPhoneNumber = "+442071838750"// val message = "Hi there"telephonyClient.sendSMSMessage(phoneNumber, destinationPhoneNumber, message) { result ->when (result) {is Result.Success -> {// result.value: PhoneMessage }is Result.Error -> {// result.throwable: com.anonyome.telephonysdk.Result.Error } }}
The result of successfully sending a message is a PhoneMessage as described below.
MMS Messages
MMS messages can be sent using the sendMMSMessage() method. This is very similar to the method used for SMS but with an additional parameter localUrl: URL for the path to the MMS media file to be sent with the message.
let localNumber: PhoneNumberlet media =URL(string:"path to media")!try! telephonyClient.sendMMSMessage(localNumber: localNumber, remoteNumber:"+442071838750", body:"Check out my new car!", localUrl: media) { result inswitch result {case .success(let message):// message: PhoneMessage (see details below)case .failure(let error):// error: SudoTelephonyClientError }}
// val phoneNumber: PhoneNumber// val destinationPhoneNumber = "+442071838750"// val message = "Hi there"// val localUrl: URLtelephonyClient.sendMMSMessage(phoneNumber, destinationPhoneNumber, message, localUrl) { result ->when (result) {is Result.Success -> {// result.value: PhoneMessage (see details below) }is Result.Error -> {// result.throwable: com.anonyome.telephonysdk.Result.Error } }}
The result of successfully sending a message is a PhoneMessage, described below.
Phone Message
SMS and MMS messages are represented in the Telephony SDK by a PhoneMessage as described below:
structPhoneMessage {/// The direction of the messageenumDirection {case inboundcase outboundcase unknown }/// The state of the messageenumState {case queuedcase sentcase deliveredcase undeliveredcase failedcase receivedcase unknown }let id: String// Unique ID of messagelet owner: String// Unique ID of message ownerlet conversation: String// Unique ID of the conversation this message is part oflet updated: Date // Date/time message was last updatedlet created: Date // Date/time message was createdlet localPhoneNumber: String// E.164 formatted local phone numberlet remotePhoneNumber: String// E.164 formatted remote phone numberlet body: String// body of messagelet direction: Direction // Direction of message (see enum above)let state: State // State of message (see enum above)let media: [MediaObject] // Media attachements for MMS messages}
To retrieve SMS and MMS messages, including both sent and received messages, use the getMessage() and getMessages() methods. Messages can be retrieved using either a message ID or the local and remote phone numbers.
Single Message using ID
To retrieve a single message, use the getMessage() method with the message ID. This returns a PhoneMessage object as described above.
// val message: PhoneMessagetelephonyClient.getMessage(message.id) { result ->when (result) {is Result.Success -> {// result.value: PhoneMessage (see details below) }is Result.Error -> {// result.throwable: com.anonyome.telephonysdk.Result.Error } }}
Multiple Messages using a Local and Remote Number
To retrieve multiple messages for a specific local and remote number, use the getMessages() method. A limit can be specified for paging, as well as a paging token.
let localNumber: PhoneNumbertry! telephonyClient.getMessages(localNumber: localNumber, remoteNumber:"+442071838750", limit:20, nextToken:nil) { (result) inswitch result {case .success(let listToken):// listToken: TelephonyListToken<PhoneMessage> (see details below)case .failure(let error):// error: SudoTelephonyClientError }}
// val phoneNumber: PhoneNumber// val destinationPhoneNumber = "+442071838750"// val limit: Int = 20// val nextToken: String? = nulltelephonyClient.getMessages(phoneNumber, destinationPhoneNumber, limit, nextToken) { result ->when (result) {is Result.Success -> {// result.value: TelephonyListToken<PhoneMessage> }is Result.Error -> {// result.throwable: com.anonyome.telephonysdk.Result.Error } }}
The result of the getMessages() call is a TelephonyListToken as described below.
Get Messages Result
When multiple messages are retrieved, for example through the getMessages() method, a list token object is returned which includes a list of results and a paging token that can be used to retrieve the next set of results.
structTelephonyListToken<PhoneMessage> {let items: [PhoneMessage] // Phone messageslet nextToken: String?// Reference for next page}
A conversation is a convenient way to retrieve all messages between a specific local number and a specific remote number, sometimes referred to in outside contexts as a message thread or chat history. There are three methods for fetching conversations using different parameters.
Conversation by ID
To retrieve a conversation by ID, use the getConversation(conversationId: String) method.
// val id = "abc"telephonyClient.getConversation(id) { result ->when (result) {is Result.Success -> {// result.value: PhoneMessageConversation }is Result.Error -> {// result.throwable: com.anonyome.telephonysdk.Result.Error } }}
Conversation by local and remote number
To retrieve a conversation using the local and remote number, use the getConversation(localNumber: PhoneNumber, remoteNumber: String) method.
let localNumber: PhoneNumbertry! self.getConversation(localNumber: localNumber, remoteNumber:"+1") { (result) inswitch result {case .success(let conversation):// conversation: PhoneMessageConverastioncase .failure(let error):// error: SudoTelephonyClientError }}
// val localNumber: PhoneNumber// val remoteNumber = "+442071838750"telephonyClient.getConversation(localNumber, remoteNumber) { result ->when (result) {is Result.Success -> {// result.value: PhoneMessageConversation }is Result.Error -> {// result.throwable: com.anonyome.telephonysdk.Result.Error } }}
Conversations by local number
To retrieve the list of conversations for a given local number, use the getConversations method. A limit can be specified for paging, as well as a paging token.
// val localNumber: PhoneNumber// val limit = 20// val nextToken = nulltelephonyClient.getConversations(localNumber, limit, nextToken) { result ->when (result) {is Result.Success -> {// result.value: TelephonyListToken<PhoneMessageConversation> }is Result.Error -> {// result.throwable: com.anonyome.telephonysdk.Result.Error } }}
The PhoneMessageConversation type contains a latestPhoneMessage property which can be used to retrieve the local and remote phone numbers involved in the conversation, as well as to display a preview of the conversation contents.
structPhoneMessageConversation {let id: String// Unique id of conversationlet latestPhoneMessage: PhoneMessage?// Latest sent/received message in conversationpubliclet type: MessageConversationType // `MessageConversationType` of the conversationpubliclet latestMessageId: String// ID of the latest message in the conversationpublicvar latestPhoneMessage: PhoneMessage?// Latest phone messagepubliclet created: Date // Creation date of the conversationpubliclet updated: Date // Date of the last modification to the conversation}structTelephonyListToken<PhoneMessageConversation> {let items: [PhoneMessageConversation] // Conversationslet nextToken: String?// Reference for next page}
dataclassPhoneMessageConversation (val id: String, // Unique ID of the conversationval owner: String, // ID of the owner of the messageval type: MessageConversationType, // `MessageConversationType` of the conversationval latestMessageId: String, // ID of the latest message in the conversationvar latestPhoneMessage: PhoneMessage?, // Latest phone messageval created: Date, // Creation date of the conversationval updated: Date// Date of the last modification to the conversation)dataclassTelephonyListToken<PhoneMessageConversation>(val items: List<PhoneMessageConversation>, // Conversationsval nextToken: String? // Reference for next page)
Downloading MMS Message Media
When MMS messages are retrieved, the media data is not automatically downloaded. This gives you control over performance when retrieving MMS messages, particularly those with large media attachments.
To download MMS message media, use the downloadData() method, passing it a MediaObject which can be found in the media property of an MMS message. This method returns the raw media data. Images (jpeg, png, gif) are currently the only supported message media type.
let message: PhoneMessagelet mediaItem = message.media[0]try! telephonyClient.downloadData(for: mediaItem) { (result) inswitch result {case .success(let data):// Convert data to image for displaylet image =UIImage(data: data)case .failure(let error):// error: SudoTelephonyClientError }}
To delete a message, the deleteMessage() method is used and requires the message ID.
try! telephonyClient.deleteMessage(id:"1234") { result inswitch result {case .success(let id):// id: Message ID stringcase .failure(let error):// error: SudoTelephonyClientError }}
// val message: PhoneMessagetelephonyClient.deleteMessage(message.id) { result ->when (result) {is Result.Success -> {// result.value: Message ID string }is Result.Error -> {// result.throwable: com.anonyome.telephonysdk.Result.Error } }}
Subscribing to Message Events
To subscribe to new messages and message status change events, use the subscribeToMessages method. When new messages or message updates occur, the result handler or subscriber you provide will be called with the latest version of the message. On iOS this method returns a SubscriptionToken that cancels the subscription when it's released. On Android a unique ID is passed in to identify the subscriber and can be passed in to the unsubscribeFromPhoneMessages(id: String?) method on Android.
let token =try! telephonyClient.subscribeToMessages { (result) inswitch result {case .success(let message):// message: PhoneMessagecase .failure(let error):// error: SudoTelephonyClientError, if an error occurred processing subscription data }}
// val subscriber: PhoneMessageSubscriber// val subscriberId: StringtelephonyClient.subscribeToMessages(subscriber, subscriberId)// PhoneMessageSubscriber definitioninterfacePhoneMessageSubscriber : TelephonySubscriber {/** * Notifies the subscriber of a new 'PhoneMessage'. * @param phoneMessage new `PhoneMessage`. */funphoneMessageReceived(phoneMessage: PhoneMessage)}