Upgrade to Pro — share decks privately, control downloads, hide ads and more …

初代 SwiftUI 就用來寫 Watch App 吧!

Ethan Huang
September 21, 2019

初代 SwiftUI 就用來寫 Watch App 吧!

許多人對 SwiftUI 抱持高度興趣,想找機會來使用與學習。但是實際玩過以後會發現它的成熟度還不足以取代 UIKit,作為開發 iOS app 的主要 UI 框架。開發者普遍的共識是,在 iOS 13 使用 SwiftUI 的風險很大,用在 side project 或小型專案還可以,但不適用於商業上的應用。

難道 SwiftUI 就無用武之地嗎?2019 年第一版它只能當玩具嗎?其實 Apple 規劃出一個很不錯的路線,讓 SwiftUI 可以用在商業應用上,只是很容易被開發者忽略——watchOS 6 才是 SwiftUI 在今年發揮作用的平台。

watchOS 6 在開發方面有幾個特色:
1. 因為 Swift ABI 穩定,app 體積小,安裝到實機開發節省相當多時間
2. 可以使用 SwiftUI,不再受限 WKInterface
3. 可以獨立打包上架,不一定要有 iOS app
4. WKExtendedRuntimeSession 增加了好幾個應用情境

過去 watch app 很少人開發,很大的原因就是上述幾點困難尚未被克服。既然開發者大多都沒有寫過、甚或移除了原有的 watch app,watchOS 6 + SwiftUI 或許就是很好的重新來一次的機會,也可以想出許多 side project 的題目。

Ethan Huang

September 21, 2019
Tweet

More Decks by Ethan Huang

Other Decks in Programming

Transcript

  1. 不會聽到什麼? • ⽤ WCSession 整合 iOS app • 多媒體 •

    串接網路或 iCloud • 怎麼靠寫 app 發⼤財
  2. 基本架構 • iOS App Target: 可割可棄 • Watch App Target

    放 Storyboard • WatchKit Extension Target 放 code • Complication 顯⽰在錶⾯ • Notification 適時的個⼈化通知
  3. App Store Connect • ⼀樣在 Developer Account 開新的 Bundle ID

    • ⼀樣在 App Store Connect 開新的 app,選 iOS • ⽤ Xcode 11 上傳 binary • 附上 watch app 截圖,但不⽤ iOS 的 • 其他都⼀樣,定價、Pre-release、⾃動發布...
  4. iOS App 不在了嗎? • 獨立 watch app 其實藏了⼀個不會顯⽰在 iPhone 桌⾯跟系

    統設定的 iOS app • iOS app 與 watchOS 仍然是同⼀個 bundle ID prefix、同⼀ 個 binary • 如果將來要加上 iOS app,在 App Store 上是就會是同⼀個 app
  5. TestFlight? • 發送流程、安裝流程,都跟 iOS TestFlight 完全⼀樣。因為 Apple Watch 上沒有 TestFlight

    app,所以你也只能⽤ iOS 來 安裝 • 獨立 watch app 的圖⽰會顯⽰ 圓形的版本。也會有⼩字標 「Apple Watch 上」
  6. 其他我個⼈想法 • 不要把 iOS app 搬到 watchOS,從頭開始想 • 畫⾯能夠不要捲動就不要捲動 •

    但可以⽤ Digital Crown 來精準改變數值 • ⽤ Paged Navigation,主畫⾯⼀⾴、設定畫⾯⼀⾴
  7. 想要快速啟動世界迷霧 • 走在路上突然想要記錄軌跡 • ⼿機版:
 拿出⼿機 ➡ 解鎖 ➡ 找到

    app ➡ 點開 等載入 點⼀下 開始記錄 ➡ 上鎖 ➡ 收起⼿機 • ⼿錶版:
 抬⼿ ➡ 點⼀下錶⾯進入 app ➡ 點⼀下開始記錄 放⼿
  8. 概念 • 點⼀下開始記錄、再點⼀下結束 • ⽤ CoreLocation 追蹤⼀系列座標 • 儲存在 CloudKit(watchOS

    沒有 iCloud Drive 與 iCloud Key-Value Store) • 輸出前,把經緯度與時間轉成 GPX(XML) 格式
  9. 番茄鐘⼯作法 • The Pomodoro Technique • 安排要作的事情 • 固定 25

    分鐘為專注的時間單位 • 設定倒數計時器,做事直到計時器響起 • 記錄完成事項,辨別內外在⼲擾因素 • 休息 5 分鐘後進⾏下⼀個...
  10. 限制 • Alarm 偶爾會失效 • AVSpeechSynthesizer 只能講話 30 秒。我還在找⽅法 •

    規定要 call 震動 API。⼀開始會震動,講話完就不震動了
  11. 新專案預設名稱是 OOO WatchKit App • 在 WatchKit App 的 Info.plist

    或 Targets General 把 Display Name 改掉 • 或是新增 InfoPlist.strings 再加上 CFBundleDisplayName 的 key value • 注意 target 是 WatchKit App ⽽不是 WatchKit Extension
  12. WKHostingViewController<View> 要怎麼加 environmentObject • 因為 Type 會不⼀樣 • ⽤ AnyView()

    包起來 • 但是據說⽤ type eraser 效能會差,盡量避免
  13. 怎麼做 Paged Navigation? • 左右滑動換⾴ • SwiftUI 沒有直接⽀援的⽅法 • 可以⽤

    WatchKit 本來的作法,也就是在 Storyboard 裡⾯ 拉 next page 的 segue • ⽤ HostingController 的 didAppear() 來判斷⽬前畫⾯
  14. 狀態機 • 以往我們會⽤ enum 來表⽰狀態,以狂鬧鐘為例,就是 「未設定鬧鐘」、「已設定鬧鐘」、「鈴響中」三種狀態 • SwiftUI 的 View

    採⽤的 function builder 還是半殘狀態,
 只⽀援 if,不⽀援 switch case • 所以就是各種 if else,⾃⼰⼩⼼
  15. Context Menu • SwiftUI Preview 不⽀援 • ⽤ Simulator 要注意

    Hardware ➡ Touch Pressure 是 Shallow or Deep
  16. 單元測試? • watchOS 根本沒有 test target 可以建立 • 就算開 watchOS

    framework 也是沒有 • 這個時候可以考慮開個 Swift Package • CI 什麼的可以順理成章不做(誤)
  17. Digital Crown API • 先幫 View 加上 .focusable(_:onFocusChange:) • 再加上

    
 .digitalCrownRotation(_:from:through:by:sensitivity:isConti nuous:isHapticFeedbackEnabled:)
  18. 怎麼更新 Complication • ClockKit API 有更新次數限制,每個 app 每⽇的呼叫上限是 50 次

    • Apple 希望你⼀次提供⼀系列針對不同時間的 complications,⽽ 不是每隔幾分鐘呼叫系統來更新⼀次 • watchOS 6 也可以⽤ PushKit • 使⽤ CLKRelativeDateTextProvider 來做計時或倒數 • 舊錶⾯在⽤的 RingText 不⽀援每秒的更新 • 新錶⾯在⽤的 GaugeProvider ⽀援每秒的更新
  19. 程式碼架構 • 我書讀得少,不懂架構 • 不過我幾乎都可以⽤⼀個 ObservableObject 作為 user data/state 的

    singleton 來解決 • SwiftUI 的部分,乖乖從 HostingController 丟 .environmentObject() 進去 • 其他地⽅則直接使⽤同⼀個 singleton(例如 ExtensionDelegate or ComplicationController)
  20. ⼀起來寫 Watch App? • iOS ⼯程師的盲點?Apple Watch 能做的事真的很少嗎?還 是我們想得太多 •

    Apple 平台還有很多,iOS ⼯程師可以嘗試把技能遷移過去 • 做這種很少資源可以查詢,要⾃⼰摸索的⼩題⽬⼩產品, 很有回到初⼼的感覺
  21. Reference • Creating a watchOS App with SwiftUI (sample code)

    • Creating Independent Watch Apps (WWDC19, 208) • SwiftUI on watchOS (WWDC19, 219) • Extended Runtime for watchOS Apps (WWDC19, 251) • Exploring Tinted Graphic Complications (WWDC19, 253) • Streaming Audio on watchOS 6 (WWDC19, 716) • Building Activity Classification Models in Create ML (WWDC19, 426)