1

I am using Swift 3 on iOS 10. I am using the UIActivityViewController with subclass of UIActivity with activityType set to mail. When the call to present UIActivityViewController is made I get an error in the debugger which says:

2017-05-26 14:09:27.583 TrialActivityViewControllerMail3[798:21017] -[TrialActivityViewControllerMail3.TSSActivityMail setSourceIsManaged:]: unrecognized selector sent to instance 0x60800026c580
2017-05-26 14:09:27.605 TrialActivityViewControllerMail3[798:21017] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[TrialActivityViewControllerMail3.TSSActivityMail setSourceIsManaged:]: unrecognized selector sent to instance 0x60800026c580'

The key message is unrecognized selector sent to instance for selector setSourceIsManaged. That deals with the multithreading system which I don't have control of.

How do I fix this or get around it or find out more about the problem?

In addition to putting my code here, I also put the entire project in a git repository on GitHub. It's a small project intended only to try code to use the UIActivityViewController with a mail activity.

Here's the url:

https://github.com/Shinehah-Gnolaum/TrialActivityViewControllerMail3.git

Here is my code:

    let mailItemProvider = TSSMailItemProvider(placeholderItem: textView.text as Any)

    let activityItems = [mailItemProvider]

    let activityMail = TSSActivityMail()

    let applicationActivities = [activityMail]

    let activityViewController = UIActivityViewController.init(activityItems: activityItems, applicationActivities: applicationActivities)

    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiom.pad) {

        activityViewController.modalPresentationStyle = UIModalPresentationStyle.popover
        activityViewController.preferredContentSize = CGSize(width: 0, height: 0)
        activityViewController.popoverPresentationController?.barButtonItem = barButtonItemMore

    }

    present(activityViewController, animated: true, completion: nil)

Here is TSSActivityMail.swift:

import UIKit
import MessageUI

class TSSActivityMail: UIActivity, MFMailComposeViewControllerDelegate {

var activityItem: Any?

let mailComposeViewController = MFMailComposeViewController()

override init() {

    super.init()

}

// Succeed when activityType is remarked out or when it returns nil.
override var activityType: UIActivityType? {

    get {

        return UIActivityType.mail

    }

}

override var activityTitle: String? {

    get {

        return "Mail"

    }

}

override var activityImage: UIImage? {

    get {

        return UIImage(imageLiteralResourceName: "email.png")

    }

}

override func canPerform(withActivityItems activityItems: [Any]) -> Bool {

    // !!! Perform checks.

    return true

}

override func prepare(withActivityItems activityItems: [Any]) {

    activityItem = activityItems[0] // $$$ as! String

    mailComposeViewController.mailComposeDelegate = self

    let filename = "file.txt"

    mailComposeViewController.setSubject("subject")
    mailComposeViewController.setMessageBody("Message body.", isHTML: false)

    let content = activityItem as! String // $$$ ('as! String' was added)

    let length = content.lengthOfBytes(using: String.Encoding.utf8)

    let outputData = NSData(bytes:content, length: length) as Data

    mailComposeViewController.addAttachmentData(outputData, mimeType: "plain", fileName: filename)


}

override class var activityCategory: UIActivityCategory {

    get {

        return UIActivityCategory.action

    }

}

override var activityViewController: UIViewController? {

    get {

        return mailComposeViewController as UIViewController // $$$ ('as UIViewController' was added)

    }

}

func mailComposeController(_ controller: MFMailComposeViewController, didFinishWith result: MFMailComposeResult, error: Error?) {

    print("TSSActivityMail.mailComposeController(_:_:_:)")

    // Check the result or perform other tasks.
    print("result.rawValue = \(result.rawValue)")

    if let error = error {

        print("error.localizedDescription = \(error.localizedDescription)")

        self.activityDidFinish(false)

    }
    else
    {

        if !(result == MFMailComposeResult.sent) {

            self.activityDidFinish(false)

        }
        else
        {

            self.activityDidFinish(true)

        }

    }
}

}

Here is TSSMailItemProvider.swift:

import UIKit

class TSSMailItemProvider: UIActivityItemProvider {

var placeholderItemAny: Any
var localActivityType: UIActivityType?

override init(placeholderItem: Any) {

    placeholderItemAny = placeholderItem

    super.init(placeholderItem: placeholderItem)

}

override var item: Any {

    get {

        let itemAny = NSString(string: placeholderItemAny as! String)

        localActivityType = UIActivityType.mail

        return itemAny

    }

}

override var placeholderItem: Any? {

    get {

        return placeholderItemAny

    }

}

override var activityType: UIActivityType? {

    get {

        return localActivityType

    }

}

}
daniel
  • 1,446
  • 3
  • 29
  • 65
  • [Edit] your question with relevant code. – rmaddy May 26 '17 at 21:16
  • Did you solve your problem? If not, please add your code so we can help. – Mozahler Jul 05 '17 at 17:30
  • Be sure to notice my comment in the code that says that when I don't override the activityType property or if I return nil for that property, the code works. The documentation however instructs me to do what I did with overriding the activityType property. – daniel Jul 06 '17 at 09:48
  • @rmaddy I have edited my question with relevant code. I just now figured out how to ping people. Notice also my comment above. – daniel Sep 14 '17 at 00:13
  • @Mozahler I have not solved my problem. I added the relevant code. I just now figured out how to ping people. Notice also my comment above. – daniel Sep 14 '17 at 00:15

0 Answers0