你好,歡迎來到IOS教程網

 Ios教程網 >> IOS編程開發 >> IOS開發基礎 >> 走進 WatchKit Framework

走進 WatchKit Framework

編輯:IOS開發基礎

寫在前面

WatchKit Apple提供的開發專題頁面如下: https://developer.apple.com/watchkit/。其中包含兩個Demo,這兩個Demo可以讓大家快速的了解WatchKit的構建。

Watch App Architecture

每一個Apple Watch App和 iOS Extension一樣仍然需要依賴一個主體App,Apple Watch App 包含兩個部分:Watch App 和 WatchKit Extension,如下圖:

0021.jpg

其中 Watch App 部分位於用戶的Apple Watch上,它目前為止只允許包含Storyboard文件和Resources文件。在我們的項目裡,這一部分不包括任何代碼。

WatchKit Extension 部分位於用戶的iPhone安裝的對應App上,這裡包括我們需要實現的代碼邏輯和其他資源文件。

這兩個部分之間就是通過 WatchKit進行連接通訊。

WatchKit

WatchKit用來為開發者構建Apple Watch App。它所有的類如下,其中最上層的類繼承於NSObject。

WKInterfaceController
    WKUserNotificationInterfaceController
WKInterfaceDevice
WKInterfaceObject
    WKInterfaceButton
    WKInterfaceDate
    WKInterfaceGroup
    WKInterfaceImage
    WKInterfaceLabel
    WKInterfaceMap
    WKInterfaceSeparator
    WKInterfaceSlider
    WKInterfaceSwitch
    WKInterfaceTable
    WKInterfaceTimer
WKInterfaceController

WKInterfaceController是我們開發Watch App的核心類,它的地位和之前使用的UIViewController一樣。

每一個Watch App構建時,至少需要在Storyboard上設置一個WKInterfaceController實例作為程序入口。我們可以在Storyboard上使用Main Entry Point設置。

當用戶launch了Watch App時,Watch OS 會開始加載程序中的Storyboard。我們在Storyboard中為每一個WKInterfaceController設置的響應事件,會在用戶觸發時在WatchKit Extension中響應。我們可以像以前一樣push, pop, present 目標WKInterfaceController。

生命周期

WKInterfaceController一樣也有自己的生命周期,以下幾個API對應了幾個不同的狀態:

- (instancetype)initWithContext:(id)context;
- (void)willActivate;
- (void)didDeactivate;

當Watch OS加載App中的Storyboard時,iPhone端也會開始加載對應的WatchKit Extension。

022.jpg

當Watch OS開始初始化我們Watch App的Storyboard中的UI時,iPhone端WatchKit Extension會生成對應的WKInterfaceController,並且響應initWithContext:方法。

當Watch OS顯示當前加載的UI時,WatchKit Extension中對應的WKInterfaceController響應willActivate方法。

當用戶切換頁面或者停止使用時,WatchKit Extension中對應的WKInterfaceController響應didDeactivate方法。

0023.jpg

從上圖可知這三個API,對應了Watch OS加載一個視圖控制器的三個狀態。我們在自己的WKInterfaceController類中,應該實現這三個API用來處理不同的情況:

  • initWithContext: 我們可以在這裡加載數據或者更新在StoryBoard中當前Controller添加的interface objects。

  • willActivate 我們可以在這裡更新interface objects或者處理其他事件

  • didDeactivate 我們應該在這裡清理task或者數據。在這裡更新interface objects將會被系統忽略。

頁面跳轉

當用戶和我們的APP進行交互時,有很多時候,我們需要進行頁面的跳轉。WKInterfaceController目前支持兩組API進行頁面跳轉:

- (void)pushControllerWithName:(NSString *)name context:(id)context
- (void)popController;
- (void)popToRootController;
- (void)presentControllerWithName:(NSString *)name context:(id)context;
- (void)presentControllerWithNames:(NSArray *)names contexts:(NSArray *)contexts;
- (void)dismissController;
- (void)becomeCurrentPage;

Push,Pop, Present, Dismiss的行為和UIViewController中類似。我們可以在代碼中,根據程序上下文的狀態,控制跳轉到某一個頁面。

使用這一組API時有四點需要注意:

  • Push和Present方法第一個參數是對應的在Storyboard中為WKInterfaceController設置的identifier字符串。WatchKit Extension使用這幾個API向Watch OS傳遞消息,真實的UI加載渲染行為是在Watch端進行。

  • popToRootController是跳轉到Watch App的Storyboard中Main Entry Point對應的Controller。

  • presentControllerWithNames, 我們可以present一組Controller, 這一組Controller將以page control的形式展示。

  • becomeCurrentPage 當頁面是以page control的形式展現時,我們可以調用這個方法改變當前的page

另外一組API是:

- (id)contextForSegueWithIdentifier:(NSString *)segueIdentifier;
- (NSArray *)contextsForSegueWithIdentifier:(NSString *)segueIdentifier;
- (id)contextForSegueWithIdentifier:(NSString *)segueIdentifier inTable:(WKInterfaceTable *)table rowIndex:(NSInteger)rowIndex;
- (NSArray *)contextsForSegueWithIdentifier:(NSString *)segueIdentifier inTable:(WKInterfaceTable *)table rowIndex:(NSInteger)rowIndex;

當我們在應用設計的階段就知道需要跳轉的下一個WKInterfaceController時,我們可以直接在Storyboard中設置Triggered Segues。使用Segues時,Selection同樣支持Push和Model兩種跳轉方式。

我們可以使用上面一組API進行跳轉中的數據傳遞。

響應交互事件

WKInterfaceObject中像Button,Slider, Switch等控件可以和用戶交互,我們和往常一樣,可以在WKInterfaceController實現對應的Action,標記為IBAction,然後連接到Storyboard中。

這裡特別的地方是,當我們的WKInterfaceController中包含WKInterfaceTable實例時,我們可以通過實現默認的- (void)table:(WKInterfaceTable *)table didSelectRowAtIndex:(NSInteger)rowIndex方法響應table中每一行的點擊事件,這裡和往常的UITableView的實現方式不太一樣,更加簡單。

Glance

Glance是 Watch App上新的概念,它主要作用是給用戶一個短時的提醒。我們可以通過Storyboard創建一個Glance interface Controller.對應的WatchKit Extension中,它同樣需要繼承於WKInterfaceController,享有同樣的生命周期。我們可以在其中實現自己的邏輯。

這裡需要注意的是,Glance是可以和用戶進行交互的。當用戶Tap Glance頁面時,會跳轉到我們的Watch App中。這裡可以在自定義的GlanceInterfaceController中使用- (void)updateUserActivity:(NSString *)type userInfo:(NSDictionary *)userInfo傳遞數據。比如我們需要在用戶點擊Glance之後進入到某一個特定的頁面,我們可以把目標頁面的identifier和要傳遞的其他消息包裝到字典中,然後在Initial Interface Controller中實現- (NSString *)actionForUserActivity:(NSDictionary *)userActivity context:(id *)context方法跳轉到目標頁面,這裡的userActivity就是上文傳遞的userInfo,返回的NSString是目標頁面的identifier,context指針是目標頁面initWithContext中context數據。

Notification && WKUserNotificationInterfaceController

當我們的主體App支持Notification時,Apple Watch將能夠顯示這些通知。Watch OS提供了默認的通知顯示,當用戶點擊通知進入我們的App時,Initial Interface Controller中- (void)handleActionWithIdentifier:(NSString *)identifier forRemoteNotification:(NSDictionary *)remoteNotification或者- (void)handleActionWithIdentifier:(NSString *)identifier forLocalNotification:(UILocalNotification *)localNotification方法將會被響應,我們可以通過實現這兩個方法獲得通知的消息,跳轉到目標頁面。

我們同樣可以通過Storyboard創建一個Notification interface Controller,這樣可以實現自定義的通知界面。對應的WatchKit Extension中,它繼承於WKUserNotificationInterfaceController,享有和WKInterfaceController同樣的生命周期。我們可以通過實現下面兩組API- (void)didReceiveRemoteNotification:(NSDictionary *)remoteNotification withCompletion:(void(^)(WKUserNotificationInterfaceType interface)) completionHandler或者- (void)didReceiveLocalNotification:(UILocalNotification *)localNotification withCompletion:(void(^)(WKUserNotificationInterfaceType interface)) completionHandler獲得通知內容,並設置處理完成的回調Block。

Menu

我們可以通過Storyboard在界面中添加Menu,它看起來像這樣:

5414.jpg

我們不但可以通過Storyboard在Menu中添加Item,也可以通過WKInterfaceController中以下一組API,在上下文環境中添加相應的Item:

- (void)addMenuItemWithImage:(UIImage *)image title:(NSString *)title action:(SEL)action; 
- (void)addMenuItemWithImageNamed:(NSString *)imageName title:(NSString *)title action:(SEL)action;
- (void)addMenuItemWithItemIcon:(WKMenuItemIcon)itemIcon title:(NSString *)title action:(SEL)action;
- (void)clearAllMenuItems;

WKInterfaceObject

WKInterfaceObject負責界面的元素,目前Apple公開了11個具體的子類用來展現各種不同類型的元素。它和之前的UIView或者UIView的子類不一樣,WKInterfaceObject只負責在WatchKit Extension和Watch App中傳遞相應的事件,具體的UI渲染在Watch App中完成。

Watch App 采取的布局方式和 iOS App 完全不同。我們無法指定某個視圖的具體坐標,也不能使用AutoLayout來進行布局。WatchKit只能在以“行”為基本單位進行布局。在一行中如果要顯示多個元素,我們就要通過WKInterfaceGroup在行內進行列布局。

WKInterfaceTable

和學習iOS開發一樣,先從一個TableView開始上手。目前在WatchKit中最復雜的界面元素也是WKInterfaceTable。

我們可以通過Storyboard直接在當前WKInterfaceController中添加一個Table,每一個Table默認包含一個Table Row Controller, 這個Table Row Controller作用相當於之前的Cell,不過這裡是繼承於NSObject。我們可以使用Table Row Controller中定義每一種Row的樣式,然後設置一個唯一的identifier用來區分。

我們可以通過以下兩組設置Table的每一行的樣式,rowType對應Storyboard中Row Controller的identifier。

- (void)setRowTypes:(NSArray *)rowTypes;
- (void)setNumberOfRows:(NSInteger)numberOfRows withRowType:(NSString *)rowType;

我們可以通過- (id)rowControllerAtIndex:(NSInteger)index獲得某一行對應的Row Controller。下面是一段在interface controller中初始化Table Rows的例子:

- (void)loadTableRows {
    [self.interfaceTable setNumberOfRows:self.elementsList.count withRowType:@"default"];
    // Create all of the table rows.
    [self.elementsList enumerateObjectsUsingBlock:^(NSDictionary *rowData, NSUInteger idx, BOOL *stop) {
        AAPLElementRowController *elementRow = [self.interfaceTable rowControllerAtIndex:idx];
        [elementRow.elementLabel setText:rowData[@"label"]];
    }];
}

我們同樣可以使用下面的API進行添加,刪除Table的Rows:

- (void)insertRowsAtIndexes:(NSIndexSet *)rows withRowType:(NSString *)rowType;
- (void)removeRowsAtIndexes:(NSIndexSet *)rows;

WKInterfaceDevice

這是一個單例類,可以獲得當前Apple Watch的部分信息。目前公開的信息有:

@property(nonatomic,readonly) CGRect    screenBounds;
@property(nonatomic,readonly) CGFloat   screenScale;
@property(nonatomic,readonly,strong) NSLocale *currentLocale;
@property(nonatomic,readonly,copy)  NSString *preferredContentSizeCategory;

另外我們可以使用這個類中的以下一組方法來緩存圖片,以備將來繼續使用:

- (void)addCachedImage:(UIImage *)image name:(NSString *)name;
- (void)addCachedImageWithData:(NSData *)imageData name:(NSString *)name;
- (void)removeCachedImageWithName:(NSString *)name;
- (void)removeAllCachedImages;

已經緩存的圖片,可以使用WKInterfaceImage中下面的API直接讀取:

- (void)setImageData:(NSData *)imageData;
- (void)setImageNamed:(NSString *)imageName;

WatchKit允許每一個App最多緩存20MB的圖片,如果超過的話,WatchKit將從最老的數據開始刪除,為新數據騰出空間。

總結

關於WatchKit Framework中API的知識點都基本包含在了上述筆記中。目前所提供的API功能有限,主要是信息的顯示,通知的接收。更多關於多媒體或者傳感器方面的API在這個版本中並沒有開放,期待蘋果的下一次更新。

  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved