Apple watch 入門

LaiYoung_發表於2016-11-29

這篇文章其實早在8月份就寫出來了,一直沒發表出來,這期間也有好幾位朋友來問我關於 Apple watch 相關的問題。我也將這篇文章的 md 發給他們了,現在將這篇文章發表出來,讓更多想了解 Apple watch 開發的小夥伴能有一個簡單的入門吧。

相關文章文章推薦

喵神 Apple WatchKit 初探

喵神 WWDC15 Session筆記 - 30 分鐘開發一個簡單的 watchOS 2 app

Apple Watch和iOS App之間的通訊&Apple Watch自定義Cell

Kiss小錦 Apple watch開發些列

Apple Watch三個月開發的一些收穫總結

Apple Watch應用優化的一些心得技巧總結

如何設計Apple Watch上的App

Apple Watch音訊錄製,.wav轉換.mp3,獲取音訊檔案時長

Apple Watch開發中遇到的那些問題(WatchOS 2)

Apple watch 人機互動指南(譯)

WatchKit開發的部落格

Apple Watch開發總結

watchKit相關程式設計問題

Apple watch開發指南

配置

Glance以及Notification需要自己手動的配置,編輯它們的Scheme就可以了。

生命週期

Launch的生命週期

生命週期

介面初始化呼叫順序(OneController,TwoController)

push modal
OneController init OneController init
OneController awakeWithContext: OneController awakeWithContext:
OneController willActivate OneController willActivate
OneController didAppear OneController didAppear

點選事件之後...

push modal
OneController willDisappear TwoController init
TwoController init TwoController awakeWithContext:
TwoController awakeWithContext: OneController willDisappear
TwoController willActivate TwoController willActivate
OneController didDeactivate TwoController didAppear
TwoController didAppear OneController didDeactivate

返回事件之後...

pop dismiss
TwoController willDisappear TwoController willDisappear
OneController willActivate OneController willActivate:
TwoController didDeactivate OneController didAppear
OneController didAppear TwoController didDeactivate

生命週期總結:(摘抄至喵神的blog)

每個 WKInterfaceController 物件必然會被呼叫的生命週期方法有三個,分別是該物件被初始化時的-initWithContext:,將要呈現時的 -willActivate 以及呈現結束後的 -didDeactivate,同樣類比 UIViewController 的話,可以將它們理解為分別對應-viewDidLoadviewWillAppear: 以及 -viewDidDisappear: 我們一般在 -initWithContext: 和 -willActivate 中配置“檢視元素”的屬性,在 -didDeactivate 中停用像是 NSTimer 之類的會 hold 住 self 的物件。需要特別注意的是,在 -didDeactivate 中對“檢視元素”屬性進行設定是無效的,因為當前的 WKInterfaceController 已經非活躍。

關於介面控制元件佈局

帶你玩- AppleWatch開發二:介面佈局 帶你玩-AppleWatch開發四:Table檢視

一個控制元件只能對應一個action tableView的點選事件,注意不要去給cell拉線

#pragma mark - Table Row Select
-(void)table:(WKInterfaceTable *)table didSelectRowAtIndex:(NSInteger)rowIndex
{
    NSLog(@"did select rowIndex = %i",rowIndex);
    /** 設定傳指資料(正向傳指) */
    NSDictionary *contextDic = @{@"PicName":@"picture",@"index":[NSNumber numberWithInteger:rowIndex]};
//    [self presentControllerWithName:@"detail" context:contextDic];
    [self pushControllerWithName:@"detail" context:contextDic];
}
複製程式碼

MenuController

Apple watch獨有的,類似iPhone的3DTouch,也是根據重力感應來彈出選單

帶你玩-AppleWatch開發五:Menu選單

經過測試,最多隻能新增四個,不管新增多少個,只會顯示前4個。

導航方式(層級式,分頁式)

push或者Modal之後返回只有一個返回箭頭

注意點

針對 Watch 的開發不能使用程式碼的方式。首先,所有的 WKInterfaceObject 物件都必須要設計的時候經由 StoryBoard 進行新增,執行時我們無法再向介面上新增或者移除元素 (如果有移除需要的,可以使用隱藏);其次 WKInterfaceObject 與佈局相關的某些屬性,比如行高行數等,不能夠在執行時進行變更和設定。基本來說在執行時我們只能夠改變檢視的內容,以及通過隱藏某些檢視元素來達到有限地改變佈局 (其他檢視元素會試圖填充被隱藏的元素)。

控制器跳轉

- (void)pushControllerWithName:(NSString *)name context:(nullable id)context;

- (void)presentControllerWithName:(NSString *)name context:(nullable id)context;
/** present多個控制器,類似next Page */
- (void)presentControllerWithNames:(NSArray<NSString*> *)names contexts:(nullableNSArray*)contexts;
複製程式碼

presentControllerWithNames(忘了這圖的原出處了,要是原作者看見請告知,侵刪)

控制器之間傳值

正向傳值
- (void)pushControllerWithName:(NSString *)name context:(nullable id)context;
- (void)presentControllerWithName:(NSString *)name context:(nullable id)context;
- (void)presentControllerWithNames:(NSArray<NSString*> *)names contexts:(nullableNSArray*)contexts;
複製程式碼

在上面的三個方法中的末尾都有一個context:引數,這個引數就是用於在我們跳轉控制器的時候傳值,這點比iOS端方便多了。

Segue傳值
//tableView
- (NSArray *)contextsForSegueWithIdentifier:(NSString *)segueIdentifier inTable:(WKInterfaceTable *)table rowIndex:(NSInteger)rowIndex {
    return nil;//傳值內容
}

- (id)contextForSegueWithIdentifier:(NSString *)segueIdentifier {
    return nil;//傳值內容
}

- (NSArray *)contextsForSegueWithIdentifier:(NSString *)segueIdentifier {
    return nil;//傳值內容
}
//tableView
- (id)contextForSegueWithIdentifier:(NSString *)segueIdentifier inTable:(WKInterfaceTable *)table rowIndex:(NSInteger)rowIndex {
    return nil;//傳值內容
}
複製程式碼
資料接收

在控制器的awakeWithContext:方法接收資料

- (void)awakeWithContext:(id)context {
    [super awakeWithContext:context];
    NSLog(@"receive = %@",context);
    
    // Configure interface objects here.
}
複製程式碼

多媒體

官方程式設計文件

MP3/MP4播放
    //.mp3 or .mp4
    NSURL *url = [[NSBundle mainBundle] URLForResource:@"Jennifer Lopez - Feel the Light" withExtension:@".mp3"];
    NSDictionary *options = @{WKMediaPlayerControllerOptionsAutoplayKey:@YES};
    [self presentMediaPlayerControllerWithURL:url options:options completion:^(BOOL didPlayToEnd, NSTimeInterval endTime, NSError * _Nullable error) {
        if (error) {
            NSLog(@"error = %@",error);
            return ;
        }
        NSLog(@"endTime = %f",endTime);
    }];
複製程式碼

mp3播放.png

mp4播放.png

音訊錄製

Apple watch有自帶的錄音控制器,我們只需要配置好就可以。支援.wav, .mp4, and .m4a格式

 NSDictionary *recorderOptions = @{
                                      /** 錄製好之後的標題 */
                                    WKAudioRecorderControllerOptionsActionTitleKey:@"傳送",
                                    /** 是否自動錄製 */
                                    WKAudioRecorderControllerOptionsAutorecordKey:@YES,
                                    /** 時間 NSTimeInterval */
                                    WKAudioRecorderControllerOptionsMaximumDurationKey:@30
                                    };
    
    [self presentAudioRecorderControllerWithOutputURL:_recorderUrl preset:WKAudioRecorderPresetHighQualityAudio options:recorderOptions completion:^(BOOL didSave, NSError * _Nullable error) {
        NSLog(@"didSave = %@",didSave?@"YES":@"NO");
        if (error) {
            NSLog(@"error = %@",error);
        }
    }];

複製程式碼
注意點:

OutputURL 這個URL不是沙盒URL,而是App Groups的URL。 在模擬器上使用沙盒路徑,錄製播放都沒有問題。 但是,使用手錶的話就會出現一錄音這個控制器就直接dismiss掉了。

App Groups 的路徑

/** Identifier 要跟App Groups 一致 */
NSURL *url =  [[NSFileManager defaultManager] containerURLForSecurityApplicationGroupIdentifier:@"group.com.LaiYoung.NextPage1111"];
NSURL *fileUrl = [url URLByAppendingPathComponent:@"record.wav"];
複製程式碼

相關文章 Apple Watch音訊錄製,.wav轉換.mp3,獲取音訊檔案時長

Glance介面(沒有互動響應,點選任何位置都會跳轉到應用內部)

這是一個類似簡介的東西 開始沒有選擇,如何新增一個Glance,在storyboard拖一個Glance Interface Controller,然後新增一個Scheme,命名為ClanceXXX,選擇Edit Scheme...Executable選擇XXX Watch App.app,Watch Interface則選擇對應的Glance,close即可

UI:Glance都是基於特定模版的,蘋果提供了一系列的模版,包括了螢幕頂部和底部的設計。在Glance Interface Controller Scene的第四個選擇器選擇。 UI介面不能新增帶有事件操作性的控制元件,例如Button,Switch等等,但是可以新增Label,Image這樣的控制元件。避免使用tablemap

Notifications

Apple watch的通知有兩種,分別是short lookslong looks

short looks
short looks:短版本 從上圖看,內容很簡單,一個App的icon,應用的名字,一條訊息。 和Glance的UI介面一樣不能新增帶有操作性的控制元件。至於哪些能新增哪些不能新增,最直接的辦法就是拖一個控制元件到Static Notification interface controller 或者 Dynamic Notification interface controller 不報錯就說明這個控制元件是可以新增的。
long looks

long looks:長版本,長版本相對於短版本來說多了不少東西 從上圖看首先它的UI是可以滾動的 將它分為3個部分,分別是sashcontentactions

sash:包括了應用的名稱和icon,這部分預設的顏色是透明的,可以自己自定義顏色(修改顏色,選擇Static Notification interface controller的入口,第四個選擇器) content:這部分就是推送的詳細內容 action:操作按鈕(最多可以新增4個),然後Dismiss按鈕是系統一直會有的,不需要我們新增

模擬long looks

Static and dynamic notification interfaces

我們建立好一個Apple watch應用或者為已有專案新增一個target的時候預設會選擇Notification Scene,然後我們的Notification InterfaceController就會是上面的樣子,可能和storyboard中的有點不一樣,上面的圖我是在官方文件中找到的,可能官方還沒來的及更改吧。只要明白意思就好... Static interface是必須的,而dynamic interface是可選的。 在推送到訊息的時候一般預設都是選擇的dynamic interface,只有當dynamic interface不可用、沒有足夠的電力保證顯示動態介面、明確指出不能用動態介面的時候才會顯示Static interface

Apple watch 入門

配置自定義介面的類目(Category)

官方文件 Notifications

相關文章 Notifications概述

關於稽核:

關於Watch App稽核,如果你選擇了某個功能,但沒有實現,那麼一定會被拒絕的,大家注意一下這點,坑就來那裡~

坑:

  • 使用程式碼設定圖片
    Apple watch和iPhone開發不一樣,所以圖片尺寸要求也不一樣 找到Apple watch的Assets.xcassets選擇圖片之後點選第三個選擇器 Devices勾選watchOS,會發現對於的2x/38 mm 2x/42 mm 2x都 沒有圖片,所以導致程式碼設定不會出來。
  • watchOS 2.0不再支援App Groups,watchOS 2.0可以使用WCSession進行通訊,WCSession具體怎麼使用可以看我之前的這片文章 Apple Watch和iOS App之間的通訊&Apple Watch自定義Cell

Error

Apple watch的Bundle versions string,shortBundle version都要和iOS 裡面的一致,不然會build fail

小技巧

  • 修改controller title的顏色
    選擇要修改的控制器,右側的選擇器,選擇第一個選擇器下面的Global Tint

網路請求

不要使用NSURLConnection send...方法,應該使用NSURLSession方法

相關文章