通过UIActivityViewController(Twitter,Facebook,Instagram)与hashtag共享图像

Der*_*unt 24 ios swift

我试图使用UIActivityViewController与主题标签共享图像,我在尝试分享到Twitter,Facebook和Instagram时遇到了一些奇怪的行为.似乎没有关于这些服务的共享扩展的大量文档.

场景1:Init控制器,带有包含图像和文本的活动项目数组

如果我像这样初始化控制器,Twitter和Facebook将显示在控制器中(没有Instagram,因为它不支持文本项),并且两者都将以编程方式预先填充文本输入字段中的#标签:

let activityVC = UIActivityViewController(activityItems: [myHashtagString, myImage], applicationActivities: nil)
Run Code Online (Sandbox Code Playgroud)

场景2:仅具有图像的Init控制器

在这种情况下,所有网络都会显示,但我(显然)会丢失自动主题标签功能:

let activityVC = UIActivityViewController(activityItems: [myImage], applicationActivities: nil)
Run Code Online (Sandbox Code Playgroud)

场景3:UIActivityItemSource子类

如果我创建自己的UIActivityItemSource子类,我几乎可以完成所有工作.然而,这是我无法弄清楚的,使用我下面的协议方法导致自动主题标签适用于Facebook,但不是Twitter.这怎么可能 - 推特需要一个特殊的密钥吗?如果在场景#1中工作,必须有一种方法可以工作......

有趣的是,如果我插入一个URL(注释掉),这种方法适用于Twitter和Facebook.那么为什么地球上的文字不适用于Twitter!?

let activityItem = CustomItemSource(image: image, message: "#TestTag")
let activityVC = UIActivityViewController(activityItems: [activityItem], applicationActivities: nil)

...

class CustomItemSource: NSObject, UIActivityItemSource {

    private var image: UIImage!
    private var message: String!

    // MARK: Init
    init(image: UIImage, message: String) {
        super.init()

        self.image = image
        self.message = message
    }

    // MARK: Item Source Protocol
    func activityViewControllerPlaceholderItem(_ activityViewController: UIActivityViewController) -> Any {
        return image
    }

    func activityViewController(_ activityViewController: UIActivityViewController, itemForActivityType activityType: UIActivityType) -> Any? {
        if activityType == .postToTwitter || activityType == .postToFacebook {
            //return ["url": URL(string: "https://www.google.com")!, "image": image]

            return ["text": message, "image": image]
        }
        else {
            return ["image": image]
        }
    }

}
Run Code Online (Sandbox Code Playgroud)

far*_*bfn 26

定义两个UIActivityItemSource类,一个用于Image,另一个用于Text.

在第一个只返回图像.在第二个返回NSObject()placeHolder,并返回Textnil取决于活动.通过返回NSObject(),UIActivity将允许所有服务可用.

UIActivityViewController(activityItems: [ImageProvider(), TextProvider()], applicationActivities: nil)
Run Code Online (Sandbox Code Playgroud)

和提供者:

class TextProvider: NSObject, UIActivityItemSource {
    func activityViewControllerPlaceholderItem(_ activityViewController: UIActivityViewController) -> Any {
        return NSObject()
    }

    func activityViewController(_ activityViewController: UIActivityViewController, itemForActivityType activityType: UIActivityType) -> Any? {
        if activityType == .postToTwitter || activityType == .postToFacebook {
            return "Tweet with #Hashtag"
        }
        return nil
    }
}

class ImageProvider: NSObject, UIActivityItemSource {
    func activityViewControllerPlaceholderItem(_ activityViewController: UIActivityViewController) -> Any {
        return UIImage(named: ...)
    }

    func activityViewController(_ activityViewController: UIActivityViewController, itemForActivityType activityType: UIActivityType) -> Any? {
        return UIImage(named: ...)
    }
}
Run Code Online (Sandbox Code Playgroud)

首先,Keys并不是真正的敏感,唯一敏感的关键是电子邮件和支持它的应用程序的"主题",它是在UIActivityControllerAPI中实现的,我们可以直接设置它.如果您提供UIImage关键的"图像"或"1" 并不重要.

事实证明,如果文本没有直接...itemForActivity...方法中返回,Twitter活动将无法工作.所以解决方案是分离项目来源.

Twitter活动也不会起作用,如果placeholder收到任何其他内容String,但通过返回StringInstagram活动将无法正常工作,因此返回NSObject()Type将被忽略并且所有服务都将可用.如果你想限制一些服务使用UIActivityViewController.excludedActivityTypes