iOS的Share Extension直接分享視頻到微信

iOS11開始不能通過SLComposeViewController直接分享到微信了妖谴,只能通過UIActivityViewController一步一步來,分享步驟比較繁瑣。已經(jīng)放棄玖详。
——2017年11月1日

iOS app分享內(nèi)容到微信有兩種方式:

1 集成微信官方SDK挖藏,跳轉(zhuǎn)到微信分享(參看簡書app分享)
2 利用iOS Social.framework直接在自己的app內(nèi)部實現(xiàn)分享(參看系統(tǒng)相冊的分享)

集成微信官方SDK暑刃,跳轉(zhuǎn)到微信分享 ![Uploading share3_795019.gif . . .]
利用iOS Social.framework直接在自己的app內(nèi)部實現(xiàn)分享

Social.framework直接在自己的app內(nèi)部實現(xiàn)分享圖片

項目第一版要求直接分享多張圖片到朋友圈,第一種分享方式是不支持的膜眠,通過系統(tǒng)相冊分享發(fā)現(xiàn)可以選中多張照片分享給朋友或者朋友圈岩臣。
代碼:

    UIImage *imageToShareOne = [UIImage imageNamed:@"獅子"];
    UIImage *imageToShareTwo = [UIImage imageNamed:@"老虎"];
    
    NSArray *activityItems = @[imageToShareOne, imageToShareTwo];
    
    UIActivityViewController *activityVC = [[UIActivityViewController alloc]initWithActivityItems:activityItems
                                            
                                                                            applicationActivities:nil];
    
    //不出現(xiàn)在活動項目
    activityVC.excludedActivityTypes = @[UIActivityTypePrint, UIActivityTypeCopyToPasteboard,
                                         
                                         UIActivityTypeAssignToContact,UIActivityTypeSaveToCameraRoll];
    
    // 3.彈出分享控制器(以Modal形式彈出)
    UIViewController * rootVc = [UIApplication sharedApplication].keyWindow.rootViewController;
    [rootVc presentViewController:activityVC animated:TRUE completion:nil];
UIActivityViewController分享到微信.gif

產(chǎn)品大大看后說能不能簡化一下,現(xiàn)在讓用戶分享到微信需要操作太多步驟宵膨,省掉第一步選擇微信直接出現(xiàn)分享界面架谎。

通過SLComposeViewController好像可以實現(xiàn)直接分享,composeViewControllerForServiceType方法傳遞一個需要分享的app對應的serviceType辟躏,然后返回一個SLComposeViewController對象谷扣,然后present這個對象就可以.
但是系統(tǒng)api只給了這么幾個app的字符串:Twitter ,F(xiàn)acebook 捎琐,SinaWeibo 会涎,TencentWeibo裹匙,LinkedIn 我想直接分享到微信該怎么辦?

SOCIAL_EXTERN NSString *const SLServiceTypeTwitter NS_AVAILABLE(10_8, 6_0);
SOCIAL_EXTERN NSString *const SLServiceTypeFacebook NS_AVAILABLE(10_8, 6_0);
SOCIAL_EXTERN NSString *const SLServiceTypeSinaWeibo NS_AVAILABLE(10_8, 6_0);
SOCIAL_EXTERN NSString *const SLServiceTypeTencentWeibo NS_AVAILABLE(10_9, 7_0);
SOCIAL_EXTERN NSString *const SLServiceTypeLinkedIn NS_AVAILABLE(10_9, NA);

感謝大神解救了我:程序內(nèi)分享到微信
iOS8之后系統(tǒng)推出的Share Extension末秃,微信App的Share Extension往系統(tǒng)里注冊了分享到微信需要的serviceType為:"com.tencent.xin.sharetimeline"
做法如下,代碼:

    NSString *test = @"com.tencent.xin.sharetimeline";
    if (![SLComposeViewController isAvailableForServiceType:test]) {
        NSLog(@"或者沒有配置相關的帳號");
        return;
    }
    
    // 2.創(chuàng)建分享的控制器
    SLComposeViewController *composeVc = [SLComposeViewController composeViewControllerForServiceType:test];
    if (composeVc == nil){
        NSLog(@"沒有安裝微信");
        return;
    }
    // 2添加圖片
    [composeVc addImage:[UIImage imageNamed:@"獅子"]];
    [composeVc addImage:[UIImage imageNamed:@"老虎"]];
    
    // 3.彈出分享控制器(以Modal形式彈出)
    UIViewController * rootVc = [UIApplication sharedApplication].keyWindow.rootViewController;
    [rootVc presentViewController:composeVc animated:TRUE completion:nil];
    
    // 4.監(jiān)聽用戶點擊了取消還是發(fā)送
    /*
     SLComposeViewControllerResultCancelled,
     SLComposeViewControllerResultDone
     */
    composeVc.completionHandler = ^(SLComposeViewControllerResult result){
        if (result == SLComposeViewControllerResultCancelled) {
            NSLog(@"點擊了取消");
        } else {
            NSLog(@"點擊了發(fā)送");
        }
    };
SLComposeViewController分享

那是不是qq也實現(xiàn)了Share Extension概页,并且往系統(tǒng)注冊了自己的serviceType,以及其他的app有沒有呢蛔溃?

程序內(nèi)分享到微信這篇文章告訴我們绰沥,只需調(diào)用下面一句代碼。

  SLComposeViewController *composeVc = [SLComposeViewController composeViewControllerForServiceType:SLServiceTypeSinaWeibo];

下面看看控制臺輸出贺待,手機內(nèi)所有可用的Share Extension的bundle Id 都出來了

2017-06-07 17:39:32.529838 ShareVedioWechat[56472:7845914] [core] SLComposeViewController _shareExtensionWithIdentifier: continuous discovery block got extensions (
    "<NSExtension: 0x1703612c0> {id = com.apple.reminders.RemindersEditorExtension}",
    "<NSExtension: 0x17017fe00> {id = com.apple.Health.HealthShareExtension}",
    "<NSExtension: 0x170360000> {id = com.apple.mobileslideshow.StreamShareService}",
    "<NSExtension: 0x170360180> {id = com.apple.Music.MediaSocialShareService}",
    "<NSExtension: 0x170360300> {id = com.apple.share.SinaWeibo.post}",
    "<NSExtension: 0x170360480> {id = com.apple.share.Twitter.post}",
    "<NSExtension: 0x170360600> {id = com.apple.share.Flickr.post}",
    "<NSExtension: 0x170360780> {id = com.tencent.mqq.ShareExtension}",
    "<NSExtension: 0x170360900> {id = com.apple.share.Vimeo.post}",
    "<NSExtension: 0x170360a80> {id = com.apple.mobilenotes.SharingExtension}",
    "<NSExtension: 0x170360c00> {id = com.apple.share.TencentWeibo.post}",
    "<NSExtension: 0x170360d80> {id = com.apple.share.Facebook.post}",
    "<NSExtension: 0x17017fc80> {id = com.sina.weibo.ShareExtension}",
    "<NSExtension: 0x170360fc0> {id = com.tencent.xin.sharetimeline}",
    "<NSExtension: 0x170361140> {id = com.jianshu.Hugo.Share-Extension}"
) error (null)
2017-06-07 17:39:32.531016 ShareVedioWechat[56472:7845914] [core] SLComposeViewController _shareExtensionWithIdentifier: continuous discovery block did update _identifierToShareExtensionMap {
    "com.apple.Health.HealthShareExtension" = "<NSExtension: 0x17017fe00> {id = com.apple.Health.HealthShareExtension}";
    "com.apple.Music.MediaSocialShareService" = "<NSExtension: 0x170360180> {id = com.apple.Music.MediaSocialShareService}";
    "com.apple.mobilenotes.SharingExtension" = "<NSExtension: 0x170360a80> {id = com.apple.mobilenotes.SharingExtension}";
    "com.apple.mobileslideshow.StreamShareService" = "<NSExtension: 0x170360000> {id = com.apple.mobileslideshow.StreamShareService}";
    "com.apple.reminders.RemindersEditorExtension" = "<NSExtension: 0x1703612c0> {id = com.apple.reminders.RemindersEditorExtension}";
    "com.apple.share.Facebook.post" = "<NSExtension: 0x170360d80> {id = com.apple.share.Facebook.post}";
    "com.apple.share.Flickr.post" = "<NSExtension: 0x170360600> {id = com.apple.share.Flickr.post}";
    "com.apple.share.SinaWeibo.post" = "<NSExtension: 0x170360300> {id = com.apple.share.SinaWeibo.post}";
    "com.apple.share.TencentWeibo.post" = "<NSExtension: 0x170360c00> {id = com.apple.share.TencentWeibo.post}";
    "com.apple.share.Twitter.post" = "<NSExtension: 0x170360480> {id = com.apple.share.Twitter.post}";
    "com.apple.share.Vimeo.post" = "<NSExtension: 0x170360900> {id = com.apple.share.Vimeo.post}";
    "com.jianshu.Hugo.Share-Extension" = "<NSExtension: 0x170361140> {id = com.jianshu.Hugo.Share-Extension}";
    "com.sina.weibo.ShareExtension" = "<NSExtension: 0x17017fc80> {id = com.sina.weibo.ShareExtension}";
    "com.tencent.mqq.ShareExtension" = "<NSExtension: 0x170360780> {id = com.tencent.mqq.ShareExtension}";
    "com.tencent.xin.sharetimeline" = "<NSExtension: 0x170360fc0> {id = com.tencent.xin.sharetimeline}";
}

SLComposeViewController能調(diào)用所有Share Extension徽曲。實現(xiàn)直接分享
至此完美解決,之后項目完成發(fā)版

Social.framework直接在自己的app內(nèi)部實現(xiàn)分享視頻

項目發(fā)版之后馬不停蹄開始下一版本的迭代麸塞,產(chǎn)品說分享圖片很好秃臣,但是我們要做的更diao,為了讓用戶更加直觀的了解我們的產(chǎn)品,我們要分享視頻哪工!像圖片一樣直接分享奥此,略過選擇微信這一步*&¥##¥%#……&……%……%
我。雁比。稚虎。。偎捎。蠢终。這要命。
看一下SLComposeViewController的頭文件里暴露的接口:

屏幕快照 2017-06-07 下午3.43.50.png

有關設置分享內(nèi)容的方法就這么幾個茴她,vedio往哪里放寻拂??丈牢?

通過操作發(fā)現(xiàn)祭钉,系統(tǒng)相冊可以選擇視頻分享到微信的,并且彈出的應該也是SLComposeViewController

一步一步的來己沛,先實現(xiàn)和系統(tǒng)一樣的分享視頻功能,
第一步:先把視頻下載到沙盒中(我用的AFN下載)
第二步:把視頻保存到相冊中慌核,拿到在相冊中的地址url(這步是必須的,我嘗試直接通過視頻在沙盒中的地址url分享申尼,每次都發(fā)送不成功)
第三步:分享

  • 其中前兩步是基礎工作垮卓,必須先將視頻保存到相冊拿到相冊中的url,通過把url傳給SLComposeViewController或者UIActivityViewController來實現(xiàn)視頻的分享(為什么不能把視頻轉(zhuǎn)為NSData傳遞data或者干脆直接用沙盒中視頻的url分享之類的問題晶姊,我暫時也回答不了扒接,這些算是我趟過坑之后經(jīng)驗之談,雖然知其然更要知其所以然,但是好多東西蘋果爸爸都在藏著掖著钾怔,語焉不詳?shù)奈臋n碱呼,我暫時還沒有空深挖,只能出個基本教程)

下載代碼,url為視頻下載地址宗侦,filePathUrl為存到沙盒中的位置愚臀,fileName為存到沙盒中的名稱(ViewController.m文件中):

#pragma mark - 下載視頻
- (void)downloadVideoWithUrl:(NSString *)url filePath:(NSURL *)filePathUrl fileName:(NSString *)fileName {
    AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
    NSURLRequest *request = [[NSURLRequest alloc] initWithURL:[NSURL URLWithString:url]];
    NSURLSessionDownloadTask *task = [manager downloadTaskWithRequest:request progress:^(NSProgress *downloadProgress){
        NSLog(@"%@",downloadProgress);
    } destination:^NSURL *(NSURL *targetPath, NSURLResponse *response) {
        return filePathUrl;
    } completionHandler:^(NSURLResponse *response, NSURL *filePathUrl, NSError *error) {
        // 從沙盒保存到相冊
        [CLVedioDownloadManager save:filePathUrl fileName:fileName];
    }];
    [task resume];
}

把視頻保存到沙盒,url為視頻在沙盒中位置矾利,fileName為視頻名稱(CLVedioDownloadManager.m文件中):

+ (void)save:(NSURL*)url fileName:(NSString *)fileName{
    ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
    [library writeVideoAtPathToSavedPhotosAlbum:url
                                completionBlock:^(NSURL *assetURL, NSError *error) {
                                    if (error) {
                                        NSLog(@"保存視頻到相冊失敗:%@",error);
                                    } else {
                                        NSLog(@"保存視頻到相冊成功:%@",assetURL);
                                        [CLVedioShareManager directShareVedio:assetURL];
                                    }
                                }];
}

現(xiàn)在去相冊看看就可以看到保存下來的視頻了姑裂,基礎工作完成,
利用UIActivityViewController實現(xiàn)和相冊一樣的分享效果,其中url為視頻在相冊中的地址男旗,只需要傳遞一個url就可以分享視頻了:

+ (void)indirectShareVedio:(NSURL *)url {
    NSArray *activityItems = @[url];
    
    UIActivityViewController *activityVC = [[UIActivityViewController alloc]initWithActivityItems:activityItems
                                                                            applicationActivities:nil];
    //不出現(xiàn)在活動項目
    activityVC.excludedActivityTypes = @[UIActivityTypePrint, UIActivityTypeCopyToPasteboard,UIActivityTypeAssignToContact,UIActivityTypeSaveToCameraRoll,UIActivityTypeAddToReadingList];
    
    //給activityVC的屬性completionHandler寫一個block舶斧。
    //用以UIActivityViewController執(zhí)行結束后,被調(diào)用察皇,做一些后續(xù)處理茴厉。
    UIActivityViewControllerCompletionWithItemsHandler myBlock = ^(UIActivityType activityType, BOOL completed, NSArray * returnedItems, NSError * activityError)
    {
        
        if (completed)
        {
            
        }
        else
        {
            
        }
    };
    
    // 初始化completionHandler,當post結束之后(無論是done還是cancell)該blog都會被調(diào)用
    activityVC.completionWithItemsHandler = myBlock;
    
    UIViewController * rootVc = [UIApplication sharedApplication].keyWindow.rootViewController;
    [rootVc presentViewController:activityVC animated:TRUE completion:nil];
}
gif截圖時長有限可以分享成功.gif

下面要考慮的是如何省略掉UIActivityViewController直接通過SLComposeViewController分享什荣,省略了選擇微信的那一步矾缓。踩坑過程省略,直接說流程:
前提:這個項目不通過appStore分發(fā)下載稻爬,走企業(yè)賬號嗜闻,所以在我找不到合適的方法的時候,我用了私有方法桅锄。這樣不會存在不過審核這一說
SLComposeViewController的addImage琉雳,addURL這些方法最終都是在內(nèi)部轉(zhuǎn)化為NSExtensionItem對象,然后SLComposeViewController調(diào)用私有方法addExtensionItem實現(xiàn)分享內(nèi)容的加載竞滓。
思路:
自己用視頻在相冊中的地址url構造一個符合條件的NSExtensionItem的對象咐吼,然后對SLComposeViewController對象執(zhí)行addExtensionItem方法吹缔,參數(shù)就是自己構造的NSExtensionItem對象

代碼

+ (void)directShareVedio:(NSURL *)url {
    NSString *test = @"com.tencent.xin.sharetimeline";
    if (![SLComposeViewController isAvailableForServiceType:test]) {
        NSLog(@"或者沒有配置相關的帳號");
        return;
    }
    
    // 2.創(chuàng)建分享的控制器
    SLComposeViewController *composeVc = [SLComposeViewController composeViewControllerForServiceType:test];
    if (composeVc == nil){
        NSLog(@"沒有安裝微信");
        return;
    }
    // 重點
    [composeVc addVideoURL:url];
    
    // 3.彈出分享控制器(以Modal形式彈出)
    UIViewController * rootVc = [UIApplication sharedApplication].keyWindow.rootViewController;
    [rootVc presentViewController:composeVc animated:TRUE completion:nil];
    
    
    // 4.監(jiān)聽用戶點擊了取消還是發(fā)送
    /*
     SLComposeViewControllerResultCancelled,
     SLComposeViewControllerResultDone
     */
    composeVc.completionHandler = ^(SLComposeViewControllerResult result){
        if (result == SLComposeViewControllerResultCancelled) {
            NSLog(@"點擊了取消");
        } else {
            NSLog(@"點擊了發(fā)送");
        }
    };
}

(創(chuàng)建SLComposeViewController的category商佑,構造NSExtensionItem之后用self performSelector調(diào)用addExtensionItem):

#import "SLComposeViewController+Method.h"
#import <MobileCoreServices/MobileCoreServices.h>

@implementation SLComposeViewController (Method)

- (BOOL)addVideoURL:(NSURL *)url {
    NSItemProvider *itemProvider = [[NSItemProvider alloc] initWithItem:url typeIdentifier:(NSString *)kUTTypeQuickTimeMovie];    
    NSExtensionItem *extensionItem = [NSExtensionItem new];
    extensionItem.attachments = [NSArray arrayWithObject:itemProvider];
    
    return [self performSelector:@selector(addExtensionItem:) withObject:extensionItem];
}

@end
分享視頻省略選擇微信的步驟

至此完美完成需求

demo地址:https://github.com/thinkq/ShareVedioWechat

參考:程序內(nèi)分享到微信

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市厢塘,隨后出現(xiàn)的幾起案子茶没,更是在濱河造成了極大的恐慌,老刑警劉巖晚碾,帶你破解...
    沈念sama閱讀 218,755評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件抓半,死亡現(xiàn)場離奇詭異,居然都是意外死亡格嘁,警方通過查閱死者的電腦和手機笛求,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人探入,你說我怎么就攤上這事狡孔。” “怎么了蜂嗽?”我有些...
    開封第一講書人閱讀 165,138評論 0 355
  • 文/不壞的土叔 我叫張陵苗膝,是天一觀的道長。 經(jīng)常有香客問我植旧,道長辱揭,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,791評論 1 295
  • 正文 為了忘掉前任病附,我火速辦了婚禮问窃,結果婚禮上,老公的妹妹穿的比我還像新娘完沪。我一直安慰自己泡躯,他們只是感情好,可當我...
    茶點故事閱讀 67,794評論 6 392
  • 文/花漫 我一把揭開白布丽焊。 她就那樣靜靜地躺著较剃,像睡著了一般。 火紅的嫁衣襯著肌膚如雪技健。 梳的紋絲不亂的頭發(fā)上写穴,一...
    開封第一講書人閱讀 51,631評論 1 305
  • 那天,我揣著相機與錄音雌贱,去河邊找鬼啊送。 笑死,一個胖子當著我的面吹牛欣孤,可吹牛的內(nèi)容都是我干的馋没。 我是一名探鬼主播,決...
    沈念sama閱讀 40,362評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼降传,長吁一口氣:“原來是場噩夢啊……” “哼篷朵!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起婆排,我...
    開封第一講書人閱讀 39,264評論 0 276
  • 序言:老撾萬榮一對情侶失蹤声旺,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后段只,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體腮猖,經(jīng)...
    沈念sama閱讀 45,724評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年赞枕,在試婚紗的時候發(fā)現(xiàn)自己被綠了澈缺。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片坪创。...
    茶點故事閱讀 40,040評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖姐赡,靈堂內(nèi)的尸體忽然破棺而出误堡,到底是詐尸還是另有隱情,我是刑警寧澤雏吭,帶...
    沈念sama閱讀 35,742評論 5 346
  • 正文 年R本政府宣布锁施,位于F島的核電站,受9級特大地震影響杖们,放射性物質(zhì)發(fā)生泄漏悉抵。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,364評論 3 330
  • 文/蒙蒙 一摘完、第九天 我趴在偏房一處隱蔽的房頂上張望姥饰。 院中可真熱鬧,春花似錦孝治、人聲如沸列粪。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽岂座。三九已至,卻和暖如春杭措,著一層夾襖步出監(jiān)牢的瞬間费什,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評論 1 270
  • 我被黑心中介騙來泰國打工手素, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留鸳址,地道東北人。 一個月前我還...
    沈念sama閱讀 48,247評論 3 371
  • 正文 我出身青樓泉懦,卻偏偏與公主長得像稿黍,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子崩哩,可洞房花燭夜當晚...
    茶點故事閱讀 44,979評論 2 355

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

  • WebSocket-Swift Starscream的使用 WebSocket 是 HTML5 一種新的協(xié)議巡球。它實...
    香橙柚子閱讀 23,869評論 8 183
  • 今年的春天來的晚,人間四月芳菲始呀~~ 麥子該沒過腳脖子琢锋,放風箏的時節(jié)就到了辕漂。風箏是消耗品呢灶,還沒上幾次天就...
    楊舒綠閱讀 274評論 0 0
  • 如果我們下一次見面會是什么樣子吴超?那一定是久別重逢吧……我們之間就像是車窗外飛馳而過的風景當你回頭再看一眼時卻發(fā)現(xiàn)她...
    滕龍振華閱讀 673評論 0 10
  • 2009年,那年我鸯乃,19鲸阻;她跋涣,22… 夏天,毒火般的太陽烘烤著大地… 認識她是個偶然的機會鸟悴。高考失利我回到家鄉(xiāng)復讀...
    狼郎閱讀 201評論 0 1