koogawa blog

iOS、Android、foursquareに関する話題

watchOS 2 の Watch Connectivity を使ってみた

※本記事は、 一般に公開されている情報を元に作成しています。

watchOS 2から Watch Connectivity が使えるようになりましたね。

Watch Connectivityとは

image

Watch Connectivity Framework Referenceより引用)

The Watch Connectivity framework (WatchConnectivity.framework) provides a two-way communications conduit between an iOS app and a WatchKit app on a paired Apple Watch. Apps use this framework to pass files and data back and forth. Live communication is possible when both apps are active; otherwise, you send data in the background so that it is available when the other app launches.

つまり、iPhoneApple Watch 間で、双方向にデータを送受信することが可能になります。

Watch Connectivityには、大きく分けて Background transfersInteractive messaging の二種類が存在します。

Background transfersの特徴

  • すぐにデータが転送されるわけではない
  • 転送のタイミングはOSがよしなに決めてくれる
  • データは転送する前にキューイングされる

Interactive messagingの特徴

  • データは即座に転送される
  • 双方向のデータ送受信が可能
  • Watch App、iOS Appが通信可能状態(reachable)である必要がある

Session

データを受け取る側は準備が必要です。

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

最初に isSupported メソッドで、デバイスWatch Connectivityに対応してるかを確認します。その後、WCSession オブジェクトを作ってデリゲートをセットし、セッションを開始します。

Background transfers

Background transfersには次の3つの転送方法が存在します。

1. Application Context

  • 転送するデータはキューイングされ、待ち状態になる
  • 新しいデータがキューに追加されると古いデータは上書きされる
  • 結果的に最新のデータのみが転送されることになる
  • 全てのデータを完全に送る必要がないときに便利
// 送信側
NSDictionary *applicationDict = @{@"hoge" : @"huga"};
[[WCSession defaultSession] updateApplicationContext:applicationDict error:nil];
// 受信側
- (void)session:(nonnull WCSession *)session
 didReceiveApplicationContext:(nonnull NSDictionary<NSString *,id> *)applicationContext
{
    // 処理
}

2. User Info Transfer

  • Application Contextとは違い、データは上書きされない
  • すべてのデータを転送する必要がある時に便利
// 送信側
[[WCSession defaultSession] transferUserInfo:applicationDict];
// 受信側
- (void)session:(nonnull WCSession *)session
 didReceiveUserInfo:(nonnull NSDictionary<NSString *,id> *)userInfo
{
    // 処理
}

3. File Transfer

  • ファイルの転送が可能
// 送信側
NSURL *url = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"marimo" ofType:@"png"]];
WCSessionFileTransfer *fileTransfer = [[WCSession defaultSession] transferFile:url
                                                                          metadata:self.applicationDict];

送信待ちのファイルは outstandingFileTransfers プロパティで確認できる。

// 受信側
- (void)session:(nonnull WCSession *)session
 didReceiveFile:(nonnull WCSessionFile *)file
{
    // 処理
}

Interactive messaging

  • リアルタイムのデータ送受信が可能
  • iPhoneApple Watchがペアリングされている必要がある
  • iOS App/Watch Appがフォアグラウンドである必要がある

最初に、相手側のデバイスと通信可能であることを確認します。

if ([[WCSession defaultSession] isReachable]) {

reachableであれば、通信を開始します。

// 送信側
[[WCSession defaultSession] sendMessage:self.applicationDict
                           replyHandler:^(NSDictionary *replyHandler) {
                               // do something
                           }
                           errorHandler:^(NSError *error) {
                               // do something
                           }
 ];
// 受信側
- (void)session:(nonnull WCSession *)session
 didReceiveMessage:(nonnull NSDictionary<NSString *,id> *)message
 replyHandler:(nonnull void (^)(NSDictionary<NSString *,id> * __nonnull))replyHandler
{
    // 処理
}

サンプルコード

Objective-Cですが、簡単なサンプルコードを書きました。

https://github.com/koogawa/WatchConnectivitySample

どなたかSwift版を作ってくださいm( )m

リンク