Apple watch 開(kāi)發(fā)入門

這篇文章其實(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)文章文章推薦

喵神 Apple WatchKit 初探

喵神 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é)

如何設(shè)計(jì)Apple Watch上的App

Apple Watch音頻錄制,.wav轉(zhuǎn)換.mp3,獲取音頻文件時(shí)長(zhǎng)

Apple Watch開(kāi)發(fā)中遇到的那些問(wèn)題(WatchOS 2)

Apple watch 人機(jī)交互指南(譯)

WatchKit開(kāi)發(fā)的博客

Apple Watch開(kāi)發(fā)總結(jié)

watchKit相關(guān)編程問(wèn)題

Apple watch開(kāi)發(fā)指南

配置

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

生命周期

Launch的生命周期
Launch的生命周期
生命周期
生命周期

界面初始化調(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;
presentControllerWithNames(忘了這圖的原出處了,要是原作者看見(jiàn)請(qǐng)告知,侵刪)

控制器之間傳值

正向傳值
- (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);
    }];
mp3播放.png
mp4播放.png
音頻錄制

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這樣的控件。避免使用tablemap

Notifications

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

short looks
short 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
long looks

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

Static and dynamic notification interfaces
Static and dynamic notification interfaces

我們創(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,shortBundle version都要和iOS 里面的一致,不然會(huì)build fail

小技巧

  • 修改controller title的顏色</br>
    選擇要修改的控制器,右側(cè)的選擇器,選擇第一個(gè)選擇器下面的Global Tint

網(wǎng)絡(luò)請(qǐng)求

不要使用NSURLConnection send...方法,應(yīng)該使用NSURLSession方法

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,048評(píng)論 6 542
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,414評(píng)論 3 429
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人,你說(shuō)我怎么就攤上這事?!?“怎么了?”我有些...
    開(kāi)封第一講書人閱讀 178,169評(píng)論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書人閱讀 63,722評(píng)論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 72,465評(píng)論 6 412
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書人閱讀 55,823評(píng)論 1 328
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,813評(píng)論 3 446
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書人閱讀 43,000評(píng)論 0 290
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,554評(píng)論 1 335
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 41,295評(píng)論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 43,513評(píng)論 1 374
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,035評(píng)論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,722評(píng)論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 35,125評(píng)論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 36,430評(píng)論 1 295
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 52,237評(píng)論 3 398
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 48,482評(píng)論 2 379

推薦閱讀更多精彩內(nèi)容