探秘 iOS 14 的 WidgetKit

What’s new in Widget

• 能主屏显示

• 多种尺寸

• 不可交互,只可点击

• 智能叠放

Widget Extension 提供了 small, medium, large 三个尺寸,不同尺寸可以展示不同的数据、不同的界面,开发者也可以锁定自己APP的 Widget 只有某类尺寸,相同的widget也能重复添加。作为添加在主屏幕上的控件,苹果用了 “At a glance” 来形容 widget ,所以 widget extension 是无法交互的,它能做的只有展示一些信息与点击两个作用,点击后就会引导至app,同时为了性能与耗电量的考虑,Widget extension 也不能展示视频和动态图像。

另外用户可以将数个 Widget 放在同一个位置,这样 Widget 就会叠放在一起,它被叫做Widget Gallery,用户可以自由的切换顶部展示的 Widget。同时用户可以开启智能叠放,之后苹果会根据用户习惯等,在叠放的地方根据不同情况展示不同 Widget,如在每天早晨会展示天气 Widget,随后上下班通勤时会展示路况信息的Widget。开发者是无法指定自己的 Widget 在智能叠放中的位置的。

What’s new in Widget Development

以上的特定更多是产品上的表现形式,作为开发者我们更关心的是新的 Widget Extension 需要怎么开发:

• Swift UI Only

• Timeline Update

• IntentConfiguration

• Link

首先 Widget extension 只能通过Swift ui来开发,是没有办法调用任何UIKit的元素。只能使用Swift UI是一个大胆但也很合理的尝试,因为它很方便的适配暗黑模式、动态字体等元素,用在Widget开发上能够确保都能符合苹果的设计理念,同时iOS、iPadOS、macOS上的 Widget 也能利用同一套代码。

另外 widget extension 的刷新是基于时间线(Timeline)的刷新,不再是原有 Widget 基于UIViewController的各种刷新时机了,比如一个股票的widget,在交易的时候可以频繁更新,但是在非交易时段是可以完全不更新的,所以根据这个规律,开发者可以提前设置这个widget 的更新时间线,然后系统就会在对应的时间节点去自动更新 widget。

而 Widget 的展示的内容也是可以让用户去定制的,比如天气 widget 可以让用户去选择展示的城市,这个定制的选项是使用了 Intents 这个框架,这个框架最开始是在SiriKit上使用的,开发者是不需要编写代码,只需要加相关的配置项就可以自动生成界面和选项了。

最后 Widget 点击的跳转是通过一个叫Link的类去处理,类似NSURL。

Timeline Reload

在新的 Widget 中,刷新是基于 Timeline 的,Timeline是一系列Timeline entry的集合,Timeline entry包括了时间节点与对应时间节点 Widget 要展示的信息,Widget 的刷新完全由 WidgetCenter控制。开发者无法通过任何 API 去主动刷新 Widget 的页面,只能告知 WidgetCenter,Timeline 需要刷新了。

系统提供了两种方式来驱动 Timeline 的刷新。System Reloads(系统刷新) 和 App-Driven Reloads(App通知的刷新)

System Reloads

• 可预测事件

• 按时发起

• 动态决策

System Reloads 通常是用于可预测事件的刷新,如股票 Widget ,他能预知每个交易日的开始时间和结束时间,所以开发者可以提前告诉WidgetCenter,它需要在什么时候刷新该 Widget 的时间线,在什么时候可以停止刷新。

这个行为由系统主动发起,会刷新 Widget 的 Timeline ,向 Widget 请求下一阶段刷新的数据。系统会按时发起 System Reloads ,比如天气 Widget 设置了每天刷新一次,那么在对应的时间节点就会刷新;另外系统还会动态决策每个不同 Widget 的 TimeLine 的系统刷新频次,如果某个 Widget 经常被查看,那么它被刷新的频率将高于查看次数相对较低的 Widget 。

App-Driven Reloads

• 主动刷新

• 主APP必须存活

指的是 App 主动请求 Widget 下一阶段刷新的数据。这里也要分两种场景,应用在前台运行和应用在后台运行。当应用在前台运行的时候,App 可以直接请求WidgetCenter的 API 来触发 Reload Timeline;而当应用处于后台时,后台推送(Background Notification)也可以触发 Reload Timeline。

Timeline Provider

既然上文说到这个 “Reload” 并不是说刷新 Widget 的界面,而是说请求新的 Timeline 数据,那么TimelineProvider就是提供这个数据的对象。TimelineProvider提供的数据有两部分,一部分是TimelineEntry,另外一部分是 ReloadPolicy。

• TimelineEntry:包括了时间点与对应时间节点下 Widget 需要呈现的信息。

• ReloadPolicy:接下来这段时间 Timeline 的刷新策略,一共有三种:

• atEnd: 是指 Timeline 执行到最后一个TimelineEntry的时候再刷新。

• atAfter: 是指在某个时间以后有规律的刷新。

• never:是指以后不需要刷新了,什么时候需要重新刷新需要 App 重新告知 Widget。

当TimelineProvider提供完下一阶段的数据之后,就会停止运行。系统会根据TimelineEntry 的信息,在对应的时间节点对 Widget 的展示内容进行刷新。由于开发者只提供了TimeLineEntry和ReloadPolicy,所以 Widget 界面真正的刷新时间和刷新频率其实全部都是交给系统控制的,这样系统能够更好的把控 Widget 的耗电量与刷新频率,避免某个 Widget 由于大量的刷新导致消耗了过多的电量。

Intent Configuration

• 无需编写UI代码

• 用户设置后会刷新 Widget 界面

在用户使用的过程中,Widget 是需要一定的自定义能力,比如当我添加一个天气 Widget,我可以选择我 Widget 要显示哪个地方的天气。为了实现这个能力,苹果给 Widget 提供了 Configuration 的能力。顾名思义,就是可配置。一共有两种配置类型:

• StaticConfiguration:静态配置,只和用户信息有关系

• IntentConfiguration:动态配置,支持用户自定义

IntentConfiguration的实现是基于 Intents.framework,开发过 SiriKit 和 Shortcuts 的同学一定知道 Intents API 是用于了解用户意图的。简要的说它是一个智能的表单系统,创建一个 SiriKit Intent Definition File 之后,只需要简单的配置,Xcode 会自动帮你生成对应的代码和UI。

Link

Widget 的 UI 是不支持滚动等交互元素的。唯一开放的能力只有通过点击或DeepLink 来唤起主 App。

苹果提供了两种 API 给到开发者,第一种是SwiftUI 的 WidgetURL API,它的可点击区域是在整个widget页面。

对于 systemSmall 类型来说,只支持 widgetURL 的方式,但是对于 systemMedium 和 systemLarge 还可以使用 SwiftUI Link API,而 Link 的可点击区域是这样的:

总结

新的 Widget 带来了更多的信息展示窗口,APP能够通过 Widget 在主屏幕上更好的展示数据,其新特性也是十分吸引与有趣。另外需要注意的是新 Widget 目前还是在Beta版本,接口尚不稳定(如原有的PlaceHolder就被废弃了),开发时还需要注意这方面的坑。

参考

[1] https://mp.weixin.qq.com/s/ujZfU1CEQ1EfqoO8UR_kSg
[2] https://developer.apple.com/design/human-interface-guidelines/ios/system-capabilities/widgets
[3] https://developer.apple.com/news/?id=yv6so7ie
[4] https://developer.apple.com/documentation/widgetkit/creating-a-widget-extension


https://mp.weixin.qq.com/s/Vk5UFzfvAKwFzHqdrZ4S6g

iOS APP 图标版本化

在我们的项目开发过程中,需要频繁打包给测试人员去测试,有时候我们都不知道测试机上安装的版本是否是最新的,这样会造成很多不必要的麻烦和成本。因此我们需要将buildNumber以水印的方式打在APPIcon上,可以很直观的知道当前是哪一个版本。

发布于:8天以前  |  21次阅读  |  详细内容 »

如何实现一个HTTP请求库——axios源码阅读与分析

在前端开发过程中,我们经常会遇到需要发送异步请求的情况。而使用一个功能齐全,接口完善的HTTP请求库,能够在很大程度上减少我们的开发成本,提高我们的开发效率。

发布于:9天以前  |  23次阅读  |  详细内容 »

老司机 iOS 周报 #144 | 2021-01-14

发布于:12天以前  |  44次阅读  |  详细内容 »

快手,快影 iOS App反调试

发布于:19天以前  |  65次阅读  |  详细内容 »

优酷iOS插件化页面架构方法

随着业务不停地迭代,优酷 APP 用于分发视频资源的 UI 控件越写越多,也越来越复杂,并且同时相似相近的代码也非常多。

发布于:2月以前  |  180次阅读  |  详细内容 »

iOS中的内嵌汇编

写一篇在iOS上使用汇编的文章的想法在脑袋里面停留了很久了,但是迟迟没有动手。虽然早前在做启动耗时优化的工作中,也做过通过拦截objc_msgSend并插入汇编指令来统计方法调用耗时的工作,但也只仅此而已。刚好最近的时间项目在做安全加固,需要写更多的汇编来提高安全性(文章内汇编使用指令集为ARM64),也就有了本文

发布于:2月以前  |  182次阅读  |  详细内容 »

77.9K 的 Axios 项目有哪些值得借鉴的地方

Axios 是一个基于 Promise 的 HTTP 客户端,同时支持浏览器和 Node.js 环境。它是一个优秀的 HTTP 客户端,被广泛地应用在大量的 Web 项目中。

发布于:2月以前  |  166次阅读  |  详细内容 »

不会吧,这也行?iOS后台锁屏监听摇一摇

一般情况下,出于省电、权限、合理性等因素考虑,给人的感觉是很多奇怪的需求安卓可以实现,但是iOS就无法实现!今天要介绍的需求也有这种感觉,就是“当 APP 处于后台或锁屏状态时,依旧可以监听到摇一摇,进而触发某些功能,比如:语音播报”。

发布于:3月以前  |  306次阅读  |  详细内容 »

iOS 稳定性:App 被终止的原因

本次 session 主要内容如下: 介绍了后台应用终止的常见原因,并提供了一些优化建议 介绍了 MetricsKit 提供的在代码中获取诊断和性能数据的方法 介绍了 Xcode Metrics Ogranizer 提供的关于线上用户性能数据的可视化报告

发布于:3月以前  |  421次阅读  |  详细内容 »

优酷iOS插件化页面架构方法

随着业务不停地迭代,优酷 APP 用于分发视频资源的 UI 控件越写越多,也越来越复杂,并且同时相似相近的代码也非常多。

发布于:3月以前  |  318次阅读  |  详细内容 »

Vue中Axios的封装和API接口的管理

在vue项目中,和后台交互获取数据这块,我们通常使用的是axios库,它是基于promise的http库,可运行在浏览器端和node.js中。他有很多优秀的特性,例如拦截请求和响应、取消请求、转换json、客户端防御XSRF等。所以我们的尤大大也是果断放弃了对其官方库vue-resource的维护,直接推荐我们使用axios库。如果还对axios不了解的,可以移步axios文档。

发布于:3月以前  |  292次阅读  |  详细内容 »

iOS 持续集成:更完备的 App Store Connect API

时隔两年 App Store Connect API 有了更新,WWDC 2018 推出了 App Store Connect API ,用于自动化一些 App Store Connect 后台操作。这次更新包含了 app 元数据相关的API,补上了原来缺失的重要一环, 使得几乎可以通过 App Store Connect API 完成 App Store Connect 上的所有操作。今后开发、证书配置、用户管理、测试、发布全流程都可以通过 API 完成。

发布于:3月以前  |  354次阅读  |  详细内容 »

iOS 性能优化:优化 App 启动速度

苹果是一家特别注重用户体验的公司,过去几年一直在优化 App 的启动时间,特别是去年的 WWDC 2019 keynote[1] 上提到,在过去一年苹果开发团队对启动时间提升了 200%

发布于:3月以前  |  327次阅读  |  详细内容 »

iOS圆角的离屏渲染,你真的弄明白了吗

发布于:3月以前  |  307次阅读  |  详细内容 »

iOS导航栏整体滑动解决方案(类似淘宝)

发布于:3月以前  |  359次阅读  |  详细内容 »

让你的应用远离越狱:iOS 14 App Attest 防护功能

当越狱在 iOS 设备第一次流行起来时,iOS 开发人员会尝试各种方法来保护自己的应用程序,以让应用免受盗版等不确定因素的困扰。有许多方法可以做到这一点,包括检查 Cydia 是否存在、检测应用程序是否可读取自身沙箱之外的文件、在检测到调试器时让应用程序崩溃等等。

发布于:3月以前  |  346次阅读  |  详细内容 »

探秘 iOS 14 的 WidgetKit

Widget Extension 提供了 small, medium, large 三个尺寸,不同尺寸可以展示不同的数据、不同的界面,开发者也可以锁定自己APP的 Widget 只有某类尺寸,相同的widget也能重复添加。作为添加在主屏幕上的控件,苹果用了 “At a glance” 来形容 widget ,所以 widget extension 是无法交互的,它能做的只有展示一些信息与点击两个作用,点击后就会引导至app,同时为了性能与耗电量的考虑,Widget extension 也不能展示视频和动态图像。

发布于:3月以前  |  384次阅读  |  详细内容 »

iOS 的自动构建流程

发布于:3月以前  |  410次阅读  |  详细内容 »

iOS14 Widget 万字指北,先人一步获得顶级流量

2020 年 6 月 22 日,苹果召开了第一次线上的开发者大会 - WWDC20。这次发布会上宣布了ARM架构Mac芯片(拳打Intel)、iOS 14 ATT(脚踢Facebook),可谓是一次载入史册(我是爸爸)的发布会了,当然还发布了被称为下一个顶级流量入口的Widget。踩着八月的尾巴,本次我们就来探究一下Widget。本文会从Widget初窥和Widget开发两个维度和章节来探究一下Widget, 其中初窥章节会带您简单的了解一下Widget,适合应用决策者阅读; 开发章节会带着您一步一步的完成设计开发Widget,适合程序员阅读。

发布于:3月以前  |  523次阅读  |  详细内容 »

iOS 性能优化 - Allocations分析内存分配

发布于:3月以前  |  375次阅读  |  详细内容 »

最多阅读

快速配置 Sign In with Apple 1年以前  |  3784次阅读
开篇 关于iOS越狱开发 1年以前  |  2565次阅读
APP适配iOS11 1年以前  |  2526次阅读
使用 GPUImage 实现一个简单相机 1年以前  |  2509次阅读
给数组NSMutableArray排序 1年以前  |  2487次阅读
在越狱的iPhone设置上使用lldb调试 1年以前  |  2440次阅读
App Store 审核指南[2017年最新版本] 1年以前  |  2336次阅读
UITableViewCell高亮效果实现 1年以前  |  2318次阅读
所有iPhone设备尺寸汇总 1年以前  |  2258次阅读
使用ssh访问越狱iPhone的两种方式 1年以前  |  2193次阅读
关于Xcode不能打印崩溃日志 1年以前  |  2117次阅读
使用ssh 访问越狱iPhone的两种方式 1年以前  |  2016次阅读
UIDevice的简单使用 1年以前  |  1805次阅读
为对象添加一个释放时触发的block 1年以前  |  1783次阅读
使用最高权限操作iPhone手机 1年以前  |  1749次阅读