0

I have the following code that takes a partial snapshot of my screen in-app, then opens up a SMS dialogue window.

import UIKit
import MessageUI
import AVFoundation


class ViewController: UIViewController, MFMailComposeViewControllerDelegate
{


@IBAction func smsScreenShot(sender: AnyObject) {

    audioPlayer.play()

    // Declare the snapshot boundaries 
    let top: CGFloat = 100
    let bottom: CGFloat = 60

    // The size of the cropped image
    let size = CGSize(width: view.frame.size.width, height: view.frame.size.height - top - bottom)

    // Start the context
    UIGraphicsBeginImageContext(size)
    CGContextTranslateCTM(context, 0, -top)

    // Draw the view into the context (this is the snapshot)
    view.layer.renderInContext(context)
    let snapshot = UIGraphicsGetImageFromCurrentImageContext()

    // End the context (this is required to not leak resources)
    UIGraphicsEndImageContext()

    // Composing the SMS

    if !MFMessageComposeViewController.canSendText() {
        print("SMS services are not available")
    }

    if (MFMessageComposeViewController.canSendText()) {

        let composeVC = MFMessageComposeViewController()

        composeVC.recipients = ["Enter tel no"]
        composeVC.body = "Have a look at this cool image!";

        // Attaching the image to the SMS.
        let image = snapshot
        let imageData = UIImagePNGRepresentation(image)
        composeVC.addAttachmentData(imageData!, typeIdentifier: "image/png", filename:"myImage")

        self.presentViewController(composeVC, animated:true, completion:nil)

    }

}

I realise I have to add MFMessageComposeViewControllerDelegate in the class construct just after 'MFMailComposeViewControllerDelegate'.

In doing so, I receive the following error:

Type 'ViewController' does not conform to protocol 'MFMessageComposeViewControllerDelegate'

And this is because I haven't dismissed the controller.

To dismiss the MFMMessageComposeViewController, I added the following code:

func messageComposeViewController(controller: MFMessageComposeViewController!, didFinishWithResult result: MessageComposeResult) {

switch result.value {
case MessageComposeResultCancelled.value:
    NSLog("cancelled")
case MessageComposeResultFailed.value:
    NSLog("cancelled")
case MessageComposeResultSent.value:
    NSLog("cancelled")
default:
    NSLog("default...")
}
controller.dismissViewControllerAnimated(true, completion: nil)
}

And I inserted this code just after:

self.presentViewController(composeVC, animated:true, completion:nil)

But now I am presented with the same Type 'ViewController' does not conform to protocol 'MFMessageComposeViewControllerDelegate' error as well as errors in the switch statement.

Switch Statement Errors

Firstly, I had an error using result.value so I changed it to result.rawValue. That seemed to solve that error.

But I now have errors in the case statements: Value of type 'MessageComposeResult' has no member 'value'. I think this is because the syntax surrounding MessageComposeResult is outdated or wrong?

How can I fix my case statements? I guess if I fix the case statements, all my problems will be resolved?

I have spent hours scouring similar questions and material on the Web, but am really stumped here.

Could someone please tell me where I am going wrong? And how to amend my code?

Many thanks.

Amended Code

import UIKit
import MessageUI
import AVFoundation


    class ViewController: UIViewController, MFMailComposeViewControllerDelegate, MFMessageComposeViewControllerDelegate {

   // Composing the SMS

    if !MFMessageComposeViewController.canSendText() {
        print("SMS services are not available")
    }

    if (MFMessageComposeViewController.canSendText()) {


        let composeVC = MFMessageComposeViewController()


        composeVC.recipients = ["Enter tel no"]
        composeVC.body = "Have a look at this cool image!";
        composeVC.messageComposeDelegate = self;

        // Attaching the image to the SMS.

        let image = snapshot
        let imageData = UIImagePNGRepresentation(image)
        composeVC.addAttachmentData(imageData!, typeIdentifier: "image/png", filename:"myImage")



        self.presentViewController(composeVC, animated:true, completion:nil)

        func messageComposeViewController(controller: MFMessageComposeViewController, didFinishWithResult result: MessageComposeResult) {
            switch result {
            case MessageComposeResultCancelled:
                NSLog("Cancelled")

            case MessageComposeResultFailed:
                NSLog("Failed")

            case MessageComposeResultSent:
                NSLog("Sent")

            default:
                NSLog("Unknown result")

            }

        }
Paul Metas
  • 254
  • 3
  • 19
  • That warning is because you haven't implemented the required method of the delegate - https://developer.apple.com/library/ios/documentation/MessageUI/Reference/MFMessageComposeViewControllerDelegate_protocol/#//apple_ref/occ/intfm/MFMessageComposeViewControllerDelegate/messageComposeViewController:didFinishWithResult: but you also haven't set your view controller as the MFMessageComposeViewController's delegate. – Paulw11 Jan 30 '16 at 21:08
  • If I add `func messageComposeViewController(controller: MFMessageComposeViewController!, didFinishWithResult result: MessageComposeResult) { switch result.value { case MessageComposeResultCancelled.value: NSLog("cancelled") case MessageComposeResultFailed.value: NSLog("cancelled") case MessageComposeResultSent.value: NSLog("cancelled") default: NSLog("default...") } controller.dismissViewControllerAnimated(true, completion: nil) }` isn't that implementing the required method? – Paul Metas Jan 30 '16 at 21:11
  • Yes, but if that function has errors then it will be ignored. Fix the errors in the switch statement (you don't say what they are) and the function will be recognised – Paulw11 Jan 30 '16 at 21:12
  • I have amended my question to be more clear re the switch statement. I think you're right. Fix the switch statement, and the function will work and my code should work in totality? – Paul Metas Jan 30 '16 at 21:23

1 Answers1

1

Your problem is that you are using an MFMessageComposeViewController but you have said that your class is an MFMailComposeViewControllerDelegate - Message vs Mail. You have implemented the delegate method for the MFMessageComposeViewController, which doesn't match the declaration for your class, so you get the error.

You want

class ViewController: UIViewController, MFMessageComposeViewControllerDelegate

and then

func messageComposeViewController(controller: MFMessageComposeViewController, didFinishWithResult result: MessageComposeResult) {
    switch result {
    case MessageComposeResultCancelled:
        NSLog("Cancelled")

    case MessageComposeResultFailed:
        NSLog("Failed")

    case MessageComposeResultSent:
        NSLog("Sent")

    default:
        NSLog("Unknown result")

    }

}

Also, you haven't set your view controller as the delegate, so the delegate method won't be invoked:

let composeVC = MFMessageComposeViewController()
composeVC.messageComposeDelegate=self
Paulw11
  • 108,386
  • 14
  • 159
  • 186
  • I have declared `class ViewController: UIViewController, MFMailComposeViewControllerDelegate, MFMessageComposeViewControllerDelegate ` because I also have another function in my app that emails the screenshot. – Paul Metas Jan 30 '16 at 21:44
  • I have added your amended `func messageComposeViewController ...` code, and also added `let composeVC = MFMessageComposeViewController() composeVC.delegate=self` as per your instructions. But I now get an error : `Cannot assign value of type 'ViewController' to type 'UINavigationControllerDelegate?'` attached to the `composeVC.delegate=self` line of code. – Paul Metas Jan 30 '16 at 21:46
  • I have added my amended code to the bottom of my initial question. Thanks very much for all assistance. – Paul Metas Jan 30 '16 at 21:52
  • Sorry, that class has two delegates; I have updated my answer – Paulw11 Jan 30 '16 at 21:55
  • Ahh. Yes, thats why you amended to specify `messageComposeDelegate`. Gotcha. Have amended my code accordingly, but I'm still left with the `Type 'ViewController' does not conform to protocol 'MFMessageComposeViewControllerDelegate'` error. – Paul Metas Jan 30 '16 at 22:02
  • I imported the MessageUI.framework as a linked framework. That's correct? – Paul Metas Jan 30 '16 at 22:16