2015年3月24日火曜日

Apple Watch向けWatchKitアプリの作り方講座

はじめに

Xcode6.2よりWatchKitのAPIが一般向けに公開され、シミュレータ上で誰でもApple Watch向けアプリが開発できるようになりました。

開発するための情報が未だ少ないですが、既にアプリ開発に取りかかっている開発者も多いようです。
今回は、WatchKitアプリを全く開発したことが無いiOS開発者向けに、WatchKitアプリ作成のチュートリアルを行います。

対象

iOSアプリを少しでも作成したことのある人
言語はSwiftを使用しますが、objective-Cでもやり方に大きな違いはありません

つくるもの

GitHub上に、WatchKitのサンプルアプリが公開されています。
今回はこちらのアプリを参考に、WatchKitアプリの作成方法を順番に説明していきたいと思います。
https://github.com/kostiakoval/WatchKit-Apps

リポジトリ内には、シチュエーションに合わせた機能ごとにサンプルが用意されています。今回作成していくサンプルアプリは3. AppsCommunicationです。

ペアリングされたApple WatchとiPhone間で、AppleWatch上で押したボタンに応じてiPhoneにアクションが送れる、というアプリです。

作成手順

概要

作成手順を示します。
1. iPhoneアプリを作成する
2. iPhoneアプリと連携するWatchKitアプリをTargetとして追加する
3. [iPhone側実装] Apple Watchでボタンを押したときの処理を設定する
4. [iPhone側実装] Apple Watchからのアクションを受け取る処理を設定する
5. [WatchKit側実装] ボタンのUIを設定する
6. [WatchKit側実装] ボタンを押したときのiPhoneへのアクションの送信処理を設定する

1. iPhoneアプリを作成する

WatchKitアプリはApple Watch上で単独で起動するアプリではありません。
iOSアプリの拡張機能として提供されます。開発方法も、Xcode上でiOSアプリにTargetを追加する形で実装していきます。
作成したWatchKitアプリは、App StoreからiOSアプリをインストールした際に、ペアリングしたApple Watchにインストールされます。

File -> new -> ProjectからiOSアプリを作成します。

TemplateはiOS -> Application -> Single View Applicationとします。
Product NameはMyAppsCommunicationとします。
言語はSwiftを選択します。Core Dataは使用しません。

2. iPhoneアプリと連携するWatchKitアプリを作成する

WatchKitのTargetを追加することで、既存のiOSアプリをApple Watch向けに拡張することが出来ます。
File -> New -> TargetからTargetを追加します。
TemplateはiOS -> Apple Watch -> WatchKit Appとします。
言語はSwiftです。
Include Notification Sceneにチェックが入った状態で、Finishします。
Include Notification Sceneについては、Apple Watch Programming Guideに書かれている通り、Notification機能を使用するつもりが無くてもチェックを入れることが推奨されています。

引用:

If you plan to implement a glance or custom notification interface, select the appropriate checkboxes.
For notification interfaces, it is recommended that you select the Include Notification Scene checkbox, even if you do not plan on implementing that interface right away. Selecting that checkbox adds an additional file to your project for debugging your notification interfaces. If you do not select that option, later you must create the file manually.

Activate “MyAppsCommunication WatchKit App” scheme?のダイアログに対しては、Activateします。

3. [iPhone側] アクションを受け取ったときのViewの更新を設定する

Apple Watch上でボタンを押したときに、iPhone画面上のラベルの文字が変わる、という機能を想定します。

Templateとして作成されているViewControllerに、
・ラベル
・ラベルの文字を変えるメソッド
をそれぞれ実装しましょう。

Main.storyboardとViewController.swiftを2つ開きます。
ファイル名をダブルクリックするなどして、同時に2つのウィンドウが見えるようにしましょう。

Main.storyboard上でViewControllerの画面中央にLabelを配置します。
右下のウィンドウからLabelをドラッグすることで配置できます。Label領域は広めに取りましょう。

storbyboard上で配置したLabelを選択し、ViewControllerのソースコードにOutletの参照を作成します。参照の名前はlabelとします。

ViewController上にlabelの文字を変更するメソッドを追加します。

// ViewController
    @IBOutlet weak var label: UILabel!
    func changeLabel(text: String) {
        label.text = text
    }
4. [iPhone側] Apple Watchからのアクションレシーバーを設定する

AppDelegate.swiftを編集します。
以下の処理を追加します。

// AppDelegate.swift
    func application(application: UIApplication!, handleWatchKitExtensionRequest userInfo: [NSObject : AnyObject]!, reply: (([NSObject : AnyObject]!) -> Void)!) {

        if let info = userInfo as? [String: String] {
            let VC = window?.rootViewController as ViewController
            VC.changeLabel(info["label"]!)
            reply(["response" : "success"])
        } else {
            reply(["response" : "failed"])
        }

    }

WatchKitから受け取った処理を設定するためのデリゲートメソッドはhandleWatchKitExtensionRequestで設定できます。

ポイント1
if let info = userInfo as? [String: String] {
} else {
}

この書き方はswiftでよく使う定型句です。
optional型の値をlet定数に入れてif分で評価することで、nil値の評価を行っています。userInfoの値がnilで無かったときはif ~ elseでinfo変数として使用できます。

ポイント2

userInfo、つまりWatchKitから受け取った値がnilでなかった時は、ViewControllerのchangeLabelメソッドを呼び出し、画面上の文字を変えます。画面上に表示する文字は、WatchKitから受け取ります。

ポイント3

replyはWatchKitからのcallback関数です。
reply関数が呼ばれなかった場合、WatchKit側でwarningが出るため、呼ぶようにしましょう。
引数を空データにしたければ、

reply([NSObject : AnyObject]())

とすればOKです。
今回は、処理の成功/失敗を引数に与えています。

5. [WatchKit側] ボタンのUIを設定する

ソースコードの構成を見てみましょう。
WatchKitのTargetを追加することで、以下の2つのグループが追加されました。
・MyAppsCommunication WatchKit Extension
・MyAppsCommunication WatchKit App

WatchKitのアプリの構造は大きく2つに分かれます。

WatchKit Extension
WatchKitの動的な処理を行います。iOSアプリと同じようにコントローラを実装します。
余談ですが、一見Apple Watch上で全ての処理を行っているように思われがちですが、WatchKit ExtensionはiPhone側にインストールされます。
WatchKit App
Apple WatchにインストールされるUIです。ボタンの配置・画面遷移などを構築していきます。
UIの構築はstoryboard上で行っていきます。
iOSアプリではinterface builder(GUI)でもaddSubviewメソッド(CUI)でもどちらでもUIの構築を行えました。
しかしWatchKitではaddSubviewのようなCUIベースでのUI構築は行えません(2015年3月現在)。

さて、UIを構築していきます。
まずInterface.storyboardを開きます。
ボタンを3つ追加します。やりかたはiOSアプリのときと同じです。

Mainという矢印のついたビューに対して、Buttonを3つ追加します。

6. [WatchKit側] ボタンを押したときのiPhoneへの送信処理を設定する

3つのボタンについて、Interface.storyboardからInterfaceController.swiftに対しアクションの参照を追加します。
アクションの名前はbutton1Tapped, button2Tapped, button3Tappedとしました。

さらに、WKInterfaceController.openParentApplicationメソッドでiOSアプリにアクションの通知を送ります。

Main.storyboardとViewController.swiftのときと同じ具合です。

// InterfaceController
    @IBAction func butotn1Tapped() {
        buttonTapped("button1")
    }

    @IBAction func button2Tapped() {
        buttonTapped("button2")
    }

    @IBAction func button3Tapped() {
        buttonTapped("button3")
    }

    func buttonTapped(label: String) {
        var userInfo = ["label": label]
        WKInterfaceController.openParentApplication(userInfo, reply: {
            (data, error) in
            if let error = error {
                println(error)
            }
            if let data = data {
                println(data)
            }
        })
    }

実装はこれで終了です。

起動

準備

Xcodeシミュレータで実際に動かしてみましょう。

TargetをMyAppsCommunication WatchKit Appに変更します。
ちなみにCommand + control + [でTargetの切り替えが出来ます。
同様にCommand + Rで起動しましょう。

iPhoneのシミュレータとApple Watchのシミュレータが同時に起動します。
もしApple Watchのシミュレータが起動しなければ、
メニューのHardware -> External Displays -> Apple Watchを選択するとシミュレータ画面が追加されます。

起動直後は
iPhoneは、ホーム画面にMyAppsCommunicationアプリがインストールされた状態
Apple Watchはボタンが3つ表示された状態
になるはずです。

iPhone側で、MyAppsCommunicationを選択してアプリを起動します。

デモ

Apple Watch上のボタンを好きに押してみましょう。
iPhone側でのLabelの文字が切り替わる筈です。

補足:デバッグについて

TargetをiOSアプリにすると、iOSアプリのみのデバッグ、
TargetをWatch Appにすると、WatchKitアプリのみのデバッグになります。

iOS, WatchKitの2つを同時にデバッグする方法が以下に紹介されています。
https://mkswap.net/m/blog/How+to+debug+an+iOS+app+while+the+WatchKit+app+is+currently+running+in+the+simulator
やり方は次の通りです。

  1. TargetをWatch Appにして、インストールする
  2. iPhone側でアプリを起動する
  3. アクティブウィンドウをXcodeに戻す
  4. Debug -> Attach to ProcessからMyAppsCommunicationアプリのプロセスを選択する

これで同時にデバッグすることができます。どちらのソースコードについても、ブレークポイントを貼ることができるようになります。

できあがったアプリはこちら
https://github.com/takanori-matsumoto-mulodo/MyAppsCommunication

0 件のコメント :

コメントを投稿