WWDC18 Notes - What's New in Cocoa Touch

WWDC18 - Session 202 笔记

在 iOS 12 中,Apple 进一步增强了 Cocoa Touch 框架,着重提高了应用的性能表现,同时也带来了不少新功能。在 What’s New in Cocoa Touch 中,对性能上的最佳实践、安全改进、多尺寸与形状屏幕的适配工具、用于 iMessage Apps 的新 API、Siri Shortcuts 以及 Swift 优化等方面进行了概括介绍。

Framework Updates

Performance

此 Session 中主要通过 Scrolling、Memory 以及 Auto Layout 三个方面介绍了 iOS 12 中的性能改进。

Scrolling

首先通过 UITableView 举例,介绍 UIKit 中滑动加载的常见流程:

  • UITableViewDataSource cellForRowAt 方法中,重用或新初始一个 cell。
  • 使用模型数据中的内容来填充此 cell 。
  • 系统在 cell 上调用 layoutSubviews 方法,对 cell 中的内容进行布局。
  • 系统在 cell 上调用 draw 方法。

以上所有这些事务都必须在一次刷新间隔中完成,才能够保证流畅的滚动不掉帧。在 120 Hz 的 iPad Pro 上,间隔时间更短,所以需要尽可能快速的完成这些工作。在 iOS 10 中,UIKit 引入了 UITableViewDataSourcePrefetching Protocol 预加载,实现 prefetchRowsAt 方法之后,就能够提前在后台进行数据准备工作以提升性能表现,但加载当前 cell与预加载将来要显示的数据会同时发生。而在 iOS 12 中,将预加载工作放在了加载 cell 完成之后进行,如下图所示。
Markdown preferences pane
同时,在先前的版本中,从简单开销小的内容滑动到复杂开销大的内容时,由于 CPU 性能调度器进行调度需要时间,因此可能会造成卡顿。而在 iOS 12 中,会更加智能的进行 CPU 调度,由上层 UIKit 通知 CPU 准备调度,预先估算在 deadline 之前需要多少 CPU 性能来满足需求,进一步提升滑动流畅度。这些改进都无需开发者做额外的适配工作即可获得性能提升,但开发者仍应尽可能控制并减少开销时间。

Memory

关注内存的原因在于 Memory Is Performance。当应用发出较大的内存请求而处于 Free 状态的内存不够时,系统就需要从其他 App 与系统使用的内存中挪出部分试图满足需求。但腾出其他 App 占用的内存并不代表对自己的 App 没有影响,内核需要做很多工作花费 CPU 时间来准备出需要的内存,因此需要花费时间进行等待。减少内存占用有很多方法,但 iOS 12 中带来了一项新技术 - Automatic Backing Store。根据图像中的信息自动减少色彩位深度以减少内存占用。
Markdown preferences pane
在 iOS 12 中,UIView.draw()UIGraphicsImageRenderer以及UIGraphicsImageRendererFormat.Range会默认启用。在 Session 219 - Image and Graphics Best Practices 中,Apple 详细介绍了 Automatic Backing Store 的内容。

Auto Layout

在 iOS 12 中,Auto Layout 有了巨大的变化,在默认情况下都会变得更快。在处理较基础的独立同层视图布局约束时,在原先随视图数量计算耗时线性增长的基础上进一步减小了耗时。而在计算相互依赖的同层视图布局约束、嵌套的视图布局约束时,iOS 12 将原先随视图数量计算耗时指数级增长优化至了线性增长。如下图所示:
Markdown preferences pane
Session 220 - High Performance Auto Layout 中对此做了更详细的介绍。

Swiftification

在 Swift 4.2 中,让 UIKit 进一步 Swift 化,通过嵌套 Types/Constants/Functions,让 Swift 味更浓,用起来感觉更自然。如下:

  • Nested Constants:
    1. enum UIApplicationState 嵌套至了 class UIApplication 中。
    2. enum UITabBarItemPositioning 嵌套至了 class UITabBar 中。
  • Nested Constants:
    1. NSNotification/Name/didChangeStatusBarOrientation、全局常量 UIApplicationStatusBarOrientationUserInfoKey 移至了 class UIApplication 中。
    2. UIFloatRangeZeroUIFloatRangeInfinite 移至了 struct UIFloatRange 中。
  • Nested Functions:
    1. UIEdgeInsetsInsetRect(originalRect, insets) -> originalRect.insetBy(insets)
    2. UIImagePNGRepresentation(image) -> image.pngData()
    3. Codable Type 支持: NSStringFrom[CGPoint, CGRect, CGSize, CGVector, CGAffineTransform, UIEdgeInsets, UIOffset] / [CGPoint, CGRect, CGSize, CGVector, CGAffineTransform, UIEdgeInsets, UIOffset]FromString -> JSONEncoder().encode(CGPoint(x: 0, y: 0)) / JSONDecoder().decode(CGPoint.self, from: encoded) / NSCoder.string(for: CGPoint(x: 0, y: 0)) / NSCoder.cgPoint(for: encoded)

NSSecureCoding

新增默认安全编码与解码,老的 API 现在为 deprecated
关于此部分,详细可见 Session 222 - Data You Can Trust

API Enhancements

Notifications

iOS 12 中对消息通知也做出了较大的改进,主要体现在以下三方面:

  • Interaction
    自定义的通知界面中,允许添加使用自定义的交互,而不在限定于预先定义的动作。
  • Grouping
    分组通知。默认即会使用分组通知,将同一个 App 的通知集合到一个组中。同时也可以设定自己 App 通知消息分组的规则。
  • Settings
    在 iOS 12 中,可以在通知页让用户设置是否开启或关闭消息推送。
    关于通知部分的详情,可见 Session 710 - What’s New in User NotificationsSession 711 - Using Grouped Notifications

Messages

在 iOS 12 中,可以将 Message 贴纸置入到 Camera 中。在 Info.plist 中可添加新的 key:

1
2
3
4
5
<key>MSSupportedPresentationContexts</key>
<array>
<string>MSMessagesAppPresentationContextMessages</string>
<string>MSMessagesAppPresentationContextMedia</string>
</array>

Automatic Passwords and Security Code AutoFill

在 iOS 11 中,引入了自动输入密码功能,可以在 App 内快速输入已在 iCloud Keychain 中存储的密码。在 iOS 12 中,此功能做了进一步的改进,可以在 App 内保存密码到 iCloud Keychain,同时也可以在 App 给使用自动生成强密码功能。并且,如果应用后端对密码的格式有要求,也可以指定这些要求从而保证自动生成的密码符合规则。同时,iOS 12 中也带来了自动从信息中提取验证码,一键输入的功能。
关于自动密码与验证码输入详情,可见 Session 204 - Automatic Strong Passwords and Security Code AutoFill

Safe Area

通过适配 SafeAreaInsets 来适配不同形状、大小与内容布局格式的界面。主讲人呼吁开发者尽快适配 SafeArea。详细可见 Session 235 - UIKit: Apps for Every Size and Shape

Siri shortcuts

Siri shortcuts 是 iOS 12 中带来的新功能。给 App 提供了在 Siri Suggestion 中展示信息、在 Apple Watch Siri 表盘中展示信息,定义出发 Siri shortcuts 语言关键词等能力。可以通过以下 API 来适配 Siri shortcut。

NSUserActivity

与 Handoff 和 Spotlight 通用的 API。适合要在 App 中打开某些具体内容的情况。为 UserActivity 设置 eligibleForPrediction = true

Intents

提供最佳 shortcut 体验需要适配 intents,可以提供无需启动 app 即可运行、提供自定义的语音响应、自定义用户界面、定义预测场景等能力。
关于 Siri Shortcut 详情可见 Session 211 - Introduction to Siri Shortcuts / Session 214 - Building for Voice with Siri Shortcuts / Session 217 - Siri Shortcuts on the Siri Watch Face