iOS←→watchOSの通信(watchOS2以降)

iOSとwatchOSで通信します。
watchOS2以降はwatchkit ExtensionはwatchOS側で動作します。
そのため、watchkitExtension内でiOS側の機能は使えません。iOS側で処理をやってwatchOSに送信(またはその逆)というスタイルになります。

まずは準備。

バックグラウンド処理の戻りはデリゲートメソッドに返ってきます。そのため、AppDelegateやExtensionDelegateにデリゲートを設定するのがよいです。

【AppDelegate.h、ExtensionDelegate.h】
#import <WatchConnectivity/WatchConnectivity.h>
@interface ExtensionDelegate : NSObject <WKExtensionDelegate,WCSessionDelegate>

【AppDelegate.m、ExtensionDelegate.m】
・applicationDidFinishLaunching内に以下のWCSessionの初期化処理を入れます。
    if([WCSession isSupported]){
        WCSession *session=[WCSession defaultSession];
        session.delegate=self;
        [session activateSession];
    }


★リアルタイム通信
・sendMessage、sendMessageDataメソッド
・即実行される
・replyHandlerに戻りが返ってくる
・リアルタイム通信は送信前に[[WCSession defaultSession] isReachable]を使って、通信可能かどうかを確認する。
・sendMessageはNSDictionary(文字列だけ)、sendMessageDataはNSDataで送信する。

【例:sendMessageDataメソッドを使う】
    if([[WCSession defaultSession] isReachable]){
        NSData*sendData=[NSKeyedArchiver archivedDataWithRootObject:@{@”name”:@”value”}];
        [[WCSession defaultSession] sendMessageData:sendData replyHandler:^(NSData * _Nonnull replyMessageData) {
       //ここで処理する
        NSLog(@”%@”,[reply objectForKey:@”name”]);
        } errorHandler:^(NSError * _Nonnull error) {
       //こっちでエラー処理
        }];
    }


★バックグラウンド通信
・applicationContext、transferUserInfo、transferFileメソッド。
・即実行はされない。
・一旦キューに入って、OSが勝手に(都合いい時に)通信する
・戻りはデリゲートメソッドに返ってくる。そのため、AppDelegateやExtensionDelegateにデリゲートを設定するのがよい。

バックグラウンド処理の送信
【例:transferFileメソッドを使う】
NSStirng*filePath;
//filePathを設定しておく
[[WCSession defaultSession] transferFile:[NSURL fileURLWithPath:filePath] metadata:@{@”name”:@”value”}];

バックグラウンド処理の受信
//applicationContextの受信
– (void)session:(nonnull WCSession *)session didReceiveApplicationContext:(nonnull NSDictionary<NSString *,id> *)applicationContext{
    dispatch_async(dispatch_get_main_queue(), ^{
        //ここで処理する
    });
}

//transferFileの受信
-(void)session:(WCSession *)session didReceiveFile:(WCSessionFile *)file{
    dispatch_async(dispatch_get_main_queue(), ^{
       //ここで処理する
    });
}

//transferUserInfoの受信
– (void)session:(nonnull WCSession *)session didReceiveUserInfo:(nonnull NSDictionary<NSString *,id> *)userInfo
{
    dispatch_async(dispatch_get_main_queue(), ^{
       //ここで処理する
     });
}