有關(guān)iOS分享的兩個(gè)小實(shí)踐

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)化葱淳,可以再多看看官方文檔,深入研究抛姑。

參考鏈接

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末赞厕,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子定硝,更是在濱河造成了極大的恐慌皿桑,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,198評(píng)論 6 514
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蔬啡,死亡現(xiàn)場(chǎng)離奇詭異诲侮,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)箱蟆,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,334評(píng)論 3 398
  • 文/潘曉璐 我一進(jìn)店門沟绪,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人空猜,你說我怎么就攤上這事绽慈。” “怎么了抄肖?”我有些...
    開封第一講書人閱讀 167,643評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵久信,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我漓摩,道長(zhǎng)裙士,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,495評(píng)論 1 296
  • 正文 為了忘掉前任管毙,我火速辦了婚禮腿椎,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘夭咬。我一直安慰自己啃炸,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,502評(píng)論 6 397
  • 文/花漫 我一把揭開白布卓舵。 她就那樣靜靜地躺著南用,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上裹虫,一...
    開封第一講書人閱讀 52,156評(píng)論 1 308
  • 那天肿嘲,我揣著相機(jī)與錄音,去河邊找鬼筑公。 笑死雳窟,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的匣屡。 我是一名探鬼主播封救,決...
    沈念sama閱讀 40,743評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼捣作!你這毒婦竟也來了誉结?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,659評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤券躁,失蹤者是張志新(化名)和其女友劉穎搓彻,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體嘱朽,經(jīng)...
    沈念sama閱讀 46,200評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,282評(píng)論 3 340
  • 正文 我和宋清朗相戀三年怔接,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了搪泳。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,424評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡扼脐,死狀恐怖岸军,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情瓦侮,我是刑警寧澤艰赞,帶...
    沈念sama閱讀 36,107評(píng)論 5 349
  • 正文 年R本政府宣布,位于F島的核電站肚吏,受9級(jí)特大地震影響方妖,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜罚攀,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,789評(píng)論 3 333
  • 文/蒙蒙 一党觅、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧斋泄,春花似錦杯瞻、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,264評(píng)論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春旗唁,著一層夾襖步出監(jiān)牢的瞬間畦浓,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,390評(píng)論 1 271
  • 我被黑心中介騙來泰國(guó)打工宅粥, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留电谣,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,798評(píng)論 3 376
  • 正文 我出身青樓剿牺,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親晒来。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,435評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容