原創(chuàng):知識點總結(jié)性文章
創(chuàng)作不易,請珍惜,之后會持續(xù)更新,不斷完善
個人比較喜歡做筆記和寫總結(jié),畢竟好記性不如爛筆頭哈哈,這些文章記錄了我的IOS成長歷程,希望能與大家一起進步
溫馨提示:由于簡書不支持目錄跳轉(zhuǎn),大家可通過command + F 輸入目錄標題后迅速尋找到你所需要的內(nèi)容
目錄
- 一、跨國應用本地化
- 1、商店描述
- 2、UI 界面
- 3、應用名稱
- 4、交給別人翻譯
- 二、跨平臺應用
- 1、創(chuàng)建跨平臺應用
- 2、Mac 應用版本間的差異
- 3、區(qū)分 iPhone 及 Mac 平臺
- 4、區(qū)分 iPadOS 及 iOS 平臺
- 5、Apple Watch 應用
- 6、Apple TV 應用
- 7、判斷 UI 在各平臺上的可用性
- 三、桌面小組件 Widgets
- 1、背景
- 2、系統(tǒng)級別的功能
- 3、制作桌面小組件的流程
- 4、代碼詳解
一、跨國應用本地化
應用本地化 Localization,主要指的是將現(xiàn)有應用,根據(jù)不同地區(qū)的語言習慣翻譯為不同語種。除此之外,它還意味著對當?shù)氐氖褂昧晳T進行針對性調(diào)整,比如閱讀語序等。SwiftUI 已經(jīng)自動處理好了諸如文本框中的使用方向,導航器的呼出方向等問題,因此獨立開發(fā)者主要需要做的本例化工作便是翻譯。
在設計一款目標發(fā)售地包含國際市場的應用時,你需要務必留意所有字符串的長度。中文作為一種用方塊文字表達意思的語言,其簡短的詞組便可以表達完整意思。而世界上很多語言是拉丁語系的,主要是用詞根和詞綴來對單詞進行修飾,甚至在不少語言中物品還存在男女的叫法,因此描述起來非常長。比如某個單詞在中文中只需要兩個字符的位置,在德語中可能需要十幾個字符位。
考慮到語言上的差異,在設計應用程序界面時應該留足空位,以便讓不同語言能完整顯示出來。對于界面元素,能用 SwiftUI 的就用,盡量避免直接從設計軟件中直接導入帶文字內(nèi)容的界面元素,這樣會給日后的本地化工作平添麻煩。
應用程序的核心邏輯常不受語言限制,將應用翻譯為不同語言,十分有助于擴展銷路。通常來說,歐洲、美國、中國這三大市場競爭較為激烈,想要讓應用獲得較好的排位相對困難。但競爭激烈的同時,這些市場的回報也最高,值得為其所在地的語言進行應用翻譯工作。
對于較為小眾的市場,諸如非洲或南亞各國,通常消費力更低一些。Apple 本身的產(chǎn)品滲透率在這些地區(qū)也稍差,這時候能做到多少,要做多少就得由你自己進行取舍了。但有一點是確定的,市場再小也是市場,且這些小眾市場往往競爭相對緩和,若你能對他們的語言進行針對性優(yōu)化,成功的可能性反而更大些。
本文將以支持「英文、中文」的應用為例,介紹應用本地化工作的方法。
1、商店描述
應用程序在 App Store 中的全部描述由 App Store Connect 網(wǎng)站負責。如下圖所示,當你希望添加不同語種的應用簡介、更新公告時,可以點擊下圖右側(cè)的語言按鈕。選中語言過后,點擊右側(cè)的「+」按鈕來新增應用描述所支持的語言。
部分人只會翻譯應用描述,卻忽略了預覽圖部分。若你在對主要的市場進行翻譯工作時,強烈建議一并更新預覽圖。假設不對預覽圖進行單獨修改,則 App Store 會默認使用默認語言,如英文的預覽圖在全球的商店顯示。
若你需要對預覽截圖進行本地化,可以長按應用程序圖標,并選擇「Edit Scheme」。在彈出的下列界面中,找到「App Language 應用語言」,將其修改為待截圖的目標語言即可。
在 App Store Connect 的語言列表中,你會看到某個語言帶有「Primary」標識,如下圖所示。在當前應用中,Primary 語言指的是在開發(fā)者沒有提供對應內(nèi)容的本地化翻譯時,任何素材、簡介、截圖等信息的默認顯示語言。
應用名稱、標題的翻譯在 App Store Connect 的「App Information 應用信息」分區(qū)中,如下圖所示。點擊右側(cè)的語言按鈕,可以在不同語言中切換。在上文中已添加中文,因此下圖中也已經(jīng)包含了中文選項。切換至不同語言后,將翻譯填入下圖表格中即可。
2、UI 界面
應用啟動后,顯示出的任何文字都可以說是 UI 界面的一部分,翻譯這一部分內(nèi)容至關重要。在 Xcode 中依次選中「項目名 - Project 標簽頁」,如下圖所示。下圖中包含一個 Localization 的選項,此處默認情況下只有一個叫做 English - Development Language 的選項,你可以把英文當作代碼層面的默認設置。想要添加新的語言支持,點擊「+」即可,本例中我選擇添加了簡體中文 Simplified Chinese。
Xcode 對 SwiftUI 中 UI 本地化流程有點像是查詢電話號碼本。該電話號碼本的文件類型為 Strings File。如下圖所示,新建一個 Strings File。
將該文件命名為 Localizable.strings,代表 UI 翻譯文件,之后點擊「Create」創(chuàng)建。
創(chuàng)建完成后,Xcode 會提供默認英文版的電話號碼本,如下圖所示。但我們還額外需要中文的電話號碼本,因此點擊下圖中右側(cè)的「Localize 本地化」按鈕。
點擊 Localize 后,在下圖右側(cè)彈出的本地化選項中勾選英文和中文兩種語言。勾選完成后,Xcode 會自動在左側(cè)創(chuàng)建兩個號碼本,一個是英文版,一個是中文版,如下圖所示。
在 SwiftUI 中,所有文本框中輸入的字符,都會被 Xcode 視作是在號碼本中查詢的鑰匙。比如下圖的簡單范例中,UI 是一個純文本視圖,顯示「Three Good Things」,此時 Three Good Things 便會被 Xcode 視作鑰匙拿去號碼本中查詢,如果號碼本中存在完全匹配的字符串,則直接用號碼本中的翻譯,如果沒有,則直接顯示 Three Good Things 這段未經(jīng)翻譯的文字。
想要讓 Xcode 知道這段話該如何翻譯,你需要依次進入剛才創(chuàng)建好的中文和英文電話號碼本,依次輸入 Three Good Things 的翻譯方式,如下圖所示,在中文的號碼本中 Three Good Things 會被翻譯為三件好事,英文的號碼本中會被翻譯為 Three Good Things 保持不變。值得注意的是,以中文翻譯「"Three Good Things" = "三件好事";」為例,等號左側(cè)的鑰匙必須要與 SwiftUI 中輸入的字符串完全匹配,等號右側(cè)的則是對應的本地化翻譯,結(jié)束時必須用到英文分號「;」。
翻譯完成后,分別運行中文版和英文版的虛擬機,UI 效果如下。至此應用的 UI 界面完成本地化翻譯。
3、應用名稱
應用名稱的翻譯與界面翻譯非常類似,不過需要創(chuàng)建一個專門用于查詢應用顯示名稱的號碼本。如下圖所示,新建一個 Strings File。
將該文件命名為「InfoPlist.strings」并創(chuàng)建文件。
與上文類似,點擊 Localize 按鈕將 Info.Plist 文件分別創(chuàng)建為兩種語言的號碼本。
打開對應的語言文件并進行翻譯,比如「"CFBundleDisplayName" = "三件好事";」會將該應用的中文顯示名稱改為「三件好事」。本例中,CFBundleDisplayName 指的是 Xcode 用于自動識別應用名稱的鑰匙。
若你使用上述虛擬機切換語言的方法,會發(fā)現(xiàn)應用的顯示名本地化沒有正確顯示。這是因為在 iOS 設備時,所有應用名稱不跟隨應用自身設置,而是全部跟隨系統(tǒng)顯示,因此想要查看翻譯是否成功,需要在虛擬機的設置中,切換系統(tǒng)語言,如下圖中間的截圖所示,之后本地化應用名稱即可正常顯示。
4、交給別人翻譯
對于機器翻譯來說,我個人比較推薦 DeepL,它的翻譯在水準之上,且支持語言較多。筆者之前寫過一篇 介紹 DeepL 用法及效果的文章,不再贅述。但還有些情況,你可能會拜托朋友第三方翻譯幫你進行本地化工作,這時便需要把文件交給別人,這時便需要分享源文件。打開 Xcode,并右鍵選擇「Show in Finder」。
在打開的 Xcode 項目中,你會看到尾綴是 .lproj 的本地化翻譯文件。比如 en 指的就是英文翻譯,zh-Hans 指的是中文翻譯。假設你希望請別人翻譯英文版,只需要把 en.lproj 文件夾分享給他人即可,不需要分享整個 Xcode 項目文件。
以中文為例,本地化文件夾中包含 InfoPlist.strings 應用名稱文件,以及 Localizable.strings 應用 UI 文件。若對方的機器是 Windows,或沒有 Xcode 的 Mac,你可以請對方用任意的文本編輯器打開進行翻譯。以 Mac 為例,右鍵打開該文件,選擇用自帶的文本編輯器「TextEdit」打開即可。
打開后的文件如下圖所示,修改好翻譯之后保存。當開發(fā)者拿到翻譯完的文件夾后,直接粘貼到 Xcode 項目中覆蓋舊的翻譯文件夾即可。
二、跨平臺應用
隨著 Mac 產(chǎn)品線逐漸過渡到 M 系列芯片,SwiftUI 轉(zhuǎn)變成為 Apple 生態(tài)系統(tǒng)中全部平臺的主要 UI 語言,跨平臺應用開發(fā)變得前所未有地簡單。對于開發(fā)者來說,使用 SwiftUI 的標準控件,可以讓你無需操心如何定制適用于各個平臺的 UI,只需要用一套寫法,在每個系統(tǒng)平臺中都會自動適配相應的 UI 外觀。
1、創(chuàng)建跨平臺應用
若你只需要某個平臺的應用,可以直接選擇對應的「iOS」或「macOS」應用模版進行創(chuàng)建。若你想創(chuàng)建跨 iPad、iOS、macOS 三平臺應用,只需要在 Xcode 創(chuàng)建應用的模版中選擇「Multiplatform - App」即可,如下圖所示。
跨三平臺的應用默認使用 SwiftUI 作為 UI 界面語言,使用 SwiftUI Lifecycle 用作生命周期控制,無任何使用其它選擇,如下圖所示。
2、Mac 應用版本間的差異
未來數(shù)年中,會出現(xiàn)英特爾芯片與 M 系列 Mac 機型并存的狀態(tài),因此 Mac 版本和運作方式稍顯復雜。創(chuàng)建完跨平臺應用后,你會注意到應用運行窗口有兩個選項,其中之一備注為 iOS,其二備注為 macOS。
這里有個選項你也許會覺得奇怪,在 iOS 大類中,居然出現(xiàn)了 My Mac (Designed for iPad) 選項。這個選項指的是該應用仍然為 iOS 應用,若開發(fā)者不進行額外說明,默認支持所有搭載 M 芯片的 Mac 電腦運行。本質(zhì)上來說,以該模式運行的應用仍然為原版的 iOS 應用。在此模式下,所有 UI 顯示方式和操作手勢等完全與 iOS 版本相同。
在 macOS 應用的選項中,出現(xiàn)了兩個 Mac 對應類型,分別是 My Mac 和 My Mac (Rosetta),均指的是以 Mac 版本的 UI 進行顯示。若你正在使用的 Mac 開發(fā)機器搭載 M1 芯片,則 My Mac 指的是讓應用以 x86 原生模式運行;若你正在使用的 Mac 開發(fā)機器搭載 M1 芯片,則 My Mac 指的是讓應用以 ARM 原生模式運行。在 M1 版本的機器上,還會額外出現(xiàn) Rosetta 的選項,指的是應用以 x86 形式編譯,通過兼容層在 M 芯片的機器上運行。
若你在應用中用到了較老的 UIKit 作為視圖框架,還可能在運行欄中看到 My Mac (Catalyst),指的是將 UIKit 應用以 MacCatalyst 翻譯后,運行在 Mac 機型中。請注意,以上所有的選項,均取決于你的開發(fā)機器,可能和本文截圖有所差異??偟膩碚f,現(xiàn)階段下 Mac 應用運行共有 6 種方式,分別是:
- Mac (Designed for iPad):純 iOS 應用,僅支持 M 芯片版 Mac
- Mac (Intel):純 macOS 應用,僅支持 Intel 芯片版 Mac
- Mac (ARM):純 macOS 應用,僅支持 M 芯片版 Mac
- Mac (Rosetta):純 macOS 應用,支持 M 及 Intel 芯片版 Mac
- Mac (Catalyst):較老的寫法。純 Mac 版 UIKit 應用,支持 M 及 Intel 芯片版 Mac
- Mac (Appkit):較老的寫法。純 Appkit 應用,支持 M 及 Intel 芯片版 Mac
3、區(qū)分 iPhone 及 Mac 平臺
你也許會問,同樣的代碼,假設我需要創(chuàng)建出兩種不同的視圖排版怎么辦。遇到特別復雜的界面差異,你可以考慮新建一個 SwiftUI 視圖,來單獨處理某個平臺的顯示。若你只需要進行一些細微變動,則可以使用語法 #if os(xxx) #endif 來進行針對性判斷。如下圖所示,如果軟件運行在 iOS 設備上,則顯示 iOS 文字,反之則顯示 macOS 文字。
將包含上述代碼所示的應用運行后,結(jié)果如下??梢钥吹?,雖然是同一個 SwiftUI 視圖,內(nèi)容根據(jù)平臺進行了差異化顯示。
4、區(qū)分 iPadOS 及 iOS 平臺
Apple 當下的生態(tài)系統(tǒng)命名有些不規(guī)范,雖然 iPad 上設備名義上運行的是 iPadOS 操作系統(tǒng),但是在 Xcode 體系中,仍然被歸類為 iOS。因此上述判斷方案無法得知應用是運行在 iPhone 還是 iPad 上。此時可以用到另一種判斷方法,如果 UIDevice.current.userInterfaceIdiom == .pad 為真,則運行在 iPad 上,反之運行在 iPhone 上,如下圖所示。
運行上述代碼后,效果如下圖所示??梢钥吹?iOS 和 iPadOS 的代碼被區(qū)分看待。
5、Apple Watch 應用
若你希望給應用增加 Apple Watch 的手表支持,可以在 Xcode 頂部菜單欄中,選擇「File - New Target」,如下圖所示。
在 watchOS 菜單中,可以看到「Watch App for iOS App」和「Watch App」兩個選項。這二者的區(qū)分度需要額外留意,其中 for iOS App 指的是該手表應用必須依賴于 iOS 應用主體發(fā)布,無法單獨在 Watch 應用商店中下載。無論該手表應用是否存在與 iOS 應用的數(shù)據(jù)互通,這種依賴關系是必須存在的。而 Watch App 指的是可以單獨發(fā)布,無需依賴任何 iOS 應用,可直接在 Watch 應用商店中下載的應用。這二者根據(jù)你的實際需求選擇即可。
選擇完成后,如下圖所示,將 Watch 應用添加至 Xcode 項目中。
添加完成后,若你選擇的是 Watch App for iOS App 選項,則會看到下圖左側(cè)多出來了 WatchApp Extension 選項。該文件夾中的內(nèi)容,是 Xcode 已經(jīng)為 Watch 應用創(chuàng)建好的模版。以我們熟悉的 ContentView.swift 為例,可以看到如下圖所示的 SwiftUI 視圖代碼。
額外說明一下,你也許會感到疑惑,Xcode 如何知道項目中相同文件名的文件到底該運行哪一份,答案是 Target Membership 運行目標。如下圖右側(cè)所示,假設代碼的核心邏輯下載在 Logic.swift 文件中,倘若在右側(cè)面板勾選 WatchApp Extension,則代表這份文件可以在 Watch 應用中使用,其它所有文件同理,都具備運行目標這個選項。
結(jié)束界面和邏輯的編程后,點擊運行欄中的 WatchApp,并在模擬器中選擇一臺虛擬機即可運行。額外說明的是,若你希望用到真機測試,則需要在 Xcode 中的「Window - Devices and Simulators」中,對手表進行與手機的配對。之后就可以直接在真機手表上進行測試了。
將 Watch 虛擬機一并運行,當前版本的跨平臺應用已支持 iPad、iPhone、Apple Watch、Mac 這四個平臺。
6、Apple TV 應用
在海外市場中,Apple TV 應用也占據(jù)一席之地。你可以將 TV 應用理解為家庭機頂盒,或運行在智能電視中的應用,只不過在 Apple 平臺的硬件載體是 Apple TV。重復上述 Apple Watch 應用的添加方法,這次選擇 TV App 即可創(chuàng)建 Apple TV 應用。創(chuàng)建完成后,點擊 Apple TV 模擬機即可運行,如下圖所示。
至此,在同一個 Xcode 項目中添加各平臺的代碼介紹完畢,如下圖所示。Mac、Apple TV、Apple Watch、iPhone、iPad 應用均通過 SwiftUI 界面語言串聯(lián)在一起。
7、判斷 UI 在各平臺上的可用性
在開發(fā)過程中,你也許會碰到另一個問題,我的 SwiftUI 代碼到底哪些可以用。這個問題的答案寫在 Apple 開發(fā)者文檔中,如下圖右側(cè)所示,在調(diào)用框架時,你需要注意該框架中內(nèi)容的可用性。比如 Toggle 開關的寫法,支持全平臺使用。如下圖所示,將一個最簡單的開關代碼放置在跨平臺文件夾中。
@State private var toggleOn = true
Toggle("Do Something", isOn: $toggleOn).padding()
對于視圖有差異的 Apple TV,同理將開關代碼復制進去,但刪除 iOS 的判斷語句。
準備完成后運行,可以看到如下圖所示的界面。在 Mac、iPhone、Apple Watch、Apple TV 中,同樣的 SwiftUI 開關寫法,實際上顯示方式完全不一樣。在 Mac 中是我們熟悉的勾選框,而在 TV 中則是點入式菜單。這也是 SwiftUI 強大的地方,并非追求統(tǒng)一,而是在代碼統(tǒng)一的前提下,保證各個平臺體驗的獨立性。
對于很多應用來說,諸如用到 Apple Pencil 的 Procreate,也許純 iPad 應用就已經(jīng)是最佳選擇;對于筆記應用如 Bear,用戶確實有跨平臺記錄的需求;對于一款快速查看潮汐的應用,也許純 Apple Watch 應用已經(jīng)是最佳選擇,畢竟在進行這類運動時用戶手機大概不在身邊。
三、桌面小組件 Widgets
桌面小組件 Widget 是 iOS 14、macOS Big Sur 之后,Apple 推出的顯示在桌面上的便捷視圖?,F(xiàn)階段,桌面小組件可以被用在 iPhone、iPad、Mac 這三類設備中。Apple 生態(tài)系統(tǒng)中的小組件以展示信息為核心訴求,僅提供非常輕量的互動。若你習慣了 Android 手機上的部分復雜強大的桌面組件,應該適當降低預期,Apple 版本的桌面小組件與其還是有較大差異的。
1、背景
以 iPhone 為例,小組件主要集中在設備的負一屏,亦可被添加在桌面的任意位置。當用戶長按桌面背景,并點擊左上角的加號后,可以看到如下圖所示的小組件選擇器。小組件選擇器羅列了當前設備中所有支持的小組件的應用,并提供了小組件預覽,用戶點擊后即可拖拽添加至桌面。
小組件分為三種尺寸,分別是占據(jù) 4 個應用圖標格的小尺寸、8 個應用圖標格的中尺寸、16 個應用圖標格的大尺寸。值得注意的是:對于小尺寸的桌面小組件來說,除自身顯示的信息外,其本質(zhì)上就僅僅是一個按鈕。開發(fā)者無法自定義任何小組件中的互動模塊,除展示信息外其功能只有一個,就是點擊后跳轉(zhuǎn)到哪里去。而中號或者大號應用小組件,則支持稍多一些的互動選項,允許開發(fā)者提供多個按鈕。
2、系統(tǒng)級別的功能
WidgetKit 是純 SwiftUI 視圖的框架。得益于 SwiftUI 及諸多系統(tǒng)內(nèi)置的功能,在開發(fā)者什么都不做的前提下,小組件自身已經(jīng)具備了幾項常用功能。本小節(jié)用「自動暗色模式」和「小組件推薦輪轉(zhuǎn)」舉例。
如下圖所示,當設備從淺色模式切換至深色模式時,界面中的黃色做出了輕微的版本調(diào)整。所有字體的和背景的顏色也進行了反轉(zhuǎn),比如 Steve's Surprise Party 從黑色切換到了白色。對于這些設置,只要你的視圖代碼中用到了類似 .color(.primary) 這樣的標準寫法,或用到了系統(tǒng)提供的標準色,以上特性都是自動白送的。
如下圖所示,用戶可以將多個小組件疊加在一起,成為一個堆疊 Stack。 對于堆疊在一起的小組件來說,系統(tǒng)會使用基于 On-Device Intelligence 本地智能的機器學習 + 推薦算法,來決定在某個時刻,哪一個小組件會在屏幕的最上方。其數(shù)據(jù)來源主要是小組件的 Donation 捐贈,舉個例子,倘若在廈門的用戶在早上 8:30 分的時候查看了天氣,那么天氣應用很可能捐贈了一個「8:30 查看廈門天氣」的事件。當捐贈形成規(guī)律后,系統(tǒng)會將這些捐贈當作一個新知識,下次 8:30 分時自動將天氣小組件前置。
3、制作桌面小組件的流程
在 Xcode 中新增小組件的流程與新增 watchOS 應用的流程非常相似,都需要新增一個 Target。如下圖所示,在頂部的菜單欄中選擇「File - New -Target」。
在彈出的選項中,選擇「iOS」。接著在「Application Extension」中找到「Widget Extension」并點擊下一步。
此處彈出的是小組件在開發(fā)期間的名稱,根據(jù)你的喜好起名即可,不得與項目名重復。本例中,使用 WidgetTarget 作為名稱,如下圖所示。
完成以上步驟后,Xcode 會新建幾份模版文件,其中之前沒見過的文件類型是:WidgetTarget.swift 和 WidgetTarget.intentdefinitions。在什么內(nèi)容都不添加的情況下,該模版文件已經(jīng)準備好了一個時鐘應用,直接運行后如下圖所示,顯示當前時間。本文會專注講解這個時鐘應用模版中各類代碼的用途。
在上圖中,你也許注意到了系統(tǒng)的實際時間是 6:59,而小組件顯示時間是 6:56,這是因為小組件的更新不是即時的,而是由系統(tǒng)根據(jù)開發(fā)者提供的時間軸來盡量安排。
4、代碼詳解
上述流程走完后,Xcode 模版會自動生成的 WidgetTarget.swift 文件,如下圖所示。
此處的 WidgetTarget.swift 文件名,與之前創(chuàng)建 Widget 時空格中填寫的命名一致。因每個人的命名可能不同,你的文件可能不叫 WidgetTarget,但內(nèi)容是一致的,不必擔心。本例中,我將以 WidgetTarget 這個命名為例子。
WidgetTarget.swift 文件中包含五個重要的結(jié)構(gòu)體 struct,分別是:Provider、SimpleEntry、WidgetTargetEntryView、WidgetTarget、WidgetTarget_Previews。這些概念相對較新,大多是 2020 年之后 Apple 發(fā)布的 WidgetKit 中提到的全新概念,因此我會在下文亂序進行逐一解析。
如下圖所示,WidgetTargetEntryView 結(jié)構(gòu)對應的是標準的 SwiftUI 視圖。其中與視圖有關的代碼寫在 var body: some View { } 中。如下圖所示,Text(entry.date, style: .time) 指的是用 date 這個時間戳用于數(shù)據(jù)來源,并將其以 time 時鐘的方式顯示出來,是一個 Text 純文本視圖。
你也許會好奇,傳遞數(shù)據(jù)的信息是從哪里來的,答案是 SimpleEntry 這個結(jié)構(gòu)體。如下圖所示,SimpleEntry 繼承了一個名為 TimelineEntry 的協(xié)議。對于小組件來說,存在一個重要的時間軸 Timeline 的概念 ,對于組件的任何一個時刻,系統(tǒng)需要知道組件想顯示什么內(nèi)容,并根據(jù)組件的時間軸進行排期。比如一個日歷應用,很可能每天在三個時間點各更新一次,每次對應的時間的信息都不同,每一個時間點的信息片段,都存在 SimpleEntry 中。
如下圖所示,WidgetTarget 和 WidgetTarget_Previews 這兩個結(jié)構(gòu)體負責視圖的顯示和 Xcode 窗口預覽。其中 WidgetTarget_Previews 就不多說了,只是單純地提供該小組件的 Canvas 預覽窗口,與實際允許在設備中的代碼無關。.previewContext(WidgetPreviewContext(family: .systemSmall)) 是個新的修改器,指的是用小尺寸的小組件來預覽。
上圖中 @main 指的是小組件應用的接入點。其中 WidgetTargetEntryView(entry: entry) 負責把上文中定義的 SwiftUI 視圖 WidgetTargetEntryView 代入最新數(shù)據(jù)并顯示。值得額外介紹的是兩個新的修改器,此處 .configurationDisplayName("My Widget") 指的是小組件選擇界面的組件名稱,.description("This is an example widget.") 指的是小組件描述,對應內(nèi)容如下圖所示。
最后值得一提的新內(nèi)容便是 Provider 這個結(jié)構(gòu)體,如下圖所示,繼承了 IntentTimelineProvider。顧名思義,Provider 是一個提供者,負責由小組件向操作系統(tǒng)提供信息。這個協(xié)議來要求開發(fā)者提供三個必備函數(shù),分別是 placeholder、getSnapshot 和 getTimeline。
getPlaceholder 的用途是在沒有網(wǎng)絡連接,或數(shù)據(jù)還沒能及時加載的情況下,小組件接收到的默認的信息。這一部分信息可以由開發(fā)者直接提供,以淘寶為例,貨物信息默認可以是「精選商品」,運輸信息可以是「已經(jīng)在路上」。
getSnapshot 則是在諸如小組件選擇界面,屏幕上真實展示的小組件中,顯示的具備真實信息的內(nèi)容。舉個例子,假設現(xiàn)在是 10:00 分,則 getSnapshot 返回的便是具備 10:00 這個信息的小組件狀態(tài)。
getTimeline 指的是操作系統(tǒng)向小組件索要的時間軸。系統(tǒng)需要知道桌面顯示出來的每個組件,需要在什么時候進行數(shù)據(jù)更新。比如你的小組件顯示的內(nèi)容只是每日精選書摘,那么時間軸中的內(nèi)容便是「每日更新一次」這個時間。系統(tǒng)會根據(jù)這個頻率來對組件內(nèi)容進行更新。
請注意,在時間軸函數(shù)中,開發(fā)者給出的時間軸只是告訴系統(tǒng)我希望你按照這個標準刷新小組件。但系統(tǒng)并不保證執(zhí)行,因此這只是君子協(xié)議,實際刷新時間由系統(tǒng)根據(jù)當前電量、顯示在最上層的組件等信息決定。
上圖中的文件 WidgetTarget.intentdefinition,作用是為小組件提供更復雜的自定義功能。這一部分內(nèi)容對于新人有些超綱了,因為它涉及了一些關于 SiriKit的知識,本教程不做額外擴展講解。
以上知識可以帶你入門,卻不足以憑此構(gòu)建一個復雜的小組件應用。若你對創(chuàng)建復雜桌面小組件感興趣,強烈推薦以下 WWDC 開發(fā)者大會視頻。
桌面小組件算是過去數(shù)年中,能帶來明顯用戶感知的新系統(tǒng)特性。其核心目的在于展示信息,并非提供深層次互動。你可以圍繞該目的,去思考應用中哪些信息適合以小組件的形式呈現(xiàn)出來。與此同時,若你的應用的確需要的是復雜的互動,直接考慮完整應用會更合適一些,切忌把復雜邏輯交給注重「輕量」的小組件。
Demo
Demo在我的Github上,歡迎下載。
SwiftUIDemo
從零開始實操完整的小組件項目
- 10034: Widgets Code-Along, Part 1: The Adventure Begins
- 10035: Widgets Code-Along, Part 2: Alternate Timelines
- 10036: Widgets Code-Along, Part 3: Advancing Timelines