Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

WCSession.sendMessageに潜む罠

More than 1 year has passed since last update.

はじめに

このエントリは iOS Advent Calendar 2018 の19日目の投稿です。(遅くなりましてすみません...)

当方iOSの技術者と言いながら最近iOSの開発があまりできていませんが、頑張って書いていきたいと思います!

やりたいこと

部長「iPhoneとApple Watchで何かしらのメッセージやりとりできるようにしてくんない?」
わたし「めんどくさ(わかりました)」

事の経緯

上記の通りiPhoneからApple Watchにメッセージを送る必要があった。
それっぽいリファレンスを発見できたので、軽い気持ちで見てみたらメソッドを見ていると以下のことがわかった。

  • メッセージは辞書型で必須
  • replyHandlerとerrorHandlerはnilが許容されている。(成功時/失敗時の処理はなくてもいい)
open func sendMessage(_ message: [String : Any], replyHandler: (([String : Any]) -> Swift.Void)?, errorHandler: ((Error) -> Swift.Void)? = nil)

なのでメッセージを送る時に以下のようにした。

ViewController.swift
self.session.sendMessage(
    ["message" : "7/25は高森藍子の誕生日!"],
    replyHandler: nil,
    errorHandler: { (error) in do {
        // エラー発生
        print(error)
    }}
)

そうすると警告文が発生していた。
どうやら実装に不備があったらしい。

2018-06-22 10:00:00.000000 SampleProject WatchKit Extension[17803:213358] [WC] -[WCSession _onqueue_notifyOfMessageError:withErrorHandler:] errorHandler: NO with WCErrorCodeDeliveryFailed

似たような事象にあっている人を見つけた。
Apple Watchで寿司をまわしてGetWildする
replyHandlerはnilを許容しているのに、nilを渡すと動かなくなるらしい。

以下のように実装したら無事送信が成功するようになった。
relpyHandlerがなんでnil許容してんだよ...

ViewController.swift
self.session.sendMessage(
    ["message" : "7/25は高森藍子の誕生日!"],
    replyHandler: { (reply) in do {
        // 空でもいいので置いとく必要があるがせっかくなのでお祝いしないと。
        print("藍子誕生日おめでとう!")
    }},
    errorHandler: { (error) in do {
        // エラー発生
        print(error)
    }}
)

Apple Watch側でもメッセージ受け取ったらreplayHandlerに何かしら返す必要がある。

AppleWatchViewController.swift
func session(_ session: WCSession, didReceiveMessage message: [String : Any], replyHandler: @escaping ([String : Any]) -> Void) {
    // nilを設定すると送り手側のreplyHandlerが呼ばれない=送信完了のステータスにならない。
    // replyHandler(nil)

    // なんでもいいから送っとけ
    replyHandler(["message" : "お祝いしないといけないね!"])
}

ソース全文

ViewController.swift
//
//  ViewController.swift
//  SampleProject
//
//  Created by satoshi baba <s_baba@currentia.co.jp> on 2018/12/15.
//  Copyright © 2018年 Currentia.inc. All rights reserved.
//

import UIKit
import WatchConnectivity

class ViewController: UIViewController {

    /// Apple Watchの接続用のセッション
    let session:WCSession = WCSession.default

    override func viewDidLoad() {
        super.viewDidLoad()
        self.initWCSession()
    }

    func initWCSession() {
        if WCSession.isSupported() {
            self.session.delegate = self
            self.session.activate()
        }
        else{
            // サポートされていない時の処理は省略
        }
    }

    func sendMessage() {
        DispatchQueue.main.async {
            self.session.sendMessage(
                ["message" : "7/25は高森藍子の誕生日!"],
                replyHandler: { (reply) in do {
                    // 空でもいいので置いとく必要がある。
                    print("藍子誕生日おめでとう!")
                }},
                errorHandler: { (error) in do {
                    // エラー発生
                    print(error)
                }}
            )
        }
    }
}

extension ViewController: WCSessionDelegate {
    func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) {
        switch(activationState){
        case .activated:
            // アクティブになったのでメッセージを送る
            self.sendMessage()
        case .inactive:
            // 省略
        case .notActivated:
            // 省略
        }
    }

    func sessionDidBecomeInactive(_ session: WCSession) {
        // 省略
    }

    func sessionDidDeactivate(_ session: WCSession) {
    // 省略
    }
}
satoshi-baba-0823
しがない何でもやる系エンジニア iOS,Androidアプリ開発から、Pythonとかも言われたらとりあえずやります。
dip-net
ディップ株式会社は「バイトル」「はたらこねっと」などの求人情報サービスをはじめ、人工知能専門メディア「AINOW」、スタートアップ専門メディア「スタートアップタイムズ」、アニメなどの舞台を紹介するサイト「聖地巡礼マップ」といった新しい分野のサービスを自社で開発・運営しています。
https://www.dip-net.co.jp/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away