質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.59%

swift callkitで通話中の電話を切電(トランザクション)する際に出力されるエラーについて

受付中

回答 0

投稿

  • 評価
  • クリップ 0
  • VIEW 1,264

RyomaD

score 16

現在IOS callkitを実装し、受電した際にcallkitを出力させるような使用になっております。
しかし発電→切電→発電→切電を繰り返すと以下のようなエラーが出力されアプリがクラッシュしてしまいます。(切電時に発生します。)

Error Domain=com.apple.CallKit.error.requesttransaction Code=4 "(null)"


解決方法を探していると同じような問題が発生している資料を見つけたので
当資料を参考にし、CXEndCallActionにセットされているUUIDが実際のUUIDと同じものか確認したのですが、やはり同じもので間違いありませんでした。
Error while requesting a transaction with CXEndCallAction

コードは以下になります。

//電話を切る時の処理
@objc func disCallTapped(sender : AnyObject) {
        let endCallAction = CXEndCallAction(call: UUIDs)
        print("UUIDs③: \(UUIDs)")
        let transaction2 = CXTransaction(action: endCallAction)

        self.controller.request(transaction2) { (error) in

            if let error = error {
                print(self.UUIDs)
                print(error)
            } else {
                 //ここで電話を終了している!
                print("=================切電===================")
                self.mediaConnection?.close()
            }
        }
    }
//電話をかける時の処理
@objc func callTapped(sender : AnyObject) {
        //①
        guard let peer = self.peer else{
            return
        }
        //電話をかける場合は「CXStartCallAction」を生成することから始まる。
        let transaction = CXTransaction(action: CXStartCallAction(call: UUIDs, handle: CXHandle(type: .generic, value: "Gokonテスト")))
        self.controller.request(transaction){ error in

            if let error = error {
                print("Error requesting transaction: \(error)")
            } else {
                print("Requested transaction successfully") // Error Domain=com.apple.CallKit.error
                self.call(targetPeerId: self.peerId)//peerId)  // ここで電話をかけている! -> callPeerIDSelectDialogでかけたい相手のpeerIdを取得
            }

        }

    //ユーザーが着信画面から電話を受け取るとここのDelegateが呼びだ出される。
    func provider(_ provider: CXProvider, perform action: CXAnswerCallAction) {
        print("=================電話を取った時===================")

        action.fulfill()
    }

//callkitのために追加(通話拒否・終了)
    func provider(_ provider: CXProvider, perform action: CXEndCallAction) {
        print("your UUID②: \(UUIDs)")//②
        print("=================電話を切った時===================")
        self.mediaConnection?.close()//②
        action.fulfill()
    }

//発電ボタンを押した時に走っている
    func setupMediaConnectionCallbacks(mediaConnection:SKWMediaConnection){
        print("=================setupMediaConnectionCallbacks(1)===================")
        // MARK: MEDIACONNECTION_EVENT_STREAM  相手のカメラ、マイク情報を受信したとき
        mediaConnection.on(SKWMediaConnectionEventEnum.MEDIACONNECTION_EVENT_STREAM, callback: { (obj) -> Void in
            if let msStream = obj as? SKWMediaStream{
                self.remoteStream = msStream
                DispatchQueue.main.async {
                  print("=================setupMediaConnectionCallbacks(2)===================")
                }
            }
            print("=================setupMediaConnectionCallbacks(3)===================")
        })

        // 切断されたとき、電話を切った時に走っているMARK: MEDIACONNECTION_EVENT_CLOSE 
        mediaConnection.on(SKWMediaConnectionEventEnum.MEDIACONNECTION_EVENT_CLOSE, callback: { (obj) -> Void in
            print("=================MEDIACONNECTION_EVENT_CLOSE(1)===================")
            if let _ = obj as? SKWMediaConnection{
                DispatchQueue.main.async {
                    self.remoteStream = nil
                    self.mediaConnection = nil <= ここで問題のエラーが出力される!
                print("=================MEDIACONNECTION_EVENT_CLOSE(2)===================")
                }
                print("=================MEDIACONNECTION_EVENT_CLOSE(3)===================")
                let endCallAction = CXEndCallAction(call: self.UUIDs)
                print("your UUID①: \(self.UUIDs)")//①
                let transaction2 = CXTransaction(action: endCallAction)
                self.controller.request(transaction2) { (error) in

                    if let error = error {
                        print("your UUID①: \(self.UUIDs)")
                        print(error)
                        print("=================MEDIACONNECTION_EVENT_CLOSE(4)===================")
                    } else {
                        print("=================MEDIACONNECTION_EVENT_CLOSE(5)===================")
                    }
                }
            }
        })

    }
}


どなたか本問題の原因、解決方法がご存知の方がいらっしゃれば
お力添えのほどよろしくお願いします。

以下のような記事にも記載されているような action.fulfill()も実装しているつもりですが、
書き漏れや、抜けがあればご教示頂けると幸いです。

CXEndCallAction transactions fails with Incorrect UUID

よろしくお願いします。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

まだ回答がついていません

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.59%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る