原文:watchOS 2 Tutorial Part 1: Getting Started
這一年的 WWDC 大會上,蘋果公司推出了 watchOS 2,這標志著 Apple Watch 的開發(fā)產(chǎn)生了巨大的變化。現(xiàn)在,你可以開發(fā)能運行在你手表上原生的 app 了。
在這篇 watchOS 2 教程中,你會開發(fā)一個簡單但是功能齊全的 watchOS 2 的 app。
在這個過程中,你會學到:
- 如何為 iOS app 添加 watchOS 2 的 target
- 如何在兩個 target 之間共享數(shù)據(jù)
- 如何添加一個 watchOS 2 界面控制器到 storyboard,并放置界面對象
- 如何創(chuàng)建 WKInterfaceController 的子類并連線
正式開始吧
首先下載教程的起始項目吧。
在Xcode中打開它然后編譯運行。你應該會看到一個空白界面:

這個項目沒有太多的文件,只包含一些你需要的最基本的文件。
添加 WatchKit App
選擇 File\New\Target… ,在出現(xiàn)的對話框中選擇 watchOS\Application\WatchKit App 然后點擊 Next:

在接下來的界面中,設置項目名字為 Watch,確保語言設置為 Swift,然后取消選中任何復選框。點擊 Finish:

之后會詢問你是否想要激活 watch scheme,你需要這么做,所以確保選擇了激活:

祝賀,你剛剛創(chuàng)建了你的第一個手表 app!這真的很容易。
你會注意到,這個操作實際上創(chuàng)建了兩個 target,而不是一個,在項目導航中看到兩個對應的組。這是因為手表 app的代碼實際是作為一個擴展形式存在的,類似 iOS 上的 Today extensions。
當你在項目導航中點開 Watch 和 Watch Extensions 組的時候,你會看到所有 storyboard 放在 Watch 組,當前 target 創(chuàng)建的所有的類文件放在 Watch Extensions 組中:

你需要遵循如下的原則:任何你添加的代碼必須放在 Watch Extension 組中然后添加到 Watch Extension target,而所有的 assets 或者 storyboards 需要放在 Watch 組里。
小家務
在繼續(xù)前,你需要刪掉一些 target 模板添加的你不需要的文件。
在項目導航中右鍵點擊 InterfaceController.swift 然后選擇刪除。
當彈出提示,選擇 Move to Trash 來確保文件確實從項目中刪掉了:

下一步,打開 Interface.storyboard,選擇其中僅有的界面控制器,按下 backspace 鍵來刪除它。現(xiàn)在就剩下一個空 storyboard,或者是我認為的,一個空白畫布。
共享數(shù)據(jù)和代碼
起始項目包含一個記錄所有 Aber 航空公司航班信息的 JSON 文件,一個模型類表示飛行數(shù)據(jù)。這正是應該共享的數(shù)據(jù),因為 iOS app 和手表 app 使用相同的模型類和數(shù)據(jù)-你記得 DRY (不要寫重復的代碼)原則嗎?
在項目導航中點開 Shared 組然后選擇 Flights.json。之后,在 File Inspector 中找到 Target Membership 區(qū)域,選中 Watch Extension:

文件現(xiàn)在應該被 AirAber 和 Watch Extensions 這兩個 target 所包含。
為其他 Shared 組的文件重復這個步驟,比如說 Flight.swift。
這些都做完后,你可以開始開發(fā)航班詳情界面了!
構造界面
打開 Watch\Interface.storyboard,從對象庫拖一個界面控制器到 storyboard 里面.選中這個界面控制器,打開屬性檢查器設置它的 Identificer 為 Flight,然后勾選 Is Initial Controller:

你設置的這個 Identifier 讓你可以在代碼中引用這個界面控制器。選中 Is Initial Controller 簡單告訴 WatchKit 你希望當應用程序啟動的時候首先顯示這個界面。
下一步,從對象庫中拖動一個組到界面控制器:

之后這個組會包含 Aber 公司的 logo,航班號和路線。
選中這個組,在屬性檢查器的頂部改變它的 Insets 為 Custom。這會顯示四個額外的文本框讓你可以手動的設置組的上下左右。設置 Top 為6:

這僅僅讓你的組到頂部有個額外的空隙。
下一步,拖動 Image 到組中。組會相應的收縮來改變 Top inset (感謝 Xcode!),之后在文檔大綱中檢查來確保 Image 是組的子節(jié)點,而不是同級:

現(xiàn)在需要顯示一張圖片,下載 logo 圖片 然后把它拖動到 Watch\Assets.xcassets 中。這會創(chuàng)建一個新的 logo 圖片,存放在2x的部分。

為了給圖片染色,選中這張圖片,在屬性檢查器中修改 Render As 為 Template Image。
重新打開 Watch\Interface.storyboard 選中之前的 image.使用屬性檢查器,做如下的改變:
- 設置圖片為 Logo - 當下拉列表沒有出現(xiàn),你可以自己輸入;
- 設置 Tint 為 #FA114F(也可以在顏色面板中輸入值);
- 設置 Width 為 Fixed,值為40;
- 設置 Height 為 Fixed,值為40。
屬性檢查器現(xiàn)在應該像下面這樣:

不要擔心看不到 logo,因為 Xcode 設計時無法給模板圖片染色!
下一步,往已經(jīng)存在的組中拖動另外一個組,確保它出現(xiàn)在 image 的右側,使用屬性檢查器設置 Layout 屬性為 Vertical.同樣修改 Spacing 為0、Width 為 Size to Fit Content。然后拖動兩個 label 到新的組中,放置一個到另一個的下面。

選擇上面的 label,使用屬性檢查器,設置文本為 Flight 123,文字顏色為 #FA114F。
選擇下面的 label,設置文本為 MAM to SFO。界面控制器最后看起來像下面這樣:

這些文本僅僅充當占位符,之后會被控制器中設置的文本取代。
下一步,拖動另一個組到界面控制器中,但是這次確保與第一個組同級。當不能設置組級別關系請使用文檔大綱(Document Outline)。

選中新的組,設置它的 Layout為 Vertical、Spacing 為0。
現(xiàn)在,拖動三個 label 到新的組中:

確保 label 都在 group 中,而不是與 group 同級!
選擇頂部的 label 使用屬性檢查器修改它的文本為 AA123 Boards。
選中中間的 label,修改文本顏色為 #FA114F,字體選擇 System,Regulaer 樣式和54.0的 size.最后,修改 Height 為 Fixed,值是44。
選中底部的 label 修改文本為 On time,文本顏色為 #04DE71。
你的界面控制器應該現(xiàn)在像下面這樣:

從對象庫中拖動一個新的組到下面的組,這次確保它是在子節(jié)點而不是在同級,之后向其中添加兩個 label,你完全的界面對象關系應該像這樣:

使用屬性檢查器,設置左邊的 label 文本為 Gate 1A。右邊的 label 設置為 Seat 64A,之后設置它的 Horizontal alignment 為 Right
完全的界面應該像如下這樣:

恭喜,你已經(jīng)完成你的第一個 watch app 界面的布局了,現(xiàn)在是時候給它填充一些真實的數(shù)據(jù)然后在模擬器上運行。
創(chuàng)建控制器
在項目導航中右擊 Watch Extensions 組,選擇 New File,在出現(xiàn)的對話框中選擇 watchOS\Source\WatchKit Class 然后點擊 Next。命名新的類為 FlightInterfaceController ,確保它為 WKInterfaceController 的子類,語言設置為 Swift:

點擊 Next,之后是 Create
可以看到新的文件在代碼編輯器中打開了,刪除其中的三個空方法,只剩下 import 語句和類定義。
添加這些 outlets 到 FlightInterfaceController 的頂部:
@IBOutlet var flightLabel: WKInterfaceLabel!
@IBOutlet var routeLabel: WKInterfaceLabel!
@IBOutlet var boardingLabel: WKInterfaceLabel!
@IBOutlet var boardTimeLabel: WKInterfaceLabel!
@IBOutlet var statusLabel: WKInterfaceLabel!
@IBOutlet var gateLabel: WKInterfaceLabel!
@IBOutlet var seatLabel: WKInterfaceLabel!
這里僅僅為之前的每個 label 添加一個 Outlet。稍后會把他們連接起來。
下一步,在 outlets 下面添加 flight 屬性和對應的屬性觀察器:
// 1
var flight: Flight? {
// 2
didSet {
// 3
if let flight = flight {
// 4
flightLabel.setText("Flight \(flight.shortNumber)")
routeLabel.setText(flight.route)
boardingLabel.setText("\(flight.number) Boards")
boardTimeLabel.setText(flight.boardsAt)
// 5
if flight.onSchedule {
statusLabel.setText("On Time")
} else {
statusLabel.setText("Delayed")
statusLabel.setTextColor(UIColor.redColor())
}
gateLabel.setText("Gate \(flight.gate)")
seatLabel.setText("Seat \(flight.seat)")
}
}
}
一步步講解發(fā)生的事情:
- 你定義了一個可選的屬性類型為 Flight。這個類在 Flight.swift 中定義;
- 你添加了一個屬性觀察器,當屬性設值時候會觸發(fā)它;
- 在可選屬性中確保有一個真的 flight 而不是 nil,當 flight 存在才會去設置 labels 的值;
- 使用 flight 的相關屬性去設置 labels
- 如果航班被延誤,那么你就將標簽的文本顏色改為紅色
在控制器第一次顯示時候設置航班。添加以下聲明:
override func awakeWithContext(context: AnyObject?) {
super.awakeWithContext(context)
flight = Flight.allFlights().first!
}
本后面的教程會修改為在上下文中傳遞值給它,但現(xiàn)在你只需要從共享的 JSON 文件中加載所有的航班,然后使用數(shù)組中的第一個。
在后面的教程你將學到更多關于 awakeWithContext(_:) 的知識,但是現(xiàn)在你僅僅需要知道它是界面控制器生命周期第一環(huán)節(jié),一個設置 flight 值的地方。
現(xiàn)在僅剩最后一步你就可以編譯運行了,就是去連接 outlets
連接outlets
打開 Watch\Interface.storyboard 選擇界面控制器,使用 Identity Inspector,設置 Class\Custom Class 為 FlightInterfaceController
下一步,右擊界面控制器頂部的黃色圖片彈出窗口:

現(xiàn)在,按下面的列表連接 outlets:
boardingLabel: AA123 Boards
boardTimeLabel: 15:06
flightLabel: Flight 123
gateLabel: Gate 1A
routeLabel: MAN to SFO
seatLabel: Seat 64A
statusLabel: On time
在運行之前,有一件事情要做。本教程的實例 app 專為42mm 的 Apple Watch 開發(fā)的,所以你需要確保正確設置了模擬器,否則界面元素看起來會有點小。對于一個現(xiàn)實 app,需要確保界面能很好運行在兩種大小的手表上,但這在本教程的范圍之外。
在 Xcode 中,選擇 Window\Devices 打開設備管理器,點擊右下角的 + 圖標.在彈出的對話框中,命名模擬器為 iPhone 6 - 42mm,設置設備類型為 iPhone 6,修改配對的 Apple watch 為 Apple Watch – 42mm (WatchOS 2.0) 然后點擊 Create:

關閉設備管理器,選擇 Watch Scheme,然后選中新的模擬器:

編譯運行。一段模擬器啟動完成你會看到下面界面:

注意:如果收到一條錯誤消息,說明安裝失敗,然后你可以再次嘗試使用 Xcode,或者在手表模擬器上手動安裝 app。為此,打開 iOS 模擬器中的手表 app,點擊 AirAber ,在 Apple Watch 彈出我們的 app。一旦這么做了,返回手表模擬器,按 Shift + Ctrl + H 導航到主界面, 然后點擊 AirAber 圖片來啟動手表 app。
恭喜!你已經(jīng)完成 WatchKit 初始界面,并使用真實的數(shù)據(jù)使它很好運行在手表模擬器上。
接下來做什么?
下面是這個系列教程完整示例項目。
在這個練習中你已經(jīng)學會了如何往現(xiàn)有的 iOS app 中添加手表 app,如何創(chuàng)建一個界面控制器和使用嵌套組構造一個非常復雜的界面,以及使用 WKInterfaceController 類來配合這項工作。那么,接下來呢?
本教程系列的第二部分,你將學習所有關于表和導航 WatchKit 的使用。
如果您對本教程有任何疑問或意見,請參加下面的論壇進行討論!