簡単な Apple Watch アプリを初めて作ってみる

Apple Watch アプリプログラミング

Apple Watch アプリを作ってみようと思ったものの、どこから手をつけたらいいかわからなかったので、まずは起動して動かせるだけの簡単な Apple Watch アプリを作ってみることにしました。

Apple Watch 対応アプリのプロジェクトを作成する

Apple Watch アプリを作るには、その親になる iPhone アプリが必要になります。

その上で Apple Watch 上で動く WatchKit App を作成することになります。親アプリには WatchKit Extension を実装して、Apple Watch と iPhone とで情報をやり取りできるようになっています。

それぞれの役割を整理すると、次のようになる様子です。

ターゲット 役割
iPhone アプリ WatchKit Extension を内包して WatchKit App と通信を行うための親アプリです。
WatchKit Extension WatchKit App の画面をコントロールする機能を実装します。
WatchKit App Apple Watch に表示する画面を設計します。

iPhone アプリを作成する

それでは、まずは親になる iPhone アプリを作成します。

iPhone アプリの作り方は通常どおりです。好きな種類の iOS アプリケーションテンプレートを使用して、プロジェクトを作成します。

iOS アプリプロジェクトを作成するときの注意点としては、対象デバイスをiPhone にするところでしょうか。Universal でも構わないようですが、Apple Watch と連携できるのは iPhone だけになる様子です。

WatchKit App ターゲットを追加する

iPhone アプリのプロジェクトを作成したら、そこに WatchKit ターゲットを追加します。

プロジェクトエディターの追加ボタンから、Apple Watch のWatchKit App を選択します。

そして WatchKit App に関する情報を指定します。

ここでは既定の設定どおりで、基本的な Apple Watch アプリが追加される様子でしたので、今回はひとまずそのまま追加しておくことにしました。

なお、表示されている項目は、次のようなものがありました。

項目 用途
Product Name WatchKit App のプロダクト名です。変更はできない様子です。
Organization Name アプリ制作者の組織名を入力できます。
Organization Identifier アプリに設定されている App ID です。
Bundle Identifier WatchKit App に設定する識別子です。変更はできない様子です。
Language どの言語の WatchKit App や WatchKit Extension を作成するかを選択します。Objective-C と Swift とが選べます。
Include Notification Scene 作成する内容に Notification 画面を含めるかを選択します。
Include Glance Scene 作成する内容に Glance 画面を含めるかを選択します。
Project 作成する WatchKit App や WatchKit Extension をどのプロジェクトに登録するかを選択します。
Embed in Application 作成する WatchKit App と WatchKit Extension をどのアプリに組み込むかを選択します。

これらを指定してFinishボタン を押すことで、WatchKit App がプロジェクトに登録されます。

WatchKit App ビルドの準備

プロジェクトに WatchKit App ターゲットを登録したとき、次のようなメッセージが表示されることがあります。

ここでActivateボタン を押すことで、WatchKit App をビルドするためのビルドスキームに切り替わります。そうすることで、あとはいつものようにビルドやデバッグ実行を行うことで、すぐに WatchKit アプリの動作テストを行えます。

ここで Activate しなくても、Xcode のメニューバーにあるビルドスキームのリストから WatchKit App のスキームを選択できます。

Apple Watch プロジェクトの構成を知る

上記のようにして作成された Apple Watch プロジェクトは、次のようなファイル構成になっていました。

$(PROJECT_NAME)

プロジェクト名のすぐ下にあるプロジェクト名のグループフォルダーには、通常の iPhone アプリ関連のファイルが収められていて、既定ではこれらのファイルが iOS アプリのターゲットに組み込まれるようになっています。

構成は普段の iOS アプリと同じです。

$(PROJECT_NAME)Tests

続く、プロジェクト名 + "Tests" は、通常の iPhone アプリのテストコードです。既定ではこれらのファイルが iOS アプリ用のテストターゲットに組み込まれるようになっています。

構成は普段の iOS アプリと同じです。

$(PROJECT_NAME) WatchKit Extension

ここには、Apple Watch の画面に映し出されたものをコントロールするクラスのコードが配置されていました。

ファイル 用途
InterfaceController.swift WKInterfaceControllerクラス を継承したInterfaceControllerクラス が定義されています。Apple Watch アプリのメイン画面をコントロールするためのコードを実装します。
NotificationController.swift WKUserNotificationInterfaceControllerクラス を継承したNotificationControllerクラス が定義されています。Apple Watch アプリの通知画面をコントロールするためのコードを実装することになるようです。
Images.xcassets Apple Watch アプリ画面で使いたい画像のうち、WatchKit Extension 側で処理したいものを格納するアセットカタログです。ここに用意した画像は、WatchKit App 側に配置したコントロールの画像にsetImage:メソッド することで画像データを転送できるようです。
Supporting Files ここにはInfo.plist で、WatchKit Extension に関する情報が保存されています。また、Notification 機能で使うファイルでしょうか、PushNotificationPayload.apns というファイルも合わせて格納されていました。

$(PROJECT_NAME) WatchKit App

ここには Apple Watch 側に映し出す画面に関係するリソースが配置されていました。

ファイル 用途
Interface.storyboard Apple Watch 画面に表示するメイン画面や Notification などの画面がシーン として格納されています。画面のデザイン周りはここで設計することになります。
Images.xcassets Apple Watch アプリ画面で使いたい画像のうち、あらかじめ WatchKit App 側に転送しておきたいものを格納するアセットカタログです。ここに用意した画像はWKInterfaceImageクラスsetImageNamed:メソッド で読み込めるようです。Apple Watch に表示させたいアプリのアイコンもここに収めることになるようです。
Supporting Files ここにはInfo.plist で、WatchKit App に関する情報が保存されています。

Apple Watch アプリを実装する

それでは、今回は練習として Apple Watch に表示された画面を操作できるだけのアプリを作ってみます。

具体的には、画面上にラベルとスライダーを配置して、スライダーを操作するとその値がラベルに表示されるアプリを作ります。Apple Watch 側だけで動く簡単なアプリを作ることで、そもそも Apple Watch がどのようなものかを体験するとともに、WatchKit App と WatchKit Extension の役割分担を把握するのが狙いです。

WatchKit App の画面を設計する

まずは Interface Builder を使って、Apple Watch に表示する画面を設計しています。

画面を設計するのに使うファイルは、WatchKit App 用の "$(PROJECT_NAME) WatchKit App" フォルダーに配置されている Interface.storyboard です。

ここのInterface Controller Scene として用意されている画面に、WatchKit App のメイン画面として表示したいオブジェクトを配置して行きます。

今回は上記画像のように、いちばん上にラベル (WKInterfaceLabel) を配置して、その下に続けてスライダー (WKInterfaceSlider) を配置しておくことにしました。


それと、スライダーの取り得る値の範囲もここで設定しておくことにします。

スライダーの設定は、Interface Builder でスライダーを選択した状態で、左側の属性インスペクターで設定します。

項目 意味
Value スライダーの初期値です。
Minimum スライダーの最小値です。
Maximum スライダーの最大値です。
Steps スライダーの値を、全体で見て何段階で動かせるかを指定します。
Continuous ここにチェックを入れると、スライダーを動かしたときに目盛りの動きがスムーズなアニメーションで見られるようになります。

今回は 0 から 500 までの範囲を採れるスライダーで、その中を 15 段階で動かせるように設定しました。


そしてスライダーの初期値の設定ですが、スライダーが表示している現在値はコードから取得することができないようです。画面上からスライダーを操作されたときにだけ、アクションを通して現在の値が通知されます。

今回は、スライダーの値とラベルの値とを連動させたいので、スライダーの初期値はコード内から指定することにします。

画面設計時は Apple Watch のサイズに注意

WatchKit App の画面設計は、サイズによって配置するオブジェクトや設定値を変えられるようになっています。

ここのAny Screen Size のところはボタンになっていて、クリックして切り替えられるようになっています。

項目 意味
Any Screen Size どのサイズの Apple Watch にも表示する画面を設計するモードです。
Apple Watch 42 mm 42 mm サイズの Apple Watch に表示する画面を設計するモードです。
Apple Watch 38 mm 38 mm サイズの Apple Watch に表示する画面を設計するモードです。

この設定を間違うと、オブジェクトを配置したつもりが、片方の Apple Watch にしか組み込まれないことになったりするので注意です。


なお、この設定は属性インスペクターでも調整できるようになっています。

たとえば、オブジェクトの設定の中にInstalled と書かれた場所があり、ここにチェックが入っていると、その画面に当該オブジェクトが組み込まれるようになります。

どの画面に対する設定なのかは、左側に記されています。左側に38mm とあれば Apple Watch 38 mm で表示されることを意味し、42mm であれば Apple Watch 42 mm で表示されることを意味しています。何も書かれていない場合は、どの画面にも組み込まれることを意味します。


同様に、属性インスペクターで設定できる各値も、サイズ毎に調整できるようになっています。

各項目の左側にあるボタン をクリックして、個別に調整したい対象サイズを選択すると、そのサイズ用の値を設定する枠が追加されます。

任意のサイズを意味するAny Screen SizeApple Watch 42 mm などの個別のサイズを意味するものの両方に値を設定すると、個別のサイズ用に設定した値が優先的に使用される様子です。

WatchKit Extension に画面をコントロールするためのコードを実装する

オブジェクトを配置したら、それをコントロールするためのコードを用意します。

コードは WatchKit Extension 上のクラスに実装することになるようです。

アウトレットを用意する

まずは、ラベルへの書き出しやスライダーの読み込みを行うために、それらと連結するアウトレットを用意します。

メイン画面のオブジェクトを扱うためのコードなので、メイン画面を担当しているInterfaceControllerクラス に実装するのが妥当でしょう。

このクラスの中に、@IBOutletディレクティブ 付きのインスタンス変数として、ラベル用の変数countLabel とスライダー用の変数countSlider を定義します。

class InterfaceController: WKInterfaceController {

	@IBOutlet weak var countLabel:WKInterfaceLabel!
	@IBOutlet weak var countSlider:WKInterfaceSlider!
}

カウントを保持する変数を用意する

そして、同じくInterfaceControllerクラス に、現在のカウントを保存するインスタンス変数を保存型プロパティで定義します。

class InterfaceController: WKInterfaceController {

	var count:Int32 = 0 {
		
		didSet {
			
			self.countLabel.setText(String(self.count))
		}
	}
}

このプロパティにはdidSet を用意して、値が設定されたときにその内容を画面上のラベル (countLabel) にも反映されるようにしておくことにします。

カウントに初期値を設定する

Apple Watch アプリを起動したときの、スライダーの初期値を設定しておきます。

画面に表示される直前にオブジェクトの状態を調整したい場合は、InterfaceController.swiftawakeWithContext:メソッド にコードを実装します。

class InterfaceController: WKInterfaceController {

	override func awakeWithContext(context: AnyObject?) {

		super.awakeWithContext(context)

		self.count = 100
		self.countSlider.setValue(Float(self.count))
	}
}

ここで変数count 変数に初期値を設定して、それをスライダーの設定値としても使用しています。

スライダーの設定値だけなら Interface Builder で設定する方法もありますが、WatchKit のスライダーに設定されている値はスライダーが指で操作されたときにしか得られないため、起動時にスライダーの値をラベルに書き込むことができません。そのため、今回のようにコードから値を設定する方法を採っています。

スライダーを操作したときにカウントを操作する

Apple Watch 上でスライダーを操作したときに、それが示す値をカウントに反映させるメソッドも定義しておきます。

WatchKit のスライダーは、値が変更されたときに、それをFloat型 で受け取るメソッドを呼び出してもらえるようにできるので、そのようなメソッドをひとつ定義しておきます。

class InterfaceController: WKInterfaceController {

	@IBAction func countSliderAction(value:Float) {
		
		self.count = Int32(value)
	}
}

内容としては、受け取ったFloat型 の値を、カウントを保持する変数と同じInt32型 に変換して、カウントを保持する変数に設定します。

なお、このメソッドは後で Interface Builder でスライダーに割り当てるので、ここで@IBActionディレクティブ を付与しておきます。

WatchKit App の画面と WatchKit Extension のコードを連携させる

必要なアウトレットやアクションのコードを用意したら、それを画面設計で配置したオブジェクトと連結します。今回は Interface Builder の接続インスペクターを使って連結することにします。

画面設計用のInterface.storyboard を開いたら、右側の接続インスペクターを使って、それぞれ次のように連結します。

アウトレット/オプション 接続先のオブジェクト
countLabel ラベル
countSlider スライダー
countSliderAction: スライダー

これで、画面上のオブジェクトとコード上のシンボルとが関連付けられました。

これでたとえば、画面上でスライダーが操作されたときにはcountSliderAction: に書いたコードが呼び出されるようになりますし、コード上でcountSlidesetValue:メソッド を実行して画面上のスライダーの状態を操作できるようになります。

Apple Watch アプリを実行してみる

これで、スライダーを操作してその値をラベルに表示するアプリが出来上がりました。作成した Apple Watch アプリは Xcode の iPhone シミュレーターを使って実行できます。

実行方法は通常通りです。スキーマが WatchKit App 用のものになっている状態でデバッグモードで実行します。

そうすると、iPhone シミュレーターと一緒に Apple Watch の画面が別ウィンドウで表示されます。

iPhone シミュレーターでは何も起動していないように見えますが、ここでも今回作った WatchKit App の WatchKit Extension がバックグラウンドで動作しています。

Apple Watch 画面ウィンドウが見当たらない場合

Apple Watch アプリを iPhone シミュレーターで実行してみても Apple Watch の画面ウィンドウが見当たらない場合には、iPhone シミュレーターのメニューから Window Apple Watch 42 mm のように辿ると見つけられます。

Apple Watch 画面ウィンドウを切り替える

そもそも Apple Watch の画面ウィンドウが表示されていない場合や、画面サイズを 38mm と 42mm とで切り替えたい場合には、iPhone シミュレーターのメニューにある Hardware External Displays から画面ウィンドウを表示できます。