做社会化分享,经典的做法就是在各个社会化平台申请 App Key,然后集成各个平台的 SDK,并分别进行开发。更简单的方式是用类似友盟分享 SDK、ShareSDK 之类的集成化 SDK,让多平台分享的开发更加容易。之前我和团队就是采用这种方式。
其实 iOS 本身提供了一种分享的方式,App Store 里的分享就是一个实现的例子:
这个弹出的分享框,叫做 UIActivityViewController。通过它来实现分享,好处是样式统一、实现简单,更重要的是它直接使用系统中设置的平台账号,并且不需要对应用进行授权。这一点降低了用户分享的心理负担。同时,开发者不需要去平台为应用申请 App Key,也一定程度上降低了开发的门槛。
但正是因为这种分享不依附于应用,所以也会带来一些缺点。比如分享出去的东西会显示“来自 iOS” 而不是你的应用,也导致了不能进行用户统计。而且通过这个只能做分享,不能用做 SSO 登录。对于只需要分享的简单场景下,用 UIActivityViewController 完全足够并且更加合适,所以我在词记里尝试了一下。
基本的实现非常简单,把需要分享的内容,可以是文字、图片、链接,传入初始化方法即可:
1 2 3 4
| NSString *str = @"Hello"; NSURL *url = [NSURL URLWithString:@"http://www.stoneark.org"]; UIActivityViewController *activityViewController = [[UIActivityViewController alloc] initWithActivityItems:@[str, url] applicationActivities:nil]; [self presentViewController:activityViewController animated:YES completion:nil];
|
如果需要为不同平台提供不同的分享内容,或者生成某个分享内容的过程较复杂,可以为这个内容创建一个 UIActivityItemProvider 的子类,并实现方法 -(id)activityViewController: itemForActivityType:
,如:
ShareTextProvider1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| @interface MonthViewShareTextProvider : UIActivityItemProvider @property (strong, nonatomic) NSString *shareText; @end @implementation MonthViewShareTextProvider - (id)activityViewController:(UIActivityViewController *)activityViewController itemForActivityType:(NSString *)activityType { if ([activityType isEqualToString:UIActivityTypeSaveToCameraRoll] || [activityType isEqualToString:UIActivityTypePrint] || [activityType isEqualToString:UIActivityTypeCopyToPasteboard] || [activityType isEqualToString:@"com.tencent.xin.sharetimeline"] ) { return nil; } else { return _shareText; } } @end
|
利用它去初始化 UIActivityViewController 时:
1 2 3 4
| ShareTextProvider *textProvider = [[ShareTextProvider alloc]initWithPlaceholderItem:@"Hello"]; [textProvider setShareText:@"Hello"]; UIActivityViewController *activityViewController = [[UIActivityViewController alloc]initWithActivityItems:@[textProvider] applicationActivities:nil]; [self presentViewController:activityViewController animated:YES completion:nil];
|
注意初始化方法里的 PlaceholderItem,它应该是能够正确反应内容数据类型的简单数据。在弹出的 UIActivityViewController 里,会根据这些 PlaceholderItem 的类型,来决定显示哪些选项,此时并不会去调用 ItemProvider 里的方法。比如有两个 UIImage,则会显示“存储 2 张图片”;如果没有 UIImage,则不会显示存储图片这一个按钮。当你真正点击某一项分享渠道时,才会调用其 itemForActivityType 方法来得到真正的内容。
你可能注意到了,上面微信的 activity type 用了字符串 @”com.tencent.xin.sharetimeline”。而关于 UIActivityType,查看 UIActivityType.h
,可以看到这些:
UIActivity.h1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| UIKIT_EXTERN NSString *const UIActivityTypePostToFacebook NS_AVAILABLE_IOS(6_0) __TVOS_PROHIBITED; UIKIT_EXTERN NSString *const UIActivityTypePostToTwitter NS_AVAILABLE_IOS(6_0) __TVOS_PROHIBITED; UIKIT_EXTERN NSString *const UIActivityTypePostToWeibo NS_AVAILABLE_IOS(6_0) __TVOS_PROHIBITED; UIKIT_EXTERN NSString *const UIActivityTypeMessage NS_AVAILABLE_IOS(6_0) __TVOS_PROHIBITED; UIKIT_EXTERN NSString *const UIActivityTypeMail NS_AVAILABLE_IOS(6_0) __TVOS_PROHIBITED; UIKIT_EXTERN NSString *const UIActivityTypePrint NS_AVAILABLE_IOS(6_0) __TVOS_PROHIBITED; UIKIT_EXTERN NSString *const UIActivityTypeCopyToPasteboard NS_AVAILABLE_IOS(6_0) __TVOS_PROHIBITED; UIKIT_EXTERN NSString *const UIActivityTypeAssignToContact NS_AVAILABLE_IOS(6_0) __TVOS_PROHIBITED; UIKIT_EXTERN NSString *const UIActivityTypeSaveToCameraRoll NS_AVAILABLE_IOS(6_0) __TVOS_PROHIBITED; UIKIT_EXTERN NSString *const UIActivityTypeAddToReadingList NS_AVAILABLE_IOS(7_0) __TVOS_PROHIBITED; UIKIT_EXTERN NSString *const UIActivityTypePostToFlickr NS_AVAILABLE_IOS(7_0) __TVOS_PROHIBITED; UIKIT_EXTERN NSString *const UIActivityTypePostToVimeo NS_AVAILABLE_IOS(7_0) __TVOS_PROHIBITED; UIKIT_EXTERN NSString *const UIActivityTypePostToTencentWeibo NS_AVAILABLE_IOS(7_0) __TVOS_PROHIBITED; UIKIT_EXTERN NSString *const UIActivityTypeAirDrop NS_AVAILABLE_IOS(7_0) __TVOS_PROHIBITED; UIKIT_EXTERN NSString *const UIActivityTypeOpenInIBooks NS_AVAILABLE_IOS(9_0) __TVOS_PROHIBITED;
|
里面并没有发现微信。通过运行时打印,可以整理出如下的表格:
方式 |
字符串常量 |
字符串内容 |
AirDrop |
UIActivityTypeAirDrop |
com.apple.UIKit.activity.AirDrop |
SMS |
UIActivityTypeMessage |
com.apple.UIKit.activity.Message |
Mail |
UIActivityTypeMail |
com.apple.UIKit.activity.Mail |
备忘录 |
N/A |
com.apple.mobilenotes.SharingExtension |
新浪微博 |
UIActivityTypePostToWeibo |
com.apple.UIKit.activity.PostToWeibo |
iBooks |
UIActivityTypeOpenInIBooks |
com.apple.UIKit.activity.OpenInIBooks |
QQ |
N/A |
com.tencent.mqq.ShareExtension |
微信 |
N/A |
com.tencent.xin.sharetimeline |
Twitter |
UIActivityTypePostToTwitter |
com.apple.UIKit.activity.PostToTwitter |
Facebook |
UIActivityTypePostToFacebook |
com.apple.UIKit.activity.PostToFacebook |
Flicker |
UIActivityTypePostToFlickr |
com.apple.UIKit.activity.PostToFlickr |
Vimeo |
UIActivityTypePostToVimeo |
com.apple.UIKit.activity.PostToVimeo |
腾讯微博 |
UIActivityTypePostToTencentWeibo |
com.apple.UIKit.activity.TencentWeibo |
提醒事项 |
N/A |
com.apple.reminders.RemindersEditorExtension |
保存到相册 |
UIActivityTypeSaveToCameraRoll |
com.apple.UIKit.activity.SaveToCameraRoll |
指定到联系人 |
UIActivityTypeAssignToContact |
com.apple.UIKit.activity.AssignToContact |
复制到剪贴板 |
UIActivityTypeCopyToPasteboard |
com.apple.UIKit.activity.CopyToPasteboard |
打印 |
UIActivityTypePrint |
com.apple.UIKit.activity.Print |
添加到阅读列表 |
UIActivityTypeAddToReadingList |
com.apple.UIKit.activity.AddToReadingList |
可以查阅 NSHipster上的这篇文章了解有关 UIActivityViewController 的更多信息。