プログラムの事とか

お約束ですが「掲載内容は私個人の見解です」

XamarinでApple Watchアプリを作る(その4)- iPhoneとのやりとり

母艦(iPhone)側アプリとのやり取りをしてみます。

適当に調べたんですが、iPhone - Watch のやり取りはWatchがトリガーになるしかなさそうです。(iPhone側から能動的にデータを送ることはできないっぽい?)

これまたXamarinのオンラインドキュメントをほとんど写してます。

Watch側

WKInterfaceController.OpenParentApplication(NSDictionary userInfo,Action<NSDictionary, NSError> reply)

を使います。 第一引数にiPhone側アプリに渡したいデータを入れます。 第二引数は応答受信時のコールバックですね。

前回のコードをいじって、入力された文字列をいったん母艦に渡してその応答をラベルに出力するように変更します。

partial void Button1_Activated() => this.PresentTextInputController(new[] { "Yes", "No", "Maybe" }, WKTextInputMode.Plain, delegate (NSArray results) {
    if (results?.Count > 0)
    {
        WKInterfaceController.OpenParentApplication(new NSDictionary("input", results.GetItem<NSObject>(0).ToString()), (replyInfo, error) => {
            if (error != null)
            {
                this.label1.SetText(error.ToString());
                return;
            }

            var result = ((NSString)replyInfo["result"]).ToString();
            this.label1.SetText(result);
        });
    }
});

NSDictionaryに"input"というパラメーターを突っ込んであとは応答を待ちます。

iPhone

UIApplicationDelegate.HandleWatchKitExtensionRequest(UIApplication application, NSDictionary userInfo, Action<NSDictionary> reply))

をoverrideするとWatchからのリクエストを受け取れます。 第二引数はWatchから渡されるパラメーターです。 第三引数を呼ぶとWatch側のコールバックが呼ばれます。

入力文字列に文字列を追加して返すようにしてみます。

public override void HandleWatchKitExtensionRequest(UIApplication application, NSDictionary userInfo, Action<NSDictionary> reply)
{
    var input = ((NSString)userInfo["input"]).ToString();
    var result = "Your input is " + input;
    reply(new NSDictionary("result", result));
}

試してみる

Watchのシミュレーターで実行してみます。

f:id:puni-o:20160115161315g:plain

やったね。

不思議なのはiPhone側のアプリを起動していないというところです。 てっきりエラーが出るんだと思ってWatch側単体で動かしたら普通に動いてしまいました。

やり取りできるデータ型にはNSData型もあるので画像なんかも送れますよ。