WonderPlanet DEVELOPER BLOG

ワンダープラネットの開発者ブログです。モバイルゲーム開発情報を発信。

WatchKitでWatchAppからiPhone側のアプリを操作する

今回のエンジニアブログ担当の近藤です。

このページを見ている皆さんはもちろんApple Watchは手に入れましたよね?w
まだ発売して2ヶ月ほどですが、さっそく先日のWWDCでwatchOS 2の発表がありました。
現状ではiPhone側のアプリとセットで動かすことが前提でしたが、AppleWatch単体での動作できるようになるなど、いろいろ期待大です。
現行バージョンでいろいろもどかしい思いをしていた部分が解消されていくと良いですね。

さて、今回はそんなもどかしい思いをしている機能の紹介です。
以前の記事で紹介したとおり、WatchAppとiPhoneアプリをセットで開発し、プログラムの処理自体はiPhoneアプリ(親アプリ)側で行い、その結果をWatchApp側で表示させる仕組みになっています。
お互いにやりとりするための機能がWatchKitに備わっているので、それらの機能を動かしてみましょう。

openParentApplication:reply:メソッド

WatchApp側のInterfaceControllerから「openParentApplication:reply:」メソッドを実行すると、
iPhoneアプリ側のAppDelegateの「handleWatchKitExtensionRequest:」メソッドを呼び出すことができます。
handleWatchKitExtensionRequestメソッドで、ViewControllerやUIViewクラスなどの部品に何かしらの動作をさせることで、WatchAppからiPhoneアプリを操作できます。
では実装作ってみましょう。

プロジェクト作成

以前の記事を参考にプロジェクトを作りましょう。

InterfaceController

Storyboadでラベルとボタンを配置しておきます。
ボタンにはtapButtonメソッドをIBActionでつなげておきます。
labelはIBOutletでつなげておきましょう。
labelにはiPhoneアプリから返ってきた値をWatchApp側のラベルに表示するようにします。

#import "InterfaceController.h"  
@interface InterfaceController()  
@property (weak, nonatomic) IBOutlet WKInterfaceLabel *label;  
@end  
  
int count;  
@implementation InterfaceController  
- (IBAction)tapButton {  
  
    //iPhoneアプリに送るデータを設定  
    NSDictionary *applicationData = @{@"message":@"AppleWatchのボタンをタップしました"};  
  
    //iPhoneアプリを呼び出す  
    [WKInterfaceController openParentApplication:applicationData reply:^(NSDictionary *replyInfo, NSError *error) {  
        //iPhoneアプリから返ってきたデータを表示  
        [_label setText:[replyInfo objectForKey:@"reply"]];  
    }];  
}  
  
- (void)awakeWithContext:(id)context {  
    [super awakeWithContext:context];  
  
    // Configure interface objects here.  
}  
  
- (void)willActivate {  
    // This method is called when watch view controller is about to be visible to user  
    [super willActivate];  
}  
  
- (void)didDeactivate {  
    // This method is called when watch view controller is no longer visible  
    [super didDeactivate];  
}  
  
@end  

InterfaceController

AppDelegate.mにはhandleWatchKitExtensionRequestメソッドを追加します。
WatchApp側で「openParentApplication:applicationData」が実行された時にこのメソッドが呼び出されます。
replyでWatchApp側にNSDictionaryで値を返すことができます。
呼び出されたらWatchAppから送られてきたメッセージをアラート表示するようにしています。

-(void)application:(UIApplication *)application handleWatchKitExtensionRequest:(NSDictionary *)userInfo reply:(void (^)(NSDictionary *))reply{  
      
    //送られてきたdictionaryのデータを取り出す  
    NSString *message = [userInfo objectForKey:@"message"];  
      
    //WatchAppに返すデータを作成  
    NSDictionary *applicationData = @{@"reply":@"ダイアログを表示しました"};  
    reply(applicationData);  
      
      
    //アラート表示  
    UIAlertController *ac = [UIAlertController alertControllerWithTitle:@"Message"  
                                                                message:message  
                                                         preferredStyle:UIAlertControllerStyleAlert];  
    UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"OK"  
                                                       style:UIAlertActionStyleDefault  
                                                     handler:^(UIAlertAction *action) {  
                                                           
                                                           
                                                     }  
                               ];  
    [ac addAction:okAction];  
    [self.window.rootViewController presentViewController:ac animated:YES completion:nil];  
}  
  

実行結果

WatchAppに配置したボタンをタップすると、iPhoneアプリ側でダイアログが表示されます。
そしてWatchApp側に帰ってきたメッセージをラベルに表示しています。
IMG_1582 IMG_1581

これで、WatchAppからiPhoneアプリに値を渡し、iPhoneアプリ側からreplyでWatchアプリに値を返すことができるようになりました。
今回は文字列の値を送って表示するだけでしたが、これらの機能を駆使すれば、カメラを起動してシャッターを切ったり、音楽を再生・停止をさせることもできるようになります。
handleWatchKitExtensionRequestが呼び出すことができればiPhoneアプリ側の実装で各種機能を呼び出すことができるようになるはずです。
これらの機能を駆使していろんなアプリのアイデアも浮かんで来るのではないでしょうか?

watchOS 2も発表され、今後もいろんな機能が増えてくると思います。
これからもAppleWatchの動向を追いかけて行きます。