這篇文章其實(shí)早在8月份就寫出來(lái)了,一直沒(méi)發(fā)表出來(lái),這期間也有好幾位朋友來(lái)問(wèn)我關(guān)于 Apple watch 相關(guān)的問(wèn)題。我也將這篇文章的 md 發(fā)給他們了,現(xiàn)在將這篇文章發(fā)表出來(lái),讓更多想了解 Apple watch 開(kāi)發(fā)的小伙伴能有一個(gè)簡(jiǎn)單的入門吧。
相關(guān)文章文章推薦
喵神 WWDC15 Session筆記 - 30 分鐘開(kāi)發(fā)一個(gè)簡(jiǎn)單的 watchOS 2 app
Apple Watch和iOS App之間的通信&Apple Watch自定義Cell
Kiss小錦 Apple watch開(kāi)發(fā)些列
Apple Watch三個(gè)月開(kāi)發(fā)的一些收獲總結(jié)
Apple Watch應(yīng)用優(yōu)化的一些心得技巧總結(jié)
Apple Watch音頻錄制,.wav轉(zhuǎn)換.mp3,獲取音頻文件時(shí)長(zhǎng)
Apple Watch開(kāi)發(fā)中遇到的那些問(wèn)題(WatchOS 2)
配置
Glance以及Notification需要自己手動(dòng)的配置,編輯它們的Scheme就可以了。
生命周期


界面初始化調(diào)用順序(OneController,TwoController)
push | modal |
---|---|
OneController init | OneController init |
OneController awakeWithContext: | OneController awakeWithContext: |
OneController willActivate | OneController willActivate |
OneController didAppear | OneController didAppear |
點(diǎn)擊事件之后...
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 |
生命周期總結(jié):(摘抄至喵神的blog)
每個(gè) WKInterfaceController 對(duì)象必然會(huì)被調(diào)用的生命周期方法有三個(gè),分別是該對(duì)象被初始化時(shí)的-initWithContext:
,將要呈現(xiàn)時(shí)的 -willActivate
以及呈現(xiàn)結(jié)束后的 -didDeactivate
,同樣類比 UIViewController 的話,可以將它們理解為分別對(duì)應(yīng)-viewDidLoad
,viewWillAppear:
以及 -viewDidDisappear:
我們一般在 -initWithContext: 和 -willActivate 中配置“視圖元素”的屬性,在 -didDeactivate 中停用像是 NSTimer 之類的會(huì) hold 住 self 的對(duì)象。需要特別注意的是,在 -didDeactivate 中對(duì)“視圖元素”屬性進(jìn)行設(shè)置是無(wú)效的,因?yàn)楫?dāng)前的 WKInterfaceController 已經(jīng)非活躍。
關(guān)于界面控件布局
帶你玩- AppleWatch開(kāi)發(fā)二:界面布局
帶你玩-AppleWatch開(kāi)發(fā)四:Table視圖
一個(gè)控件只能對(duì)應(yīng)一個(gè)action
tableView的點(diǎn)擊事件,注意不要去給cell拉線
#pragma mark - Table Row Select
-(void)table:(WKInterfaceTable *)table didSelectRowAtIndex:(NSInteger)rowIndex
{
NSLog(@"did select rowIndex = %i",rowIndex);
/** 設(shè)置傳指數(shù)據(jù)(正向傳指) */
NSDictionary *contextDic = @{@"PicName":@"picture",@"index":[NSNumber numberWithInteger:rowIndex]};
// [self presentControllerWithName:@"detail" context:contextDic];
[self pushControllerWithName:@"detail" context:contextDic];
}
MenuController
Apple watch獨(dú)有的,類似iPhone的3DTouch,也是根據(jù)重力感應(yīng)來(lái)彈出菜單
帶你玩-AppleWatch開(kāi)發(fā)五:Menu菜單
經(jīng)過(guò)測(cè)試,最多只能添加四個(gè),不管添加多少個(gè),只會(huì)顯示前4個(gè)。
導(dǎo)航方式(層級(jí)式,分頁(yè)式)
push或者M(jìn)odal之后返回只有一個(gè)返回箭頭
注意點(diǎn)
針對(duì) Watch 的開(kāi)發(fā)不能使用代碼的方式。首先,所有的 WKInterfaceObject 對(duì)象都必須要設(shè)計(jì)的時(shí)候經(jīng)由 StoryBoard 進(jìn)行添加,運(yùn)行時(shí)我們無(wú)法再向界面上添加或者移除元素 (如果有移除需要的,可以使用隱藏);其次 WKInterfaceObject 與布局相關(guān)的某些屬性,比如行高行數(shù)等,不能夠在運(yùn)行時(shí)進(jìn)行變更和設(shè)定?;緛?lái)說(shuō)在運(yùn)行時(shí)我們只能夠改變視圖的內(nèi)容,以及通過(guò)隱藏某些視圖元素來(lái)達(dá)到有限地改變布局 (其他視圖元素會(huì)試圖填充被隱藏的元素)。
控制器跳轉(zhuǎn)
- (void)pushControllerWithName:(NSString *)name context:(nullable id)context;
- (void)presentControllerWithName:(NSString *)name context:(nullable id)context;
/** present多個(gè)控制器,類似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;
在上面的三個(gè)方法中的末尾都有一個(gè)context:
參數(shù),這個(gè)參數(shù)就是用于在我們跳轉(zhuǎn)控制器的時(shí)候傳值,這點(diǎn)比iOS端方便多了。
Segue傳值
//tableView
- (NSArray *)contextsForSegueWithIdentifier:(NSString *)segueIdentifier inTable:(WKInterfaceTable *)table rowIndex:(NSInteger)rowIndex {
return nil;//傳值內(nèi)容
}
- (id)contextForSegueWithIdentifier:(NSString *)segueIdentifier {
return nil;//傳值內(nèi)容
}
- (NSArray *)contextsForSegueWithIdentifier:(NSString *)segueIdentifier {
return nil;//傳值內(nèi)容
}
//tableView
- (id)contextForSegueWithIdentifier:(NSString *)segueIdentifier inTable:(WKInterfaceTable *)table rowIndex:(NSInteger)rowIndex {
return nil;//傳值內(nèi)容
}
數(shù)據(jù)接收
在控制器的awakeWithContext:
方法接收數(shù)據(jù)
- (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 = @{
/** 錄制好之后的標(biāo)題 */
WKAudioRecorderControllerOptionsActionTitleKey:@"發(fā)送",
/** 是否自動(dòng)錄制 */
WKAudioRecorderControllerOptionsAutorecordKey:@YES,
/** 時(shí)間 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);
}
}];
注意點(diǎn):
OutputURL 這個(gè)URL不是沙盒URL,而是App Groups
的URL。
在模擬器上使用沙盒路徑,錄制播放都沒(méi)有問(wèn)題。
但是,使用手表的話就會(huì)出現(xiàn)一錄音這個(gè)控制器就直接dismiss掉了。
App Groups 的路徑
/** Identifier 要跟App Groups 一致 */
NSURL *url = [[NSFileManager defaultManager] containerURLForSecurityApplicationGroupIdentifier:@"group.com.LaiYoung.NextPage1111"];
NSURL *fileUrl = [url URLByAppendingPathComponent:@"record.wav"];
相關(guān)文章 Apple Watch音頻錄制,.wav轉(zhuǎn)換.mp3,獲取音頻文件時(shí)長(zhǎng)
Glance界面(沒(méi)有交互響應(yīng),點(diǎn)擊任何位置都會(huì)跳轉(zhuǎn)到應(yīng)用內(nèi)部)
這是一個(gè)類似簡(jiǎn)介的東西
開(kāi)始沒(méi)有選擇,如何新增一個(gè)Glance
,在storyboard拖一個(gè)Glance Interface Controller
,然后新增一個(gè)Scheme
,命名為ClanceXXX
,選擇Edit Scheme...
,Executable
選擇XXX Watch App.app
,Watch Interface則選擇對(duì)應(yīng)的Glance,close即可
UI:Glance都是基于特定模版的,蘋果提供了一系列的模版,包括了屏幕頂部和底部的設(shè)計(jì)。在Glance Interface Controller Scene
的第四個(gè)選擇器選擇。
UI界面不能添加帶有事件操作性的控件,例如Button,Switch
等等,但是可以添加Label,Image
這樣的控件。避免使用table
和map
Notifications
Apple watch的通知有兩種,分別是short looks
和long looks

short looks:短版本
從上圖看,內(nèi)容很簡(jiǎn)單,一個(gè)App的icon,應(yīng)用的名字,一條消息。 和
Glance
的UI界面一樣不能添加帶有操作性的控件。至于哪些能添加哪些不能添加,最直接的辦法就是拖一個(gè)控件到Static Notification interface controller
或者 Dynamic Notification interface controller
不報(bào)錯(cuò)就說(shuō)明這個(gè)控件是可以添加的。</br>

long looks:長(zhǎng)版本,長(zhǎng)版本相對(duì)于短版本來(lái)說(shuō)多了不少東西
從上圖看首先它的UI是可以滾動(dòng)的
將它分為3個(gè)部分,分別是sash
,content
,actions
sash:包括了應(yīng)用的名稱和icon,這部分默認(rèn)的顏色是透明的,可以自己自定義顏色(修改顏色,選擇Static Notification interface controller
的入口,第四個(gè)選擇器)
content:這部分就是推送的詳細(xì)內(nèi)容
action:操作按鈕(最多可以添加4個(gè)),然后Dismiss按鈕是系統(tǒng)一直會(huì)有的,不需要我們添加
模擬long looks

我們創(chuàng)建好一個(gè)Apple watch應(yīng)用或者為已有項(xiàng)目添加一個(gè)target的時(shí)候默認(rèn)會(huì)選擇Notification Scene
,然后我們的Notification InterfaceController
就會(huì)是上面的樣子,可能和storyboard中的有點(diǎn)不一樣,上面的圖我是在官方文檔中找到的,可能官方還沒(méi)來(lái)的及更改吧。只要明白意思就好...
Static interface
是必須的,而dynamic interface
是可選的。
在推送到消息的時(shí)候一般默認(rèn)都是選擇的dynamic interface,只有當(dāng)dynamic interface
不可用、沒(méi)有足夠的電力保證顯示動(dòng)態(tài)界面、明確指出不能用動(dòng)態(tài)界面的時(shí)候才會(huì)顯示Static interface

配置自定義界面的類目(Category)
官方文檔 Notifications
相關(guān)文章 Notifications概述
關(guān)于審核:
關(guān)于Watch App審核,如果你選擇了某個(gè)功能,但沒(méi)有實(shí)現(xiàn),那么一定會(huì)被拒絕的,大家注意一下這點(diǎn),坑就來(lái)那里~
坑:
- 使用代碼設(shè)置圖片</br>
Apple watch和iPhone開(kāi)發(fā)不一樣,所以圖片尺寸要求也不一樣
找到Apple watch的Assets.xcassets
選擇圖片之后點(diǎn)擊第三個(gè)選擇器Devices
勾選watchOS,會(huì)發(fā)現(xiàn)對(duì)于的2x/38 mm 2x/42 mm 2x
都 沒(méi)有圖片,所以導(dǎo)致代碼設(shè)置不會(huì)出來(lái)。 -
watchOS 2.0
不再支持App Groups
,watchOS 2.0可以使用WCSession
進(jìn)行通訊,WCSession
具體怎么使用可以看我之前的這片文章 Apple Watch和iOS App之間的通信&Apple Watch自定義Cell
Error
Apple watch的Bundle versions string,short
和Bundle version
都要和iOS 里面的一致,不然會(huì)build fail
小技巧
- 修改controller title的顏色</br>
選擇要修改的控制器,右側(cè)的選擇器,選擇第一個(gè)選擇器下面的Global Tint
網(wǎng)絡(luò)請(qǐng)求
不要使用NSURLConnection send...
方法,應(yīng)該使用NSURLSession
方法