UIActivityViewController

這些話寫在前面⋯⋯

最近在開發的產品需要加入「分享」的功能, 希望將一些資訊及圖片分享到其他 App 或平台上; 這篇文章會先點出需求,再逐一闡述開發的過程。

需求

  • Facebook 分享 hash tag 及圖片
  • 其餘分享文字及圖片和網址

實作

我們利用 UIActivityViewController 來呈現分享的選單,並將分享的內容塞入 activityItems: [Any] 之中; 而 applicationActivities 則設為 nil,並沒有要客製 activity。 若沒有需要依照不同類別做出不同的判斷,我們可以將內容放置進去; 像是 URL、String、UIImage等等。 而幾個特點要注意一下:

Facebook:

  • String 只支援一個 hash tag(像是:“#Archie”),若超過或其他一般文字則不會顯示
  • 有網址的話,就會顯示連結;意思是圖片和連結無法同時出現,會優先顯示連結

iMessage

若 String 裡頭的時間格式為 dd/MM/yyyy HH:mm 則可以點擊,並加入行事曆 圖片會以另一則訊息傳送 網址會以縮圖顯示(就如一般訊息收到的邏輯)

依照類別提供不同內容

首先,我們可以先看 UIActivityType:

extension UIActivityType {
    @available(iOS 6.0, *)
    public static let postToFacebook: UIActivityType
    @available(iOS 6.0, *)
    public static let postToTwitter: UIActivityType
    @available(iOS 6.0, *)
    public static let postToWeibo: UIActivityType // SinaWeibo
    @available(iOS 6.0, *)
    public static let message: UIActivityType
    @available(iOS 6.0, *)
    public static let mail: UIActivityType
    @available(iOS 6.0, *)
    public static let print: UIActivityType
    @available(iOS 6.0, *)
    public static let copyToPasteboard: UIActivityType
    @available(iOS 6.0, *)
    public static let assignToContact: UIActivityType
    @available(iOS 6.0, *)
    public static let saveToCameraRoll: UIActivityType
    @available(iOS 7.0, *)
    public static let addToReadingList: UIActivityType
    @available(iOS 7.0, *)
    public static let postToFlickr: UIActivityType
    @available(iOS 7.0, *)
    public static let postToVimeo: UIActivityType
    @available(iOS 7.0, *)
    public static let postToTencentWeibo: UIActivityType
    @available(iOS 7.0, *)
    public static let airDrop: UIActivityType
    @available(iOS 9.0, *)
    public static let openInIBooks: UIActivityType
    @available(iOS 11.0, *)
    public static let markupAsPDF: UIActivityType
}

而我們可以自行創建一個類別來實作 UIActivityItemSource, 不過因為它是屬於 NSObjectProtocol,所以得一併繼承 NSObject。 例如,我現在要寫一個給 Facebook 以及其他類分別不同 String 的 ItemSource:

class ActivityStringItemSource: NSObject, UIActivityItemSource {
    func activityViewControllerPlaceholderItem(_ activityViewController: UIActivityViewController) -> Any {
        return ""
    }
    func activityViewController(_ activityViewController: UIActivityViewController, itemForActivityType activityType: UIActivityType?) -> Any? {
        guard let type = activityType else {
            return ""
        }
        switch type {
        case UIActivityType.postToFacebook, UIActivityType.postToTwitter:
            return "#Archie"
        default:
            return "Archie 的 UIActivityViewController 實作心得 #Swift"
        }
    }
}

並在創建 UIActivityViewController 的時候,宣告進去:

 let activityViewController = UIActivityViewController.init(activityItems: [ActivityStringItemSource()], applicationActivities: nil)

這樣便會依照不同的 UIActivityType 來給予特定的 String 內容; 而當然你也可以建立一個有關 URL 和 UIImage 相關的 UIActivityItemSource, 在分享出去的時候,便可以決定讓 Facebook 僅分享圖片,而在其他地方則帶有連結。

comments powered by Disqus