[watchOS 2][iOS 9] Watch Connectivity で情報をやりとりする様々な方法

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

概要

※追記(2015/07/22)図を追加しました

watchOS 2 では、Apple Watch と iPhone 間で情報をやりとりする方法として、Watch Connectivity フレームワーク が新たに用意されています。

具体的には、WCSession クラス を用います。今回は、データの送受信に使われる様々なメソッドとその使用方法をご紹介します。

準備

#import <WatchConnectivity/WatchConnectivity.h>

WatchConnectivity/WatchConnectivity.h をインポートしておきます。

@interface ViewController () <WCSessionDelegate>

WCSessionDelegate プロトコルの採用を宣言しています。

if ([WCSession isSupported]) {
    WCSession *session = [WCSession defaultSession];
    session.delegate = self;
    [session activateSession];
}

WCSession のインスタンスを作成し、デリゲートのアサインをします。

activateSession により、Apple Watch と iPhone 間で情報のやりとりが有効化されます。

Application Context

Screen Shot 2015-07-22 at 14.54.31

updateApplicationContext:error:

[[WCSession defaultSession] updateApplicationContext:self.dic error:nil];

session:didReceiveApplicationContext:

- (void)session:(nonnull WCSession *)session didReceiveApplicationContext:(nonnull NSDictionary<NSString *,id> *)applicationContext{
    // applicationContext を使った処理など
}

updateApplicationContext:error: 並びに session:didReceiveApplicationContext: は、Watch 側、または iOS デバイス側が目覚めた時、各種状態をアップデートするために使用する想定で用意されています。

実際には、辞書データがやりとりされます。新しい辞書データを送信すると、以前に送信した辞書データは上書きされます。

即座にデータをやりとりする

sendMessage:replyHandler:errorHandler:

[[WCSession defaultSession] sendMessage:self.dic replyHandler:^(NSDictionary<NSString *,id> * __nonnull replyMessage) {
    // replyMessage を使った処理など        
} errorHandler:^(NSError * __nonnull error) {
    // エラー処理
}];

sendMessageData:replyHandler:errorHandler:

[[WCSession defaultSession] sendMessageData:data replyHandler:^(NSData * __nonnull replyMessageData) {
    // replyMessageData を使った処理など        
} errorHandler:^(NSError * __nonnull error) {
    // エラー処理
}];

session:didReceiveMessage:replyHandler:

- (void)session:(nonnull WCSession *)session didReceiveMessage:(nonnull NSDictionary<NSString *,id> *)message replyHandler:(nonnull void (^)(NSDictionary<NSString *,id> * __nonnull))replyHandler
{
    // message, replyHandler を使った処理など
}

session:didReceiveMessageData:replyHandler:

- (void)session:(nonnull WCSession *)session didReceiveMessageData:(nonnull NSData *)messageData replyHandler:(nonnull void (^)(NSData * __nonnull))replyHandler
{
    // messageData, replyHandler を使った処理など    
}

辞書データや NSData を送受信するサンプルコードです。

  • 即座にメッセージやデータを送信するときに使われます。

  • Watch 側アプリと iOS デバイス側アプリの双方がアクティブである必要があります。

辞書データをやりとりする

Screen Shot 2015-07-22 at 14.38.12

transferUserInfo:

[[WCSession defaultSession] transferUserInfo:self.dic];

session:didReceiveUserInfo:

- (void)session:(nonnull WCSession *)session didReceiveUserInfo:(nonnull NSDictionary<NSString *,id> *)userInfo{
    self.str = [NSString stringWithFormat:@"%@", [userInfo objectForKey:@"key1"]];
    [self.label setText:self.str];
}

辞書データをバックグラウンドで送受信するサンプルコードです。

  • transferUserInfo:updateApplicationContext:error: と違い、新しく辞書データを送った場合も以前送ったものを上書きせず、待ち行列にデータが追加され、順次送信されます。

  • transferUserInfoself.dic を送信し、session:didReceiveUserInfo で辞書データのキーを指定して、文字列データを取り出し、UILabel にセットしています。

ファイルをやりとりする

transferFile:metadata:

NSURL *url = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"strawberry" ofType:@"jpg"]];
[[WCSession defaultSession] transferFile:url metadata:self.metadataDic];

session:didReceiveFile:

- (void)session:(nonnull WCSession *)session didReceiveFile:(nonnull WCSessionFile *)file {
    NSData *data = [NSData dataWithContentsOfURL:[file fileURL]];
    self.image = [UIImage imageWithData:data];
    [self.imageView setImage:self.image];
}

jpeg ファイルをバックグラウンドで送受信するサンプルコードです。

  • transferFile:metadata:strawberry.jpgmetadataDic (ファイルのメタデータを含んだ辞書データ)とともに送信しています。
  • session:didReceiveFile: ではデータを受信した後、self.imageViewsetImage を呼んで、画像を表示する処理を行っています。

まとめ

いかがだったでしょうか。

watchOS 2 / iOS 9 では、コレまでに比べ、格段に Apple Watch と iPhone 間での情報のやりとりがしやすくなりました。

今回ご紹介した方法などを駆使して、楽しくアプリを作っていきましょう!

クレジット

図中の Apple Watch イメージは 無料ベクター素材その3)Apple Watch vector graphics | のんびりデザイン。しているような。 より頂きました!