2015 Session 224 App Extension Best Practices

地址 App Extension Best Practices (opens new window) 参考示例地址 RxDemo (opens new window) ,这次的 Demo 被我用在了 RxSwift 示例 APP 中,安装了 RxGank 你就可以直接在 Safari 分享你的干货到 Gank.io (opens new window)

每一次的 session 笔记都不算是分享,一种简单的记录复习 & 感悟咯,强烈建议自己看一遍

最近中文版也出来了,不过个人建议看英文的咯,如果看着比较累,也可以看一遍中文一遍英文,好啦,其实英文我看了好几遍,中文倒是没看,其实可以作为翻译的官方参考,我比较懒。

# 涉及 Tip

  • Action 和 Share 的使用及一些要点
  • 如何作为一个 host app 分享给其他 app 或者 web
  • Today Widget Enhancements

# Action and Share Extensions

# Action

Action 注重对当前内容的改变,主要有以下几种特点:

  • 操作当前内容
  • 当前内容就是用户界面
  • 一个 APP 可以提供多个 Action

# Share

Share 注重对当前内容的分享,主要有以下几种特点:

  • 将内容分享到你的 APP 或者 web 中 Shares content to your app or web service
  • 可以使用 SLComposeServiceViewController
  • 一个 APP 只能提供一个 Share

Share 的 Icon 不需要单独提供,系统使用你的 APP ICON 。

# SLComposeServiceViewController

我们可以从 Session 中看到一个分享图片的例子。

有一些快捷的属性和需要注意的点:

/// 更改 textView 的 placeholder
placeholder = "Caption (Optional)"

/// 更改左下角显示的数字
charactersRemaining = 80

/// 重写 loadPreviewView 更改右上角的预览图,下面这样就会不显示预览了 ==
override func loadPreviewView() -> UIView! {
    return UIView()
}
/// 重写 configurationItems 增加多个 Item ,注意返回的应当是 [SLComposeSheetConfigurationItem]
func configurationItems() -> [AnyObject]! {
  return [optionItem]
}

# Blur 效果

2016/03/15 更新

我们可不喜欢第一个 ViewController 背景都是模糊的,而 push 的都是白色的,反正就是不透明的。加一个模糊效果可以参考 so 上的方案:

if (!UIAccessibilityIsReduceTransparencyEnabled()) {
    tableView.backgroundColor = UIColor.clearColor()
    let blurEffect = UIBlurEffect(style: .Light)
    let blurEffectView = UIVisualEffectView(effect: blurEffect)
    tableView.backgroundView = blurEffectView

    //if inside a popover
    if let popover = navigationController?.popoverPresentationController? {
        popover.backgroundColor = UIColor.clearColor()
    }

    //if you want translucent vibrant table view separator lines
    tableView.separatorEffect = UIVibrancyEffect(forBlurEffect: blurEffect)
}

我们这里就不需要这么麻烦啦。

如果你用的 UITableViewController 只需要将 tableView 的背景设置成 clearColor ,只是要注意这里设置的位置在 View Section 上。

然后我们其实可以完全自行定制 UI ,继承 UIViewController 就好了。不过原生的 UI 也不错哦。

# SLComposeSheetConfigurationItem

这个没什么可说的。

  • title 显示在左边, value 灰色在右边,都是 String
  • 一般我们用它去 push 一个处理更多选项的 ViewController

# Being a good host

上面的部分都是介绍如何处理分享,这部分是如何做一个分享,也就是弹出一个分享菜单了~

let itemProvider = NSItemProvider()
itemProvider.registerItemForTypeIdentifier(kUTTypePlainText as String) {
   completionHandler, expectedClass, options in
   completionHandler(self.renderPlainTextDocumentString(), nil)
}
itemProvider.registerItemForTypeIdentifier(kUTTypePDF as String) {
   completionHandler, expectedClass, options in
   completionHandler(self.renderPDFDocument(), nil)
}
let vc = UIActivityViewController(activityItems: [ itemProvider ],
applicationActivities: nil)
self.presentViewController(vc, animated: true, completion: nil)

你可以去注册各种类型,Text 或者 Image 什么的。

如果在这里遇到 Use of unresolved identifier 'kUTTypePlainText' 之类的,加一个 import MobileCoreServices 就可以了。

这样我们就可以想 Photo 或者 Safari 一样分享我们的东西了。

有一点需要注意的是,我们做分享时最好加一个预览,像这样:

itemProvider.previewImageHandler = {
   completionHandler, expectedClass, options in
   completionHandler(self.renderThumbnail(), nil)
}

# Activation rules

在 iOS 9 中,新增加了一项非常有用的特性 Activation rules :

比如我们可以设置 NSExtensionActivationSupportsImageWithMaxCount2 ,这样一来当分享三个图片时,这个 Share Sheet 就不会出现在当前选项中。

完整的 Keys 移步到这里查询 App Extension Keys (opens new window)

# Today Widget Enhancements

这部分暂时超简单整理下,暂时 == 没时间写 Demo 之类的。

  • 可以使用 URL Scheme 唤起 APP 并传递一些消息
  • 可以使用 NSUserDefaults 和 container app 交互基本信息,当然也有更多的方式处理
  • 注意你可能需要后台刷新