Apple Widget:下一個頂級流量入口?

0x00 前言

2020 年 6 月 22 日,蘋果召開了第一次線上的開發者大會 - WWDC20。這可謂是一次能夠載入史冊的發佈會,宣佈了 ARM 架構 Mac 芯片、軟硬件的生態大統1、iOS 14 系統界面大改等一系列激動人心的消息。前端

固然,最讓我感興趣的就是讓 iOS 界面大改的 Widget 了。過去幾年,iOS 的桌面交互體驗可謂是一言難盡,Widget 的加入無疑是一次比較大的破局。在看發佈會的時候,個人腦海裏就浮現出一個問題:「這會是下一個互聯網公司競爭的流量入口嗎?」ios

先不拋結論,讓咱們先看一下 WWDC20 介紹了哪些關於 Widget 的新東西。算法

( WWDC 2020精彩內容思否專欄:https://segmentfault.com/blog...  swift

本篇內容來自於阿里巴巴淘系技術部,高級無線開發工程師柘劍。
更多精彩內容可關注【淘系技術】公衆號。)segmentfault

0x01 什麼是 Widget?

Widget 不是一個小型的 App,它是一種新的桌面內容展示形式,主要是用於彌補主應用程序沒法及時展現用戶所關心的數據。以下圖所示:緩存

image.png

一個優秀的 Widget 須要有三個特色:簡單明瞭(Glanceable)恰當展現(Relevant)個性化定製(Personalized)安全

簡單明瞭(Glanceable)

Widget 不是一個小型的 App,這句話被反覆提起。通常用戶天天進入主屏幕的次數超過 90 次,但停留的總時長不過幾分鐘。一般來講用戶只會在主屏幕上停留片刻時間,就會跳轉到其餘地方,因此並不須要任何複雜的交互設計來加強 Widget 的做用,也不須要複雜的樣式來豐富 Widget 的內容,簡單明瞭的內容纔是 Widget 的關鍵。網絡

和安卓的 Widget 不太同樣,蘋果設計的 Widget 並不支持任何交互行爲,也不建議你們設計過於複雜的樣式來呈現內容,這也很是符合蘋果對於主屏幕的改進一直保持克制的特色。架構

恰當展現(Relevant)

蘋果指望 Widget 能夠和正在執行或者考慮的事情緊密的結合。好比,早上起牀,用戶最關心天氣怎麼樣,Widget 能夠展現一下天氣狀況;起牀後,用戶就要了解一下一天的行程,Widget 能夠展現一下 Reminders 中的內容;等到一天忙完了,準備睡覺的時候,能夠用 Widget 打開音樂稍微放鬆一下。爲此,蘋果系統提供了一個叫智能疊放(Smart Stacks)的功能,智能疊放是一個 Widgets 的集合。系統會根據每一個人的習慣,藉助端智能的能力,自動的顯示準確的 Widget 在最頂部。app

image.png

固然,蘋果也考慮到了一些特殊的場景,好比 Widget Gallery 瀏覽時,提供了 Snapshot 的能力給到開發者能夠定製展現樣式,當加載內容的時候提供了 Placeholder UI API 而不是單調的 loading 加載框來避免過多的白屏的尷尬局面。這些設計的目的只有一個,蘋果指望 Widget 能夠在任何特定的場景均可以展現合理的樣式。

個性化定製(Personalized)

Widget 須要必定的定製能力,好比當我添加一個天氣 Widget,我只須要關心杭州的天氣怎麼樣。爲了實現這個能力,蘋果給 Widget 提供了 Configuration 的能力。顧名思義,就是可配置。一共有兩種配置類型:

image.png

  • StaticConfiguration,也就是用戶無需配置,展現的內容只和用戶信息有關係。
  • IntentConfiguration,支持用戶配置及用戶意圖的推測功能。

IntentConfiguration 的實現是基於 Intents.framework,開發過 SiriKit 和 Shortcuts 必定知道 Intents API 是用於瞭解用戶意圖的。其實就是一個智能的表單系統,開發者建立一個 SiriKit Intent Definition File 以後,只須要簡單的配置,Xcode 會自動幫你生成對應的代碼和類型。

image.png

當開發者編寫完配置以後,會藉助 Intents.framework 的能力,在運行的時候直接繪製出一個配置頁面(以下圖所示),開發者並不須要關心若是編寫這個頁面。

image.png

0x02 Widget 的刷新方式


Widget 的刷新方式是很特別的,至關的剋制。在展開講刷新方式以前,要講一個概念,叫 Timeline。顧名思義,就是時間線,下面的圖就是一條 Timeline。

image.png

當系統的 WidgetKit 調用 Reload Timeline API 以後,會要求 Widget Extension 的 Timeline Provider 提供一組 TimelineEntry 和 ReloadPolicy,用來後續刷新頁面。

這裏的概念比較多,咱們一個一個來解釋。

首先,Widget 的刷新徹底由 WidgetCenter 控制。開發者沒法經過任何 API 去主動刷新 Widget 的頁面,只能告知 WidgetCenter,Timeline 須要刷新了。

系統提供了兩種方式來驅動 Timeline 的 Reload。System Reloads 和 App-Driven Reloads。

System Reloads: 這個行爲由系統主動發起,會調用一次 Reload Timeline 向 Widget 請求下一階段刷新的數據。系統除了會按時發起 System Reloads 以外,還會藉助端智能的能力,動態決策每一個不一樣的 TimeLine 的 System Reloads 的頻次。例如被查看次數很大程度上直接決定了 System Reloads 的頻率。固然還有一些因爲設備環境變化觸發的行爲也會觸發 System Reloads,好比設備時間進行了變動。

App-Driven Reloads:指的是 App 請求 Widget 下一階段刷新的數據。這裏也要分兩種場景,應用在前臺運行和應用在後臺運行。當應用在前臺運行的時候,App 能夠直接請求 WidgetCenter 的 API 來觸發 Reload Timeline;而當應用處於後臺時,後臺推送(Background Notification)也能夠觸發 Reload Timeline。

image.png

注意,前面所提到的 Reload Timeline 並非直接刷新 Widget,而是 WidgetCenter 從新向 Widget 請求下一階段的數據。而 Timeline Provider 就是提供這個數據的對象。

而 Timeline Provider 提供的數據有兩部分,一部分是 TimelineEntry,另一部分是 ReloadPolicy。

TimelineEntry 是某個時間節點下 Widget 須要呈現的視圖信息和時間點。

而 ReloadPolicy 則是接下來這段時間 Timeline 的刷新策略,一共有三種:

  • atEnd: 是指 Timeline 執行到最後一個時間片的時候再刷新。
  • atAfter: 是指在某個時間之後有規律的刷新。
  • never:是指之後不須要刷新了。何時須要從新刷新須要 App 從新告知 Widget。

當 Timeline Provider 提供完下一階段的數據以後,就會中止運行。系統也會根據 entry 的信息,到點對 Widget 的展現內容進行刷新。值得一提的是,WidgetKit 會把 Timelines 所定義的 Entries 對應的 Views 結構信息緩存到磁盤,而後在刷新的時候才經過 JIT 的方式來渲染。這使得系統能夠在極低電量開銷下爲衆多 Widgets 處理 Timelines 信息。

簡而言之,蘋果對 Widget 的刷新至關的剋制。開發者沒法直接決定 Widget 刷新,只能提供刷新策略。具體的時間和節奏所有由系統來控制。蘋果這麼作,大機率是爲了提升主屏幕的性能和減小電量開銷上的考慮。

0x03 Widget 和 SwiftUI

Widget 只能用 SwiftUI 來進行開發,確切的說,Widget 的本質是一個隨着時間線而更新的 SwiftUI 視圖

image.png

當我最開始知道這個限制的時候,說實話是至關震驚的。衆所周知,SwiftUI 是一個去年才發佈的新技術,並且最開始的時候 SwiftUI 是至關不穩定的,以致於蘋果本身都是建議開發者暫時不要用到生產環境上,Widget 做爲系統主屏幕的功能,強制使用這麼新的技術,會不會太激進了?

顯然是不會。蘋果要求 Widget 只能使用 SwiftUI 主要是基於幾點考慮:

  1. SwiftUI 通過一年的發展,有了很大的提高,不只可使用 SwiftUI 來構建整個應用程序,並且在一些方面已經優於基於 UIKit 的開發方式了。具體的內容,你們能夠看一下 《詳解 WWDC 20 SwiftUI 的重大改變及核心優點》
  2. 蘋果正在佈局跨平臺,大統一的策略。Widget 做爲系統的核心功能,使用 SwiftUI 是惟一的選擇。SwiftUI 精美的 DSL 設計,使得開發者使用一套代碼在 iOS、iPadOS、macOS、watchOS 和 tvOS 等多個平臺展現不一樣的樣式能夠輕鬆的實現。(Widget 只會在 iOS、iPadOS 以及 macOS 上展現)
  3. 使用了 SwiftUI 使得 Dynamic Type 和 Dark Mode 等問題適配起來成本很低。
  4. 只有使用 SwiftUI 才能達到不少對於 Widget 的限制。假若可使用 UIKit 開發者可能有無數種辦法繞過蘋果的限制。好比開發沒法使用 UIViewRepresentable 來橋接 UIKit,只要使用任何 UIKit 的元素會直接 Crash。
  5. 將 Swift 語言和 SwiftUI 的重要程度提高了一大截。

0x04 Widget 的展現形式

一個 App 能夠對應多個 Widget Extension

你可使用 WidgetBundle 來進行組裝。蘋果並無對 Widget Extension 有數量上的限制。因此爲了不你們開發過多的 Widget Extension 致使搜索起來麻煩,在 Widget Gallery 中只能看到一個條目。

normal-video.gif

一個 Widget Extension 一共只有三種尺寸。

考慮到簡單明瞭的特色以及手機屏幕的空間有限的問題。蘋果只提供了三種樣式能夠選擇,systemSmall(2 * 2 icon 區域)、systemMedium(2*4 icon 區域)、systemLarge(4 * 4 icon 區域)

image.png

同一種 Widget 能夠被屢次添加到主屏幕中

並且對於每個 Widget 來講,都有其對應的獨立 TimeLine,相互獨立,互不干擾。

image.png

開發者沒法開發智能疊放(Smart Stacks)

開發者沒法開發一個 Widget 的集合。智能疊放(Smart Stacks)是一個系統特有的能力,對於開發者來講,惟一能夠作的就是主動提供相關性信息。前文提到了 Timeline 的數據又一組 TimelineEntry 組成,而每一個 TimelineEntry 除了包含時間點和視圖信息之外,還能夠包含一個 TimelineEntryRelevance 對象,用來表示這個 entry 的相關性。

不可交互,只可點擊

Widget 的 UI 是無狀態的,不支持滾動,也不支持像 Switch 同樣的互動元素。惟一開放的能力只有經過點擊和DeepLink 來喚起主 App。

蘋果提供了兩種 API 給到開發者,第一種是 SwiftUI widgetURL API),代碼以下所示:

image.png

而 widgetURL 的可點擊區域以下:

image.png

對於 systemSmall 類型來講,只支持 widgetURL 的方式,可是 systemMediumsystemLarge 還可使用 SwiftUI Link API,代碼以下所示:

image.png

而 Link 的可點擊區域以下:

image.png

同時,爲了性能和耗電量的考慮。Widget 不能展現視頻和動態圖像。因此期待經過動效吸引用戶眼球的方式能夠暫時息熄火了~

0x03 總結與展望

Widget 的出現,讓 iOS 系統的桌面有了破局,必定會有不少產品都期待藉助 Widget 來豐富本身產品的內容表達。

可是,Widget 設計的初衷是簡單明瞭的在恰當的時機展現一些帶有個性化定製的內容,爲了避免讓主屏幕的總體使用體驗變得複雜,Widget 從技術上就作的很剋制,限制了不少不少的能力。所以我認爲Widget 不會成爲下一個互聯網公司競爭的流量入口,它會成爲 App 提升用戶體驗的利器。

從技術角度看,SwiftUI Only 這種看似「激進」的策略其實也是一種信號,其實也是在告訴你們蘋果對於 Swift 以及 SwiftUI 的重視程度。

雖然,從目前來看 Pure SwiftUI 的設計,能夠作的事情真的不多,可是我也相信,蘋果會不斷優化 Pure SwiftUI 的能力。讓開發者能夠以最低的開發成本,適配更多的平臺。

最後,也期待你們能夠好好研究一下 Widget,結合本身的產品,給到用戶極致的用戶體驗。

( WWDC 2020精彩內容思否專欄:https://segmentfault.com/blog...  

本篇內容來自於阿里巴巴淘系技術部,高級無線開發工程師柘劍。
更多精彩內容可關注【淘系技術】公衆號。)

參考

iOS 14 Preview: https://www.apple.com.cn/ios/ios-14-preview/

Widgets code-along: https://developer.apple.com/news/?id=yv6so7ie

Meet WidgetKit: https://developer.apple.com/videos/play/wwdc2020/10028/

What's new in SwiftUI: https://developer.apple.com/videos/play/wwdc2020/10041/

Add configuration and intelligence to your widgets:https://developer.apple.com/videos/play/wwdc2020/10194/

Build SwiftUI views for widgets: https://developer.apple.com/videos/play/wwdc2020/10033/

Creating a Widget Extension: https://developer.apple.com/documentation/widgetkit/creating-a-widget-extension

Building Widgets Using WidgetKit and SwiftUI:https://developer.apple.com/documentation/widgetkit/building_widgets_using_widgetkit_and_swiftui

Making a Configurable Widget: https://developer.apple.com/documentation/widgetkit/making-a-configurable-widget

Keeping a Widget Up To Date: https://developer.apple.com/documentation/widgetkit/keeping-a-widget-up-to-date

團隊招人

負責手淘移動端的基礎PaaS及平臺技術。涉及移動網關、網絡加速、長連通道、圖片體驗等基礎技術,以及海量消息推送、浮層搭投全域觸達等平臺型技術,並對移動端系統進行前沿探索,打造了全站IPv六、iOS用戶態網絡棧、Android最小核、自適應線程調度等高性能技術和架構。

在這裏,你會面臨超級App在性能、體驗、安全等方面的極致追求;在這裏,你會站在業務和數據視角針對目標進行充分了解和深刻優化;在這裏,你會與業界各領域大牛並肩做戰、快速成長。

咱們期待有技術、有理想的你加入,與咱們共享積極、透明、開放的團隊氛圍,伴隨着各類乾貨滿滿的分享培訓以及業務和技術挑戰,咱們將一同在技術領域不斷攻堅、推陳出新,共同駛向屬於咱們的星辰大海。

職位:iOS 開發、Android 開發、C++開發、Java 服務端開發、前端開發、數據工程師、算法工程師

感興趣的同窗可將簡歷發送到:zhejian.wzj@alibaba-inc.com,獲取優先內推資格!

相關文章
相關標籤/搜索