這篇文章其實早在8月份就寫出來了,一直沒發表出來,這期間也有好幾位朋友來問我關於 Apple watch 相關的問題。我也將這篇文章的 md 發給他們了,現在將這篇文章發表出來,讓更多想了解 Apple watch 開發的小夥伴能有一個簡單的入門吧。
相關文章文章推薦
喵神 WWDC15 Session筆記 – 30 分鐘開發一個簡單的 watchOS 2 app
Apple Watch和iOS App之間的通訊&
Apple Watch自定義Cell
Apple Watch音訊錄製,.wav轉換.mp3,獲取音訊檔案時長
Apple Watch開發中遇到的那些問題(WatchOS 2)
配置
Glance以及Notification需要自己手動的配置,編輯它們的Scheme就可以了。
生命週期
介面初始化呼叫順序(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 的話,可以將它們理解為分別對應-viewDidLoad
,viewWillAppear:
以及 -viewDidDisappear:
我們一般在 -initWithContext: 和 -willActivate 中配置“檢視元素”的屬性,在 -didDeactivate 中停用像是 NSTimer 之類的會 hold 住 self 的物件。需要特別注意的是,在 -didDeactivate 中對“檢視元素”屬性進行設定是無效的,因為當前的 WKInterfaceController 已經非活躍。
關於介面控制元件佈局
帶你玩- AppleWatch開發二:介面佈局帶你玩-AppleWatch開發四:Table檢視
一個控制元件只能對應一個actiontableView的點選事件,注意不要去給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,也是根據重力感應來彈出選單
經過測試,最多隻能新增四個,不管新增多少個,只會顯示前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;
複製程式碼
控制器之間傳值
正向傳值
- (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);
}];
複製程式碼
音訊錄製
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
這樣的控制元件。避免使用table
和map
Notifications
Apple watch的通知有兩種,分別是short looks
和long looks
short looks:短版本從上圖看,內容很簡單,一個App的icon,應用的名字,一條訊息。 和Glance
的UI介面一樣不能新增帶有操作性的控制元件。至於哪些能新增哪些不能新增,最直接的辦法就是拖一個控制元件到Static Notification interface controller
或者 Dynamic Notification interface controller
不報錯就說明這個控制元件是可以新增的。
long looks:長版本,長版本相對於短版本來說多了不少東西從上圖看首先它的UI是可以滾動的將它分為3個部分,分別是sash
,content
,actions
sash:包括了應用的名稱和icon,這部分預設的顏色是透明的,可以自己自定義顏色(修改顏色,選擇Static Notification interface controller
的入口,第四個選擇器)content:這部分就是推送的詳細內容action:操作按鈕(最多可以新增4個),然後Dismiss按鈕是系統一直會有的,不需要我們新增
模擬long looks
我們建立好一個Apple watch應用或者為已有專案新增一個target的時候預設會選擇Notification Scene
,然後我們的Notification InterfaceController
就會是上面的樣子,可能和storyboard中的有點不一樣,上面的圖我是在官方文件中找到的,可能官方還沒來的及更改吧。只要明白意思就好…Static interface
是必須的,而dynamic interface
是可選的。在推送到訊息的時候一般預設都是選擇的dynamic interface,只有當dynamic interface
不可用、沒有足夠的電力保證顯示動態介面、明確指出不能用動態介面的時候才會顯示Static interface
配置自定義介面的類目(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,short
和Bundle version
都要和iOS 裡面的一致,不然會build fail
小技巧
- 修改controller title的顏色
選擇要修改的控制器,右側的選擇器,選擇第一個選擇器下面的Global Tint
網路請求
不要使用NSURLConnection send...
方法,應該使用NSURLSession
方法