WatchKit 開發注意事項

aahung發表於2015-07-02

從一月中旬開始,我就開始全職開發我新的 WhereNotes App 的 Apple Watch 部分。我非常幸運地被邀請到位於庫比提諾的 Apple Watch 實驗室。 在過去的三個半月裡,我收集了很多小貼士和技巧,這篇文章中會提到很多。我希望之中的有些東西能夠在 Apple Watch 開發上幫到你們。

  • 也許你熟悉 UIApplication 中諸如 applicationWillEnterForeground:applicationDidEnterBackground: 的方法(這兩個方法分別在對應的 UIApplicationWillEnterForegroundNotificationUIApplicationDidEnterBackgroundNotification 前被呼叫),那麼在 WatchKit 中鮮為人知的等效的 NSExtensionContext 通知是:

  • 我個人經驗和蘋果開發者論壇的帖子都表明:如果你的 Apple Watch 處於充電狀態,測試和 debug 會更容易進行,同時也更佳穩定。
  • 不像在 iOS 中你在任何時候都能更新使用者介面,在 Apple Watch 裡,只有屬於目前處於活動狀態或者可見的檢視控制器的元素才可以被更新。在 didDeactivate 被呼叫之前對介面的更新是安全的(didDeactivate 中不能更新介面),這意味著如果你想要更新一個目前處於隱藏狀態的檢視(比如被一個最上面的檢視擋住了),你需要在處於最上面的檢視被關閉的時候,也就是下面的檢視控制器的 willActivate 被呼叫的時候再更新介面。
  • 除了預置在 WatckKit 程式包中的素材,每一個 app 可以額外加入最多為 5MB 的圖片素材,這些素材可以通過 app 擴充套件中的 WKInterfaceDevice 的一些方法來生成和管理。從 app 擴充套件傳送圖片到 Apple Watch 耗費時間和電力,如果你打算重複使用一張圖片(哪怕是一次),你都值得去把它快取起來。如果你用 addCachedImage:name: 來傳送圖片,無論 PNG 是不是最好的選擇,由於以 PNG 傳送是最保險的,這張圖片會自動轉換為 PNG 編碼然後傳送到快取中。如果你的圖片可以用 JPG 編碼,我強烈推薦你使用 addCachedImageWithData:name:,同時把你的圖片用 JPG 編碼,並嘗試設定圖片質量。這不僅能夠讓圖片傳輸得更快,還能節省很多儲存空間,這樣你就能放下更多圖片。
  • 接著上一條建議,記住你可以用後臺程式來快取圖片的(蘋果的職員在開發者論壇這麼說的)。在我的 Watch app 中我用這個技巧在圖片需要之前就把它快取進去。
  • 如果你要用到上面提到的圖片快取,沒有什麼內建的方法可以幫你找出哪些是最老的圖片從而讓你刪除掉。如果你的 app 涉及到大量的圖片,你也許會考慮再封裝一層來管理圖片快取。
  • 要測試通知的話在 iPhone 上的 Apple Watch app 中先把通用設定中的手腕檢測關掉。
  • 長按側面的按鈕(譯者注:直到電源關閉介面出現鬆手),然後再長按一次,這樣就可以強制關閉你的 app (這樣並不會把你的擴充套件關掉)。
  • 減少 willActivate 中的處理量來節省載入時間。
  • 想想假如使用者先啟動 Watch 上的 app 再啟動 iPhone 上對應的 app 會發生什麼,設計的時候考慮到這點,否則就讓蘋果稽核人員來發現問題。
  • 記住你的 Watch app 是作為一個擴充套件來執行的,它的記憶體限制比 iPhone 大得多。如果你要處理大型的圖片,最好還是通過 openParentApplication:reply: 交給 iPhone 來處理。另外你要知道在模擬器中並沒有這些記憶體的限制,所以你必須在 Apple Watch 上真機測試。
  • 如果你想檢查你的 app 是不是和 Watch 配對了,在共享NSUserDefaults(用 shared app group) 裡設定一個 BOOL 值這樣在 iPhone 上也能夠訪問到這個值。
  • 在 iPhone 和 Watch 中同步資料,要麼通過 openParentApplication:reply: 來呼叫 iPhone,要麼用 Darwin 通知 功能來 Watch 和 iPhone 之間傳遞資訊。Darwin 通知功能不支援裝載資料,如果你想用這個通知來傳遞資料,去看看 MMWormhole 專案。
  • 當你使用計時器(包括在 willActivate 中)來更新使用者介面的時候,你要知道如果你的資料來源支援的話你也可以使用 KVO 來完成。我就是這麼做的。用這個方法介面元素只在被更改的時候才更新,剩下了不必要的通訊也延長了電池使用時間。
  • 如果你要追蹤檢視控制器的話,考慮一下在 awakeWithContext: 中把引用傳遞給self,從而建立聯絡。另外通過 JBInterfaceController 的子類 把這個方法沿用到了我自己的 app 中。這樣的技巧讓你讓你能夠像 UIViewController 一樣來設定 delegate(委託)。
  • 一個 WatchKit 的擴充套件被看成是前臺的擴充套件[參考],所以如果你需要訪問 地理位置的許可權 的話你只需要 請求『使用期間』許可權
  • 除非迫不得已,想想自己是不是真的必須要保持 iPhone 和 Watch 的實時更新同步。使用者通常不會同時使用兩個裝置,所以你可以當下次 iphone 或 watch 的 app 被啟用後重新整理資料,從而避免很多這樣的頻繁同步。然而不幸的是,看到兩個模擬器在一個螢幕上難免會誘導你去寫那些複雜的同步邏輯。嗯,也許我被誘導過,誰知道呢。
  • 當你不能用程式碼建立檢視控制器和控制元件的時候,你可以聰明地通過顯示和隱藏介面元素來達到目的。在 WatchKit 的開發中這樣做很常見,例如在一個頁面中,重要事情發生的時候一個標籤可以從隱藏變為不隱藏從而被顯示出來。或者,如果你有兩個佈局你想通過程式來選擇要哪個,你可以把它們放在根部的容器中,然後顯示或者隱藏他們。
  • 記住每一次觸控螢幕和更新內容都會涉及到 Watch 和 iPhone 之間的來回通訊。按照這一點來開發程式。由於 WatchKit 中的介面元素只能夠寫不能讀(因為只有 setter ),所以追蹤你給它設定的變數的值是很有用的,這樣可以避免重複設定。WatchKit 會試圖合併在這個執行週期中你設定的所有值,然後傳送最後一次的值的方法來幫助解決這個問題,但是你仍然可以通過追蹤那些變數來更好地實現這個。
  • 由於沒有內建的活動指示器空間,當耗時較長的一些任務(傳送圖片或者下載任務)在執行的過程中,你可以顯示一系列的動圖。任務完成後只用簡單地把動圖隱藏即可。2015年3月5日補充:我在 GitHub 上建立了 JBWatchActivityIndicator 專案,讓建立活動指示器動圖變得簡單。裡面也包括了一些渲染好的蘋果風格動圖。
  • 請確保你下載並閱讀了 Apple Watch 設計資料。除了一些有用的顏色以及大小推薦,裡面還有高質量的底座圖片(bezel images)素材(Apple Watch 底座),你可以用它加上截圖來做市場宣傳。回到這篇文章的主題,你提交的截圖是不能帶有底座背景的。很多開發者感到很失望,因為他們發現圖片在模擬器上顯示得好好的在真機上卻不這麼樣。事實上這也是為什麼很多 app 通過不了稽核的原因。這個問題和影像的命名和『鬆散』的圖片檔案有關。最保險的方法是把所有的圖片都放在 Watch App 的資源庫中(不是擴充套件的資源庫)。我就是這麼做的,我也推薦你這麼做。
  • 雖然普遍都這麼請求,但是沒有辦法在 Apple Watch 上來程式性啟動 iPhone 上的 app 使之執行在前臺(就算在模擬器中有些方法能這麼做)。考慮使用『連續互通(Handoff)』這個特性。
  • 如果你需要讓兩個檢視控制器互相傳遞資訊,而且你無法使用 awakeWithContext: 來完成它,試試傳送 NSNotifications 吧,這在擴充套件中能夠達到目的。或者你可以試試我的 JBInterfaceController 子類 配上delegate(委託)來完成。
  • 本地通知需要設定 soundName 屬性 來生成 Taptic 反饋和語音報時。
  • 模擬器是個好的開始,但是在真機上測試程式是非常重要的(相比開發 iPhone 和 iPad app 重要得多)。
  • Good luck with your Watch app!
  • 祝你開發 Watch app 好運。

相關文章