Programming

AppleWatchの勉強会の振り返り(サンプルの簡単な解説付き)

 Author:fumiyasac

スクリーンショット 2015-01-26 23.44.49

1月も勉強会(もくもく会が一番多いんだけど)が多くって本当にエキサイティングな日が仕事でもプライベートでも続いていました。25日は体調不良(原因不明の頭痛)で1日中寝っこけていましてブログ書くのが遅れてしまいました。
先日、AppleWatchの勉強会がコワーキングスペースCo-Edoで開催されていましたので、僕も参加してきましたので、そのときに作成したサンプル等を公開していきたいと思います。
発売が楽しみです(←買う気でいるんかい!)

1. XCode6.2 Betaが必要&WatchKit Frameworkを使用する

まず、WatchKitでAppleWatch対応のアプリを作る際には、XCodeの6.2 Betaが必要になってきます。(一応現在XCode6.1がリリース版の最新になりますが、こちらは共存が可能ですのでXCodeを起動をする際は6.2での起動を行って下さい)

まずは概念やプロジェクトの作り方に関してはこちらのエントリー等が参考にできるのではないかと思います。

[WatchKitことはじめにあたっての参考]
Watch KitでApple Watchアプリを作ってみる(Hello World編)

こいつ自体はネイティブアプリそのものではなく、あくまでも拡張アプリ的な位置づけなので、AppExtentionと同じ概念で実装する感じです。
(iPhoneがないとアカンということなのか…)

概要やAppleWatchのライフサイクルの説明にあたっては下記の記事が参考になると思います。いきなり公式の英語ドキュメントを読むのはちょっと辛いという方にはオススメです。

[AppleWatchの概要説明の参考]
仕事じゃ触れないWatchKitの話

[AppleWatchのライフサイクルにあたっての参考]
Apple Watch Appのライフサイクルまとめ

メソッドも基本的にはsetter系のものしかないの最初はあれ?何か違うぞ?という印象も結構あったのですが、

  • 画像やボタン等のインスタンスの配置は基本的にStoryboardで行う
  • Glance(Watchアプリから重要な情報を表示するための補助機能)やNotification(通知に関する補助機能)があり、この辺の実装は任意
  • iPhoneにWatchからデータを送ることができる

等の特徴なんかもあって、APIは少ないとはいっても色々アイデアは出てきそうで是非とも試してみたい機能もたくさんありますね。

というわけで今回は簡単なサンプルとして「束縛ウォッチ」という超簡単なアプリを作ってみました。

・Objective-C
束縛ウォッチ(AppleWatch側の実装例)

※Swiftでのサンプルは結構多い印象がありますね(Objective-Cは割と少なかったので今回はそっちで作成してみました)、Swiftでの実装例は後ほど移植して公開致します。

2.要点の解説(こんな感じで使う等)

WatchExtention側での実装に関して言えば、

  1. [self.(インスタンス名) (メソッド名):(引数)];

という感じの実装をすることが多いですね。
※APIのほとんどが基本的にはsetter系のメソッド(基本的にはWKInterfaceControllerを継承しての使用です)

今回のサンプルでは主にInterfaceObjectをメインに使っており、GlanceやNotificationはまだ実装していません。

今回はこのサンプルで、

  1. 画像の配置
  2. セグエを使わずに遷移する
  3. テーブル表示

の3点に関して、説明していければと思います。

[解説1: 画像の配置]

このあたりは基本的には今まで通りではあります。
ただしタッチイベント等は実装できない感じですので、ボタンの中に画像を当て込んであげる等の代わりなりそうな処理にしてあげる必要がありそうですね。

  1. NSString *donbeImageName = @"top.jpg";
  2. [self.sokubakuImage setImageNamed:donbeImageName];

この辺はまだまだ従来通りといった感じでしょうか。

[解説2: セグエを使わずに遷移する]

こちらは意外にも簡単に実装することができました。
第1引数は”Identifier”の値を入れてあげて下さい。
また第2引数のcontextの部分に渡したい値を設定してあげれば良いみたいです。

  1. [self pushControllerWithName:@"ThirdView" context:arrayObjectForSecond[targetIndex]];

今回のサンプルでは3画面あるのですが、2画面目⇒3画面目の遷移に関しては2画面目の値を3画面目に渡すという処理を行っています。

また、3画面目では実際に受け取った後の処理も記載していますので、参考になれば幸いです。

[3: テーブルビュー]

この部分は今までのアプリと少し異なった実装をしなければいけない部分です。
大きく違う部分としては、テーブルビュー内のグループ用にNSObjectを継承したクラスを作るという点です。

tableインスタンスを配置した後に、そのtableインスタンス内にlabelやImage等のお好みのインスタンスを配置してあげて下さい。

下記がコードの本アプリでの実装例になります。

[WKTableCell.h]

こちらはCtrl + ドラッグでインスタンスを配置しただけです。

  1. #import <WatchKit/WatchKit.h>
  2. #import <Foundation/Foundation.h>
  3. @interface WKTableCell : NSObject
  4. //ラベル(束縛される項目名)を表示するラベル
  5. @property (strong, nonatomic) IBOutlet WKInterfaceLabel *sokubakuName;
  6. //ラベル(束縛される時間)を表示するラベル
  7. @property (strong, nonatomic) IBOutlet WKInterfaceLabel *sokubakuTime;
  8. @end

[SecondInterfaceController.m]

テーブルビューの書き方は下記のようになります。
(今回はwillActive内に記載)

  1. counter = (int)arrayObjectForLabel.count;
  2. [self.sokubakuTable setNumberOfRows:counter withRowType:@"cell"];
  3. //テーブルビューを表示する
  4. for (int i = 0; i < self.sokubakuTable.numberOfRows; i++) {
  5.     WKTableCell* theRow = [self.sokubakuTable rowControllerAtIndex:i];
  6.     [theRow.sokubakuName setText:arrayObjectForLabel[i]];
  7.     [theRow.sokubakuTime setText:arrayObjectForTime[i]];
  8. }

テーブルビューのセル選択時のメソッドは下記のようになります。

  1. - (void)table:(WKInterfaceTable *)table didSelectRowAtIndex:(NSInteger)rowIndex {
  2.     int targetIndex = (int)rowIndex;
  3.     [self pushControllerWithName:@"ThirdView" context:arrayObjectForSecond[targetIndex]];
  4. }

ThirdViewControllerには、実際のタイマーの処理が記載してあります。

少し解説が甘い部分もあるかと思いますが、ご参考になれば本当に嬉しい限りです。