分享内容
国内主流 app 的分享功能都是自定义的,这样做的考虑主要是为了让流量留在自己的生态中,另一方面 UIActivityViewController 不太符合国人的使用习惯。
相比之下,国外的 app 如 Twitter,使用的都是苹果从 iOS 6 开始引入的 UIActivityViewController。
如果你的 app 面向国外用户,UIActivityViewController 了解一下。:)
UIActivityViewController 使用起来非常方便,首先初始化一个实例:
init(activityItems: [Any], applicationActivities: [UIActivity]?)
其中,activityItems
是你要分享的内容,可以是字符串、URL或者图片等内容。但是接受分享的应用能接受的文件类型不一样,我们还可以通过自定义 activityItems
来实现以不同形式分享到不同应用的功能。
要自定 activityItems
,只需实现 UIActivityItemSource
,它有两个必选方法:
func activityViewControllerPlaceholderItem(_ activityViewController: UIActivityViewController) -> Any
func activityViewController(_ activityViewController: UIActivityViewController,
itemForActivityType activityType: UIActivityType?) -> Any?
其中第一个方法返回一个 placeholder,官方文档是这样解释的
For example, the placeholder could be a UIImage object but the actual value could be an NSData object with PDF information.
个人理解是比如 PDF 渲染速度较慢,UIActivityViewController 会先查询 placeholder 显示出来。
第二个方法返回的就是实际要分享的内容,可以根据不同的 UIActivityType 返回不同类型的数据。比如拷贝到剪贴板返回字符串,分享到微信返回图片。如果分享的是一个自定义文件,返回文件的 URL 即可。
至于 UIActivityItemProvider
,只是官方给出的一个实现了 UIActivityItemSource
协议的类。
实例化完毕之后,UIActivityViewController 还有一些属性需要设置:
excludedActivityTypes
:设置你不想显示的分享类型。popoverPresentationController?.sourceView
:在 iPad 上显示成 popover 时需要设置popoverPresentationController?.sourceRect
:在 iPad 上显示成 popover 时需要设置popoverPresentationController?.barButtonItem
:在 iPad 上显示成 popover 时需要设置completionWithItemsHandler
:分享结束后的回调
最后 present 设置完毕的 UIActivityViewController。
至此,分享功能就介绍完了。
打开分享的文件
但是如果想用你的 app 打开某个文件,也就是出现在 UIActivityViewController 分享界面中,还需要做额外的一些工作。
在开始之前,你需要了解 UTI(Uniform Type Identifiers) 的概念。
简单来讲,UTI 是苹果定义的用来区分文件类型的标志符。同样是文本文件,不同文件的后缀名可能是 txt、text、html,但实际上一个纯文本编辑器都能打开它们。如果系统遇到一个陌生的文件后缀,也可以通过 UTI 来正确识别,并且知道哪些应用可以用来打开这个文件。
可以看到 UTI 本身是个树形结构,类似于类的继承关系,所有的 UTI 都符合(Conforms To)public.data
,可以理解成所有 UTI 最终都是 public.data
的子 UTI。
现在要做的就是在 Xcode 的 Info.plist 中的 Document Type 里添加要支持的 UTI,具体步骤参见官方文档。可以根据 Apple 已经定义好的 UTI 列表添加对应的 UTI。
这样,当用户分享特定文件时就可以看到你的 app 了,如何获取内容呢?
AppDelegate 有个方法:
func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool
当系统通过你的 app 打开文件时会调用这个方法,其中的 url
就是文件的 URL,可以通过这个 URL 来获取文件内容。
自定义文件类型
如果你的 app 会生成自定义格式,那么你需要声明一个自定义的 UTI,Exported UTI 了解一下。
要声明一个自定义的 UTI 需要以下几个信息:
UTTypeIdentifier:自定义 UTI 的唯一标识符。
UTTypeTagSpecification:包含后缀名、对应的 MIME type 等信息。
UTTypeConformsTo:符合的已有 UTI,可以理解成父 UTI。
UTTypeIconFile(可选):文件显示的图标
UTTypeDescription:用来描述文件类型的字符串
要注意的是:
- 要保证自定义 UTTypeIdentifier 的唯一性,可以使用
官方的一个示例:
<key>UTExportedTypeDeclarations</key>
<array>
<dict>
<key>UTTypeIdentifier</key>
<string>public.jpeg</string>
<key>UTTypeReferenceURL</key>
<string>http://www.w3.org/Graphics/JPEG/</string>
<key>UTTypeDescription</key>
<string>JPEG image</string>
<key>UTTypeIconFile</key>
<string>public.jpeg.icns</string>
<key>UTTypeConformsTo</key>
<array>
<string>public.image</string>
<string>public.data</string>
</array>
<key>UTTypeTagSpecification</key>
<dict>
<key>com.apple.ostype</key>
<string>JPEG</string>
<key>public.filename-extension</key>
<array>
<string>jpeg</string>
<string>jpg</string>
</array>
<key>public.mime-type</key>
<string>image/jpeg</string>
</dict>
</dict>
</array>
具体的添加方法,参见官方文档。