Apple Watch: sendMessage/didReceiveMessageで混乱する
WatchConnectivityの送信側のsendMessage(_:replyHandler:errorHandler:)
と、受信側のsession(_:didReceiveMessage:replyHandler:)
の利用部分の処理を改めて見直していて、混乱しました。
Apple Watch→iPhoneに送信するとして、送信側で指定したreplyHandler
クロージャが、アーキテクチャも違うのにどうやって受信側のreplyHandler
として渡ってくるの?という疑問です。
何のことはない、同じ名前ですが違うものでした。
sendMessage
のmessage
と、didReceiveMessage
のmessage
は同じですが、replyHandler
は全く違います。
送信側のreplyHandler
にnilではなく(応答データ処理用)クロージャ(a)を渡すと、受信側のreplyHandler
に(WatchConnectivity標準の)返信用データ送信用クロージャ(b)が渡ってきます。
(a)は自分で書きますが、(b)は自分で書いたものではありません。
受信側では必ずreplyHandler
を呼べ、ということだったので何の気なしに呼んでいましたが、よくよく見直したときにそもそも何なんだこれは?となってちょっと混乱した、という話でした。
ちなみに、送信側でreplyHandler
にnilを渡すと、受信側はsession(_:didReceiveMessage:replyHandler:)
ではなくreplyHandler
のないsession(_:didReceiveMessage:)
のほうが呼ばれます。
(ということになっていますが、replyHandler
をnilにすると動かないという情報もあります。検証はしてません)
ちなみに、送信側で
replyHandler
にnilを渡すと、受信側はsession(_:didReceiveMessage:replyHandler:)
ではなくreplyHandler
のないsession(_:didReceiveMessage:)
のほうが呼ばれます。
(ということになっていますが、replyHandle
rをnilにすると動かないという情報もあります。検証はしてません)
この、replyHandler:
のないほうをSwift Concurrencyでasyncに書き換えようとしましたが、これダメですね。
sendMessage
のerrorHandler:
はエラーがあれば非同期で後から呼ばれてしまうので、エラーがないときにどうなるのかというと、たぶんreplyHandler:
がないと正常に終わったか分からない。
replyHandler:
のない版は、もう放り投げて終わり、届いたかどうかも気にせず、エラーがあってもどうでもいい(少なくともそこでリカバリとかはしない)、というぐらいのケースにしか使えないように思えます。
sendMessageのerrorHandler:はエラーがあれば非同期で後から呼ばれてしまうので、エラーがないときにどうなるのかというと、たぶんreplyHandler:がないと正常に終わったか分からない。
Swift Concurrencyだと、正常時にcontinuation.resume()を呼んでやる必要がありますが、それを呼ぶタイミングがありません。