iOS開發(fā)中,我們經(jīng)常會(huì)用到分享這個(gè)功能。我們希望把自己的APP里面好東西通過分享的渠道推廣出去,或者看到好的東西我們希望通過分享到APP與好友共享八孝。為了實(shí)現(xiàn)這種功能,業(yè)界常用的做法是通過集成SDK(如微信)或第三方(如友盟分享)去做鸠项,但是這樣做有個(gè)弊端就是我們得配置所有想分享的平臺(tái)的scheme干跛,分享的時(shí)候我們得調(diào)起相應(yīng)的APP。怎么樣做到像Safari那樣分享呢祟绊?
這里有兩個(gè)問題:1楼入,怎么讓自己的APP出現(xiàn)在Safari分享欄的選項(xiàng)里,讓用戶可以直接通過這種方式分享內(nèi)容到咱們自己的APP牧抽。2嘉熊、在咱們自己的APP里分享時(shí)怎么像Safari一樣分享,而不是集成SDK扬舒。
Share extensions
share extentsion的出現(xiàn)解決了咱們的第一個(gè)問題阐肤,它的(基礎(chǔ))使用也特別簡(jiǎn)單。先按照file->new->target->Share Extentsion->Next->Finish->Activate
的步驟添加Share Extension。這時(shí)候我們會(huì)發(fā)現(xiàn)active scheme已經(jīng)自動(dòng)變成咱們剛才新建的target了孕惜,而不是原來的target了(如下圖)愧薛。
點(diǎn)擊run,然后選擇一個(gè)APP(這里選的Safari)作為Host app衫画,運(yùn)行之后發(fā)現(xiàn)測(cè)試機(jī)已經(jīng)自動(dòng)啟動(dòng)Safari了毫炉。我們隨便打開一個(gè)網(wǎng)頁(yè),然后點(diǎn)分享削罩,驚喜出現(xiàn)了碘箍,咱們的APP已經(jīng)靜靜的躺在分享欄的選項(xiàng)里了,見下圖左圖鲸郊。
點(diǎn)擊Post,再啟動(dòng)咱們自己的APP货邓,可以發(fā)現(xiàn)剛才在瀏覽器分享的內(nèi)容已經(jīng)展示出來了(這里用到了APP Group服務(wù)秆撮,此處暫且略過不提),見上圖右圖换况。
新建的extension里有個(gè)默認(rèn)的ShareViewController
职辨,它繼承于SLComposeServiceViewController
,關(guān)于分享的操作都在這里完成戈二。在分享之前舒裤,我們可以通過判斷來決定是否可以分享,比如如果文字里包含“皇上”兩個(gè)字觉吭,則不讓分享腾供,Post按鈕置灰,如下圖鲜滩。
代碼如下:
override func isContentValid() -> Bool {
// 如果文字中包含“皇上”兩個(gè)字伴鳖,則不可分享
if contentText.contains("皇上") {
return false
}
return true
}
分享的數(shù)據(jù)處理則主要是在didSelectPost()
里處理:
override func didSelectPost() {
print("分享")
// 處理新的分享數(shù)據(jù)前清除老數(shù)據(jù)
let userDefaults = UserDefaults(suiteName: "group.kefan.com.KFAShareDemo")
if let ud = userDefaults {
ud.set(nil, forKey: "title_key")
ud.set(nil, forKey: "content_key")
ud.set(nil, forKey: "url_key")
}
let item = self.extensionContext!.inputItems.first as? NSExtensionItem
guard item != nil else {
print("分享內(nèi)容為空")
self.extensionContext!.completeRequest(returningItems: [], completionHandler: nil)
return
}
// 分享標(biāo)題
if let title = item!.attributedTitle {
print(title.string)
if let ud = userDefaults {
ud.set(title.string, forKey: "title_key")
}
}
// 分享內(nèi)容
if let content = item!.attributedContentText {
print(content.string)
if let ud = userDefaults {
ud.set(content.string, forKey: "content_key")
}
}
// 分享附件
if let attachments = item!.attachments as? [NSItemProvider] {
for provider in attachments {
// 如果分享的是鏈接
if provider.hasItemConformingToTypeIdentifier("public.url") {
provider.loadItem(forTypeIdentifier: "public.url", options: nil, completionHandler: { (data, error) in
let url = data as! URL
// 把url存在UserDefaults里用來與容器程序共享
if let ud = UserDefaults(suiteName: "group.kefan.com.KFAShareDemo") {
ud.set(url, forKey: "url_key")
}
})
}
}
}
self.extensionContext!.completeRequest(returningItems: [], completionHandler: nil)
}
UIActivityViewController和SLComposeViewController
這兩個(gè)類則可以為我們解決第二個(gè)問題。不同的是徙硅,UIActivityViewController
把支持的分享的APP和操作都展示出來榜聂,讓我們選擇,跟Safari界面類似嗓蘑,而SLComposeViewController
則是直接分享給目標(biāo)APP须肆。如下圖,左圖點(diǎn)擊分享用的UIActivityViewController
桩皿,所以出現(xiàn)的一個(gè)選擇界面豌汇,右圖點(diǎn)微信通過SLComposeViewController
直接分享給微信。
代碼分別如下:
if SLComposeViewController.isAvailable(forServiceType: "com.tencent.xin.sharetimeline") {
let vc = SLComposeViewController(forServiceType: "com.tencent.xin.sharetimeline")
guard vc != nil else {
return
}
vc!.setInitialText("O(∩_∩)O哈哈~业簿,給您分享一個(gè)鏈接")
vc!.add(UIImage(named: "headIcon"))
vc!.add(url)
vc!.completionHandler = {(result: SLComposeViewControllerResult) -> () in
if result == SLComposeViewControllerResult.cancelled {
print("取消分享")
}else {
print("分享")
}
}
present(vc!, animated: true, completion: nil)
}
let vc = UIActivityViewController(activityItems: ["分享標(biāo)題", UIImage(named: "headIcon")!, url], applicationActivities: nil)
present(vc, animated: true, completion: nil)
TODO
因?yàn)槭且粫r(shí)興起的小實(shí)踐瘤礁,所以還有很多細(xì)節(jié)有待深入優(yōu)化。比如ShareViewController
分享界面的自定義梅尤,比如SLComposeViewController
怎么同時(shí)分享標(biāo)題柜思、內(nèi)容岩调、圖片和URL,再比如UIActivityViewController
里分享內(nèi)容的組合和分享目標(biāo)平臺(tái)或操作的取舍展示赡盘,等等号枕。所以此篇小記錄權(quán)當(dāng)是拋磚引玉,展示這幾個(gè)功能的簡(jiǎn)單實(shí)現(xiàn)陨享,如果想實(shí)現(xiàn)一些更好的進(jìn)階優(yōu)化葱淳,可以再多看看官方文檔,深入研究抛姑。