Chapter 20. Mail and Messages

Your app can present an interface allowing the user to edit and send a mail message or an SMS message. Two view controller classes are provided by the Message UI framework; you’ll need to import MessageUI. In addition, the Social framework lets you post to Twitter or Facebook on the user’s behalf. You’ll need to import Social. The classes are:

MFMailComposeViewController
Allows composition and sending of a mail message.
MFMessageComposeViewController
Allows composition and sending of an SMS message.
SLComposeViewController
Allows composition and sending of a Twitter or Facebook post. Alternatively, you can prepare and post a message directly using SLRequest.

UIActivityViewController (Chapter 13) also provides a unified interface for permitting the user to choose any of the built-in messaging milieus and to send a message through it. However, the Message UI framework and the Social framework remain important, because the user can be presented with a message form without having to pass through an activity view, and because you can fill in fields, such as the recipient field in a mail composition form, that UIActivityViewController doesn’t let you fill in.

Another option is to form a URL of the appropriate scheme and hand it to UIApplication’s openURL: method. For example, given a mailto: URL, openURL: can generate a proposed mail message with an initial recipient field and subject field. (See the Apple URL Scheme Reference for a list of built-in URL schemes.) That takes the user to the Mail app — and out of your app — but in iOS 9 that might not be so terrible, because a Back button appears in the status bar.

Mail Message

The MFMailComposeViewController class, a UINavigationController, allows the user to edit a mail message. The user can attempt to send the message there and then, or can cancel but save a draft, or can cancel completely. Before using this class to present a view, call canSendMail; if the result is false, go no further, as a negative result means that the device is not configured for sending mail. A positive result does not mean that the device is connected to the network and can send mail right now, only that sending mail is generally possible with this device; actually sending the mail message (or storing it as a draft) will be up to the device’s internal processes.

To use MFMailComposeViewController, instantiate it, provide a mailComposeDelegate (not delegate) adopting MFMailComposeViewControllerDelegate, and configure the message to any desired extent. Configuration methods are:

  • setSubject:
  • setToRecipients:
  • setCcRecipients:
  • setBccRecipients:
  • setMessageBody:isHTML:
  • addAttachmentData:mimeType:fileName:

Typically, you’ll show the MFMailComposeViewController as a presented view controller. (On the iPad, a .FormSheet presentation feels less overwhelming.) The user can later alter your preset configurations, at which time the message details will be out of your hands.

The delegate method mailComposeController:didFinishWithResult:error: will be called, describing the user’s final action, which might be any of these:

  • MFMailComposeResultCancelled
  • MFMailComposeResultSaved
  • MFMailComposeResultSent
  • MFMailComposeResultFailed

Dismissing the presented view controller is up to you, in the delegate method. Here’s a minimal example:

@IBAction func doMail (sender:AnyObject!) {
    guard MFMailComposeViewController.canSendMail() else { return }
    let vc = MFMailComposeViewController()
    vc.mailComposeDelegate = self
    self.presentViewController(vc, animated:true, completion:nil)
}
func mailComposeController(
    controller: MFMailComposeViewController,
    didFinishWithResult result: MFMailComposeResult,
    error: NSError?) {
        // can do something with result here
        self.dismissViewControllerAnimated(true, completion: nil)
}

Text Message

The MFMessageComposeViewController class is a UINavigationController subclass. Before using this class to present a view, call canSendText; if the result is false, go no further. The user has no option to save an SMS message as a draft, so even if this device sometimes can send text, there’s no point proceeding if the device can’t send text now. However, you can register for the MFMessageComposeViewControllerTextMessageAvailabilityDidChangeNotification in the hope that the device might later be able to send text; if the notification arrives, examine its MFMessageComposeViewControllerTextMessageAvailabilityKey.

To use MFMessageComposeViewController, instantiate the class, give it a messageComposeDelegate (not delegate) adopting MFMessageComposeViewControllerDelegate, and configure it as desired through the recipients (phone number strings) and body properties. You can also configure the message subject and provide attachments. For the subject, call the class method canSendSubject, and if it returns true, you can set the subject. For attachments, call the class method canSendAttachments, and if it returns true, you may want to call isSupportedAttachmentUTI: to see if a particular file type can be sent as an attachment; finally, call addAttachmentURL:withAlternateFilename: (if you have a file URL) or addAttachmentData:typeIdentifier:filename:. Conversely, you can prevent the user from adding attachments by calling disableUserAttachments.

When you’ve finished configuring the MFMessageComposeViewController, show it as a presented view controller. The user can later alter your preset configurations, at which time the message details will be out of your hands.

The delegate method messageComposeViewController:didFinishWithResult: will be called with a description of the user’s final action, which might be any of these:

  • MessageComposeResultCancelled
  • MessageComposeResultSent
  • MessageComposeResultFailed

Dismissing the presented view controller is up to you, in the delegate method. Here’s a minimal example:

@IBAction func doMessage (sender:AnyObject!) {
    guard MFMessageComposeViewController.canSendText() else { return }
    let vc = MFMessageComposeViewController()
    vc.messageComposeDelegate = self
    self.presentViewController(vc, animated:true, completion:nil)
}
func messageComposeViewController(
    controller: MFMessageComposeViewController,
    didFinishWithResult result: MessageComposeResult) {
        // can do something with result here
        self.dismissViewControllerAnimated(true, completion: nil)
}

Twitter Post

The interface for letting the user construct a Twitter post is SLComposeViewController, part of the Social framework. Twitter, together with Facebook (and Weibo), are represented by constant strings starting with SLServiceType. You’ll use the class method isAvailableForServiceType: to learn whether the desired service is available; if it is, you can instantiate SLComposeViewController for that service and present it as a presented view controller.

SLComposeViewController has a more modern API than the mail and message view controllers. Instead of a delegate, SLComposeViewController has a completionHandler. Set it to a function taking one parameter, an SLComposeViewControllerResult. In the function, dismiss the view controller. The SLComposeViewControllerResult parameter will be .Cancelled or .Done. Here’s a minimal example:

@IBAction func doTwitter (sender:AnyObject!) {
    guard SLComposeViewController
        .isAvailableForServiceType(SLServiceTypeTwitter) else { return }
    guard let vc = SLComposeViewController(
        forServiceType:SLServiceTypeTwitter) else { return }
    vc.completionHandler = {
        (result:SLComposeViewControllerResult) in
        // can do something with result here
        self.dismissViewControllerAnimated(true, completion:nil)
    };
    self.presentViewController(vc, animated:true, completion:nil)
}

You can also, with the user’s permission, gain secure access to the user’s account information through the ACAccountStore class (part of the Accounts framework). Using this, along with the SLRequest class, your app can construct and post a message directly, without passing through the message composition interface. The ACAccountStore class can manipulate accounts in other ways as well, without violating the user’s privacy.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.145.204.201