Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to return multiple values from UIActivityItemSource function

Is it possible to return multiple values from UIActivityItemSource function, and pass them to UIActivityViewController's activityItems?

I want to return [message, image, url] array and pass to activityItems. But the switch code that I used only returns one value, either message, image, or url, depending on which activity is selected, obviously.

If I change: func activityViewController(_ activityViewController: UIActivityViewController, itemForActivityType activityType: UIActivity.ActivityType?) -> Any? to: func.... -> [Any]?

UIActivityItemSource complains:

"Type 'ActivityItemSource' does not conform to protocol 'UIActivityItemSource'"

and let you insert another set of the same functions with "-> Any?"

Maybe I don't comprehend how to handle init(), but would appreciate it if anyone could give me a direction to solve this.

I found a similar question at Multiple data from UIActivityItemSource and the poster himself figured out as: "Turned out all I needed to do was provide multiple items to the activity controller, since each activity item source can only provide one item."

Does this mean I need to make ActivityItemSource1 class for message, ActivityItemSource2 class for image, ActivityItemSource3 class for url? and assign them to activityItems like this?:

let activityItems = [ActivityItemSource1(message: message), ActivityItemSource2(image: image), ActivityItemSource3(url: url)]

==================================================================

class ActivityItemSource: NSObject, UIActivityItemSource {

var message: String!
var image: UIImage!
var url: URL!

init(message: String, image: UIImage, url: URL) {
    self.message = message
    self.image = image
    self.url = url
}

func activityViewControllerPlaceholderItem(_ activityViewController: UIActivityViewController) -> Any {
    return message
}

func activityViewController(_ activityViewController: UIActivityViewController, itemForActivityType activityType: UIActivity.ActivityType?) -> Any? {

    switch activityType {
    case UIActivity.ActivityType.postToFacebook:
        return image
    case UIActivity.ActivityType.postToTwitter:
        return message
    case UIActivity.ActivityType.mail:
        return message
    case UIActivity.ActivityType.copyToPasteboard:
        return message
    case UIActivity.ActivityType.markupAsPDF:
        return message
    case UIActivity.ActivityType.message:
        return message
    case UIActivity.ActivityType.postToFlickr:
        return image
    case UIActivity.ActivityType.postToTencentWeibo:
        return message
    case UIActivity.ActivityType.postToVimeo:
        return image
    case UIActivity.ActivityType.print:
        return message
    case UIActivity.ActivityType(rawValue: "com.apple.reminders.RemindersEditorExtension"):
        return message
    case UIActivity.ActivityType(rawValue: "com.apple.mobilenotes.SharingExtension"):
        return message

    default:
       return message

     }

   }
}


class TodaysTasksTableViewcontroller: TableViewController {
    var image: UIImage
    var message: String
    var url: URL

    image = UIImage(named: "PoliPoliIconLarge")!
    message = "I will complete the following task(s) today :"
    url = URL(string: "http://www.beckos.com")!

let activityItems = [ActivityItemSource(message: message, image: image, url: url)]

    let activityVC =      UIActivityViewController(activityItems: activityItems, applicationActivities: nil)

// Exclude some activities from share popup screen
    activityVC.excludedActivityTypes = [
        UIActivity.ActivityType.assignToContact,
        UIActivity.ActivityType.print,
        UIActivity.ActivityType.addToReadingList,
        UIActivity.ActivityType.saveToCameraRoll,
        UIActivity.ActivityType.openInIBooks,
        //UIActivity.ActivityType(rawValue: "com.apple.reminders.RemindersEditorExtension"),
        //UIActivity.ActivityType(rawValue: "com.apple.mobilenotes.SharingExtension"),
    ]


    self.present(activityVC, animated: true, completion: nil)

................
    }
like image 971
Sigabrt M Avatar asked Sep 07 '25 14:09

Sigabrt M


2 Answers

This is what I did last night. I am not sure if this way is efficient in terms of proper coding style, though. Also I'm not sure if I truly understand the way ActivitySourceItems works. Somebody probably can write it much more efficient way.

Basically I created three classes, one for message, one for image, and one for url. then pass three returns to a constant, activityItems. Still Instagram and Snapchat don't work with this, though. beside that, It does what I wanted to do anyway.

Thanx for the links, Larme. My previous search didn't show up these postings.

class TableViewController: UITableViewController {     
    let activityItems = [ActivityItemSource(message: message),    ActivityItemSourceImage(image: image), ActivityItemSourceURL(url: url)]
    let activityVC = UIActivityViewController(activityItems: activityItems, applicationActivities: nil)

    // some exclusion goes here...

    self.present(activityVC, animated: true, completion: nil)

}

class ActivityItemSource: NSObject, UIActivityItemSource {

    var message: String!

    init(message: String) {
        self.message = message
    }

    func activityViewControllerPlaceholderItem(_ activityViewController: UIActivityViewController) -> Any {
        return message
        // to display Instagram button, return image
        // image: Mail, Message, Notes, Twitter, Instagram, Shared Album, Post to Google Maps, Messenger, LINE, Snapchat, Facebook
        // message: Mail, Message, Notes, Twitter, Messenger, LINE, Facebook, LinkedIn
    }

    func activityViewController(_ activityViewController: UIActivityViewController, itemForActivityType activityType: UIActivity.ActivityType?) -> Any? {

        switch activityType {
        case UIActivity.ActivityType.postToFacebook:
            return nil
        case UIActivity.ActivityType.postToTwitter:
            return message
        case UIActivity.ActivityType.mail:
            return message
        case UIActivity.ActivityType.copyToPasteboard:
            return message
        case UIActivity.ActivityType.markupAsPDF:
            return message
        case UIActivity.ActivityType.message:
            return message
        case UIActivity.ActivityType.postToFlickr:
            return message
        case UIActivity.ActivityType.postToTencentWeibo:
            return message
        case UIActivity.ActivityType.postToVimeo:
            return message
        case UIActivity.ActivityType.print:
            return message
        case UIActivity.ActivityType(rawValue: "com.apple.reminders.RemindersEditorExtension"):
            return message
        case UIActivity.ActivityType(rawValue: "com.apple.mobilenotes.SharingExtension"):
            return message
        case UIActivity.ActivityType(rawValue: "com.burbn.instagram.shareextension"):
            return nil
        case UIActivity.ActivityType(rawValue: "jp.naver.line.Share"):
            return message

        default:
            return nil
        }
    }
}


class ActivityItemSourceImage: NSObject, UIActivityItemSource {

    var image: UIImage!


    init(image: UIImage) {
        //self.image = image
        self.image = UIImage(named: "PoliPoliIcon")!

    }


    func activityViewControllerPlaceholderItem(_ activityViewController: UIActivityViewController) -> Any {
        return image
    }

    func activityViewController(_ activityViewController: UIActivityViewController, itemForActivityType activityType: UIActivity.ActivityType?) -> Any? {


        switch activityType {
        case UIActivity.ActivityType.postToFacebook:
            return nil
        case UIActivity.ActivityType.postToTwitter:
            return nil
        case UIActivity.ActivityType.mail:
            return image
        case UIActivity.ActivityType.copyToPasteboard:
            return image
        case UIActivity.ActivityType.markupAsPDF:
            return image
        case UIActivity.ActivityType.message:
            return image
        case UIActivity.ActivityType.postToFlickr:
            return image
        case UIActivity.ActivityType.postToTencentWeibo:
            return image
        case UIActivity.ActivityType.postToVimeo:
            return image
        case UIActivity.ActivityType.print:
            return image
        case UIActivity.ActivityType(rawValue: "com.apple.reminders.RemindersEditorExtension"):
            return nil
        case UIActivity.ActivityType(rawValue: "com.apple.mobilenotes.SharingExtension"):
            return nil
        case UIActivity.ActivityType(rawValue: "com.burbn.instagram.shareextension"):
            return image
        case UIActivity.ActivityType(rawValue: "jp.naver.line.Share"):
            return image
        default:
            return image

        }
    }

}


class ActivityItemSourceURL: NSObject, UIActivityItemSource {

    var url: URL!


    init(url: URL) {
        self.url = url
    }

    func activityViewControllerPlaceholderItem(_ activityViewController: UIActivityViewController) -> Any {
        return url

    }

    func activityViewController(_ activityViewController: UIActivityViewController, itemForActivityType activityType: UIActivity.ActivityType?) -> Any? {

        switch activityType {
        case UIActivity.ActivityType.postToFacebook:
            return url
        case UIActivity.ActivityType.postToTwitter:
            return url
        case UIActivity.ActivityType.mail:
            return url
        case UIActivity.ActivityType.copyToPasteboard:
            return nil
        case UIActivity.ActivityType.message:
            return url
        case UIActivity.ActivityType.postToFlickr:
            return url
        case UIActivity.ActivityType.postToTencentWeibo:
            return url
        case UIActivity.ActivityType.postToVimeo:
            return url
        case UIActivity.ActivityType.print:
            return url
        case UIActivity.ActivityType(rawValue: "com.apple.reminders.RemindersEditorExtension"):
            return url
        case UIActivity.ActivityType(rawValue: "com.apple.mobilenotes.SharingExtension"):
            return url
        case UIActivity.ActivityType(rawValue: "com.burbn.instagram.shareextension"):
            return nil
        case UIActivity.ActivityType(rawValue: "jp.naver.line.Share"):
            return url
        //case UIActivity.ActivityType(rawValue: "com.snapchat.Share"):
          //  return nil

        default:
            return url

        }
    }
}
like image 84
Sigabrt M Avatar answered Sep 09 '25 05:09

Sigabrt M


In my case I always want to share an image but I also include a message (String) that contains a URL as part of the message when sharing on certain platforms that allow it. By default I don't display an image because some apps strip out the image if the message contains a URL.

I've created two classes of UIActivityItemSource for the message string and the image:

class MessageActivityItemSource: NSObject, UIActivityItemSource {

    var message: String

    init(_ message: String) {
        self.message = message
    }

    func activityViewControllerPlaceholderItem(_ activityViewController: UIActivityViewController) -> Any {
        message
    }

    func activityViewController(_ activityViewController: UIActivityViewController,
                                itemForActivityType activityType: UIActivity.ActivityType?) -> Any? {
        switch activityType {
        case
            UIActivity.ActivityType.message,
            UIActivity.ActivityType.postToTwitter,
            UIActivity.ActivityType.mail,
            UIActivity.ActivityType.copyToPasteboard,
            UIActivity.ActivityType.discord,
            UIActivity.ActivityType.viber,
            UIActivity.ActivityType.telegram,
            UIActivity.ActivityType.line:
                return message

        default: return nil
        }
    }
}

class ImageActivityItemSource: NSObject, UIActivityItemSource {

    var image: UIImage

    init(_ image: UIImage) {
        self.image = image
    }

    func activityViewControllerPlaceholderItem(_ activityViewController: UIActivityViewController) -> Any {
        image
    }

    func activityViewController(_ activityViewController: UIActivityViewController,
                                itemForActivityType activityType: UIActivity.ActivityType?) -> Any? {
        image
    }
}

I also have this small extension so I can detect some of the other apps:

extension UIActivity.ActivityType {

    static let discord = UIActivity.ActivityType(rawValue: "com.hammerandchisel.discord.Share")
    static let viber = UIActivity.ActivityType(rawValue: "com.viber.app-share-extension")
    static let telegram = UIActivity.ActivityType(rawValue: "ph.telegra.Telegraph.Share")
    static let line = UIActivity.ActivityType(rawValue: "jp.naver.line.Share")
}

and then present the share screen:

let activityItems = [
    ImageActivityItemSource(someUIImage),
    MessageActivityItemSource("Some text with included URL https://someApp.com/")
]

let activityVC = UIActivityViewController(activityItems: activityItems, applicationActivities: nil)

activityVC.excludedActivityTypes = [
    .assignToContact,
    .addToReadingList,
    .print,
    .postToVimeo,
    .markupAsPDF,
    .postToFlickr
]

present(activityVC, animated: true, completion: nil)
like image 35
budiDino Avatar answered Sep 09 '25 04:09

budiDino