Apple watch 開發入門

這篇文章其實早在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的生命周期
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

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

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

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

模擬long looks

Static and dynamic notification interfaces
Static and dynamic notification interfaces

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

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

官方文檔 Notifications

相關文章 Notifications概述

關于審核:

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

坑:

  • 使用代碼設置圖片</br>
    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的顏色</br>
    選擇要修改的控制器,右側的選擇器,選擇第一個選擇器下面的Global Tint

網絡請求

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

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容