Quantcast
Channel: shin – bmblog
Viewing all articles
Browse latest Browse all 94

iOS9 / watchOS9間の通信 Watch Connectivityで小ハマり

$
0
0

既存アプリのiOS9,watchOS2対応をぼちぼちと。
swift1.2 -> swift2へのconvertもあるので細かくあれこれ時間がかかる。

watchOS2では、いままでのwatchKitではiOSアプリとwatchアプリの通信に使っていた
– openParentApplication:reply:
が無くなってしまったので新しいAPI Watch Connectivity で実装し直す

– openParentApplication:reply: ではwatch側からiOS側へconnectionを開くことしかできない(iOS側から通信を開始できない)が、WCSessionでは双方ともに可能。
おかげでだいぶコードがすっきりする。

準備

delegateの宣言

iOS側のWatch Connectivityを使うクラスの宣言を以下の様に(太字部分追加)

class ViewController: UIViewController, WCSessionDelegate

watch ExtensionのWatch Connectivityを使うクラスの宣言を以下の様に(太字部分追加)

class InterfaceController: WKInterfaceController, WCSessionDelegate

両方とも
import WatchConnectivity
を忘れないように。

データを受信するためにセッションを開始する

例えばiOS側のViewControllerで使う場合、viewDidLoadの最後あたりで、以下の様にしてセッションを開始する

if (WCSession.isSupported()) {
  let session = WCSession.defaultSession()
  session.delegate = self
  session.activateSession()
}

watch Extension側でも同様に例えばWKInterfaceControllerで使う場合、willActivateの最後あたりに同じコード追加。

ハマったのはここ。
実装したかったのは片方向(iOS -> watch)の通信のみだったので受信側(watach)のみでこのコードを実装したが、iOS側からwatchを見つけられない(後述の WCSession.defaultSession().reachable がfalse になる)。
送信側にも通信が始まる前にこのコードが実行されるようにコードを追加する必要がある
openParentApplication:replyのイメージが強くて、勝手にサーバクライアントのようなモデルを想定してしまったのが失敗。

通信開始

WCSessionの通信にはすぐに通信が開始されるInteractive messagingと、機嫌が良いときに通信しておいてくれるBackground transfersがある。Interactive messagingの場合は、iOSからwatchに送信する場合はwatchOS上でアプリが起動している必要がある。

今回はInteractive messagingを例に。

送信側:

if WCSession.defaultSession().reachable { //通信可能かチェック
  var message:[String: AnyObject] = ["message": "Message From Phone" ]
  WCSession.defaultSession().sendMessage(message, replyHandler: { (replyMessage) -> Void in
    //
  }) { (error) -> Void in
    print(error)
  } 
}

受信側(delegateのメソッド実装):

func session(session: WCSession, didReceiveMessage message: [String : AnyObject], replyHandler: ([String : AnyObject]) -> Void) {
  if let tmessage:String? = message["message"] as! String? {
    print(tmessage)      
  }
}

messageが[String: AnyObject]となっていることから分かるように、String以外も送信可能。
簡単に双方向通信ができる様になった。
MMWormhole要らなくなりそうだ。
(いままで(watchOS1で)動いていたMMWormholeのコードがwatchOS2のシミュレータでは動かなかった。コンパイルも通りエラーも出ないが、受信してくれず。)


Viewing all articles
Browse latest Browse all 94

Trending Articles