CallkitとTwilio対応でつながらないエラーや切れないエラーが出た場合の対処法


 Twilioのios10・CallKit対応してエラーが出る・・・

現在、自社アプリに電話機能を入れているのですが遅まきながらiOS10に対応するためCallKitを用いてみました。

サンプル通りだとおおよそ動くのですが、発信のUIにスピーカーやミュートなぞつけていると案外思った通りに動作しないことがあるためエラーの例と解決策を書きます。

CallKitのiOS10対応、あるいは受信 / 発信 / 応答あたりの挙動がたまにおかしくなるような悩みがある方が解決すれば幸いです。

エラー1:受信側でアプリ側のCallKitで応答を押しても発信側の発信が止まらない

アプリのプロセスを切って他のアプリをいじりながら応答するとなぜか発信側の発信音が止まらず、電話を応答したことにとになりません。

しかも、アプリのプロセスを切っているのでエラーもわかりづらい・・・。

ということで、TVOIncominCallDelegateのdidFailWithErrorIncomingCallメソッドのエラーをサーバーに飛ばすという方法でデバッグしたところ、下記のエラーが出ておりました。

Inside makeCall, failed to make Error:-560577449

このエラーでGoogleで検索すると下記のページが出てきますが、読むとどうやらTwilioの中の人か詳しい人はAVAudioSession周りで何かしてないか?というのをエラーが起きた人に質問しているのがわかります。

https://github.com/twilio/voice-quickstart-objc/issues/13

ということで、僕の方もコードを調べてAVAudioSessionをどこで使ってるかな?と調べ、routeAudioToSpeakerというメソッドがサンプルにありこちらをコメントアウトすることで起こらなくなりました。

もし、同じような現象が出ている方がいましたら、AVAudioSession系のコードを実行していないかどうか確かめられると良いかと。

エラー2:30%くらいの確率で、CXEndCallActionが失敗する

CXErrorCodeRequestTransactionErrorUnknownCallUUID = 4のエラーが出力するのもAVAudioSession周りが原因でした。

この場合に現象は2パターンあります。

パターン1:Twilioで通話を切ってもCallKitのオーディオが止まらない

通話を切ってもカウントアップが終わらず「通話に戻る」がずっと出てきて大変宜しくない現象です。

この場合には緊急回避策として

 [self.callKitProvider reportCallWithUUID:alterUUID endedAtDate:callEndDate reason:reason];

というのが有効ですが、失敗した時に「接続できませんでした」というエラーが出て微妙です。(解決策はパターン2に書いてます)

パターン2:Twilioで通話を切ると「接続できませんでした」が出る

XCodeでデバッグ中によく出るエラー、あるいは [self.callKitProvider reportCallWithUUID:alterUUID endedAtDate:callEndDate reason:reason];などで無理やり切ったりすると出る現象です。

この現象を50回くらい観察して気付いたのですがCXEndCallActionが失敗するときって、アプリがもっさり開いてステータスバーの緑色の部分が微妙な動きをするときだったんですよね。

ステータスバーがアプリを開いていると出ないで、アプリを閉じると出るとか。

そのため、AudioSession周りが怪しいと睨んで全てのAVAudioSession周りのコードを実行しないようにしました。

例えば、下記のようなコードです。

[code]
 if (speakerEnabled) {

        if (![[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayAndRecord

                                              withOptions:AVAudioSessionCategoryOptionDefaultToSpeaker

                                                    error:&error]) {

            NSLog(@"Unable to reroute audio: %@", [error localizedDescription]);

        }

    }else{

        if (![[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayAndRecord

                                              withOptions:AVAudioSessionCategoryOptionAllowBluetooth

                                                    error:&error]) {

            NSLog(@"Unable to reroute audio: %@", [error localizedDescription]);

        }

        [[AVAudioSession sharedInstance] overrideOutputAudioPort:AVAudioSessionPortOverrideNone error:&error];

        [[AVAudioSession sharedInstance] setActive:YES error:&error];

    }
[/code]

なんとなく、スピーカー周りを自分の思った通りにしたかったので、旧バージョンで実行していたのが問題だったようです。

ちなみに、普通にボタンを押した時にこのメソッドを実行しても問題は起こることはありませんでした。

下記のデリゲートメソッド近辺でAVAudioSessionを実行すると起こるようです。

・ (void)incomingCallDidConnect:(TVOIncomingCall *)incomingCall 

・(void)provider:(CXProvider *)provider performAnswerCallAction:(CXAnswerCallAction *)action

TwilioのCallKit対応に起こったエラーに関するまとめ

以上のように、初期化サイクル付近でAVAudioSessionに関していじるとTwilioSDKかCallKitの動作とバッティングして予期せぬ動作が起こったみたいでした。

同様のエラーが出ている方の助けになれば幸いです。

SNSでもご購読できます。