一尘不染

通过UIActivityViewController(Twitter,Facebook,Instagram)与主题标签共享图像

swift

我正在尝试使用UIActivityViewController与主题标签共享图像,并且在尝试共享到Twitter,Facebook和Instagram时遇到一些奇怪的行为。关于这些服务的共享扩展名的文档似乎很少。

方案1:具有带有图像和文本的活动项目数组的Init控制器

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

let activityVC = UIActivityViewController(activityItems: [myHashtagString, myImage], applicationActivities: nil)

方案2:只有图片的Init控制器

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

let activityVC = UIActivityViewController(activityItems: [myImage], applicationActivities: nil)

方案3:UIActivityItemSource子类

如果我创建自己的UIActivityItemSource子类,则几乎可以使所有工作正常进行。但是,这是我不知道的,使用下面的协议方法会导致自动主题标签适用于Facebook,而不适用于Twitter。这怎么可能-
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]
        }
    }

}

阅读 239

收藏
2020-07-07

共1个答案

一尘不染

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

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

UIActivityViewController(activityItems: [ImageProvider(), TextProvider()], applicationActivities: nil)

和提供者:

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: ...)
    }
}

讲解

首先,密钥并不是真正敏感的,唯一的敏感密钥是电子邮件和支持它的应用程序的“主题”,它是在UIActivityControllerAPI中实现的,我们可以直接对其进行设置。您提供UIImage键“
image”还是“ 1” 都没关系。

事实证明,如果未在方法中 _ 直接_
返回其文本,则Twitter活动将不起作用...itemForActivity...。因此,解决方案是分离物料来源。

如果未placeholder收到Twitter活动,则Twitter活动也将不起作用,String但通过返回StringInstagram活动将不起作用,因此,通过返回NSObject()Type将被忽略,并且所有服务将可用。如果您想限制某些服务的使用UIActivityViewController.excludedActivityTypes

2020-07-07