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

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

新規登録して質問してみよう
ただいま回答率
85.48%
Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

WebRTC

WebRTC(Web Real-Time Communication)とは、プラグイン無しでウェブブラウザ間の音声通話・ビデオチャットなどリアルタイムコミュニケーションができるオープンフレームワークです。W3CがAPIレベルで、IETFがプロトコルレベルでそれぞれ標準化が進められています。

Q&A

0回答

1932閲覧

CallKitでfunctionを実行したいができない。

ninomiyanen

総合スコア21

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

WebRTC

WebRTC(Web Real-Time Communication)とは、プラグイン無しでウェブブラウザ間の音声通話・ビデオチャットなどリアルタイムコミュニケーションができるオープンフレームワークです。W3CがAPIレベルで、IETFがプロトコルレベルでそれぞれ標準化が進められています。

0グッド

0クリップ

投稿2018/09/21 08:37

SkwWayというwebRTCのapiとCallKitで電話機能を実装しています。

swift

1// 2// MediaConnectionViewController.swift 3// swift 4// 5// 6 7import UIKit 8import AVFoundation 9import PushKit 10import CallKit 11import SkyWay 12 13 14 15class MediaConnectionViewController: UIViewController, CXProviderDelegate { 16 17 let provider = CXProvider(configuration: CXProviderConfiguration(localizedName: "Gokon")) 18 var successPhone: String! 19 20 // providerDidResetはCXProviderDelegateのために必要 21 func providerDidReset(_ provider: CXProvider) { } 22 func provider(_ provider: CXProvider, perform action: CXAnswerCallAction) {action.fulfill()} //通話開始 23 func provider(_ provider: CXProvider, perform action: CXEndCallAction) { action.fulfill() } //通話拒否・終了 24 25 26 fileprivate var peer: SKWPeer? 27 fileprivate var mediaConnection: SKWMediaConnection? 28 fileprivate var localStream: SKWMediaStream? 29 fileprivate var remoteStream: SKWMediaStream? 30 31 @IBOutlet weak var localStreamView: SKWVideo! 32 @IBOutlet weak var remoteStreamView: SKWVideo! 33 @IBOutlet weak var myPeerIdLabel: UILabel! 34 @IBOutlet weak var targetPeerIdLabel: UILabel! 35 @IBOutlet weak var callButton: UIButton! 36 @IBOutlet weak var endCallButton: UIButton! 37 38 override func viewDidLoad() { 39 40 provider.setDelegate(self, queue: nil) 41 42 super.viewDidLoad() 43 self.setup() 44 } 45 46 override func viewWillDisappear(_ animated: Bool) { 47 super.viewWillDisappear(animated) 48 self.mediaConnection?.close() 49 self.peer?.destroy() 50 } 51 52 override func didReceiveMemoryWarning() { 53 super.didReceiveMemoryWarning() 54 // Dispose of any resources that can be recreated. 55 } 56 57 58 59 60 //ボタンを押して発信...ではない? 61 //ボタンを押して、相手を選択 -> Utilへ 62 @IBAction func tapCall(){ 63 guard let peer = self.peer else{ 64 return 65 } 66 // 流れ (相手のpeerIdを特定) -> (発信) ここのpeerIdをマッチング相手から取ってくる処理にする 67 Util.callPeerIDSelectDialog(peer: peer, myPeerId: peer.identity) { (peerId) in 68 69 70 71 self.call(targetPeerId: peerId)//peerId) //ここで電話をかけている! -> callPeerIDSelectDialogでかけたい相手のpeerIdを取得 72 73 74 75 } 76 } 77 78 //ボタンを押して通話終了 79 @IBAction func tapEndCall(){ 80 self.mediaConnection?.close() //ここで電話を終了している! 81 self.changeConnectionStatusUI(connected: false) 82 } 83 84 func changeConnectionStatusUI(connected:Bool){ 85 if connected { 86 self.callButton.isEnabled = false 87 self.endCallButton.isEnabled = true 88 }else{ 89 self.callButton.isEnabled = true 90 self.endCallButton.isEnabled = false 91 } 92 } 93} 94 95// MARK: setup skyway 96 97extension MediaConnectionViewController{ 98 99 func setup(){ 100 101 guard let apikey = (UIApplication.shared.delegate as? AppDelegate)?.skywayAPIKey, let domain = (UIApplication.shared.delegate as? AppDelegate)?.skywayDomain else{ 102 print("Not set apikey or domain") 103 return 104 } 105 106 let option: SKWPeerOption = SKWPeerOption.init(); 107 option.key = apikey 108 option.domain = domain 109 110 peer = SKWPeer(options: option) 111 112 if let _peer = peer{ 113 self.setupPeerCallBacks(peer: _peer) 114 self.setupStream(peer: _peer) 115 }else{ 116 print("failed to create peer setup") 117 } 118 } 119 120 func setupStream(peer:SKWPeer){ 121 SKWNavigator.initialize(peer); 122 let constraints:SKWMediaConstraints = SKWMediaConstraints() 123 self.localStream = SKWNavigator.getUserMedia(constraints) 124 self.localStream?.addVideoRenderer(self.localStreamView, track: 0) 125 } 126 127 func call(targetPeerId:String){ 128 let option = SKWCallOption() 129 130 if let mediaConnection = self.peer?.call(withId: targetPeerId, stream: self.localStream, options: option){ 131 self.mediaConnection = mediaConnection 132 self.setupMediaConnectionCallbacks(mediaConnection: mediaConnection) 133 }else{ 134 print("failed to call :(targetPeerId)") 135 } 136 } 137} 138 139// MARK: skyway callbacks 140 141extension MediaConnectionViewController{ 142 143 func setupPeerCallBacks(peer:SKWPeer){ 144 145 // MARK: PEER_EVENT_ERROR 146 peer.on(SKWPeerEventEnum.PEER_EVENT_ERROR, callback:{ (obj) -> Void in 147 if let error = obj as? SKWPeerError{ 148 print("(error)") 149 } 150 }) 151 152 // MARK: PEER_EVENT_OPEN 初期接続時の処理 153 peer.on(SKWPeerEventEnum.PEER_EVENT_OPEN,callback:{ (obj) -> Void in 154 if let peerId = obj as? String{ 155 DispatchQueue.main.async { 156 self.myPeerIdLabel.text = peerId 157 self.myPeerIdLabel.textColor = UIColor.darkGray 158 } 159 print("your peerId: (peerId)") 160 } 161 }) 162 163 164 let update = CXCallUpdate() 165 update.remoteHandle = CXHandle(type: .generic, value: "あぷりだよ!") 166 167 // MARK: PEER_EVENT_CONNECTION 168 peer.on(SKWPeerEventEnum.PEER_EVENT_CALL, callback: { (obj) -> Void in 169 170 if let connection = obj as? SKWMediaConnection{ 171 172 self.setupMediaConnectionCallbacks(mediaConnection: connection) 173 self.mediaConnection = connection 174 175 // reportNewIncomingCallは着信呼び出し画面に実際に表示されるもの 176 self.provider.reportNewIncomingCall(with: UUID(), update: update, completion: { error in }) 177 178 connection.answer(self.localStream) //ここで応答!! 179 180 print("ああああああああああああああああああああああああ") 181 } 182 }) 183 184 } 185 186 func setupMediaConnectionCallbacks(mediaConnection:SKWMediaConnection){ 187 188 // MARK: MEDIACONNECTION_EVENT_STREAM 相手のカメラ、マイク情報を受信したとき 189 mediaConnection.on(SKWMediaConnectionEventEnum.MEDIACONNECTION_EVENT_STREAM, callback: { (obj) -> Void in 190 if let msStream = obj as? SKWMediaStream{ 191 self.remoteStream = msStream 192 DispatchQueue.main.async { 193 self.targetPeerIdLabel.text = self.remoteStream?.peerId 194 self.targetPeerIdLabel.textColor = UIColor.darkGray 195 self.remoteStream?.addVideoRenderer(self.remoteStreamView, track: 0) 196 } 197 self.changeConnectionStatusUI(connected: true) 198 } 199 }) 200 201 // MARK: MEDIACONNECTION_EVENT_CLOSE 202 mediaConnection.on(SKWMediaConnectionEventEnum.MEDIACONNECTION_EVENT_CLOSE, callback: { (obj) -> Void in 203 if let _ = obj as? SKWMediaConnection{ 204 DispatchQueue.main.async { 205 self.remoteStream?.removeVideoRenderer(self.remoteStreamView, track: 0) 206 self.remoteStream = nil 207 self.mediaConnection = nil 208 } 209 self.changeConnectionStatusUI(connected: false) 210 } 211 }) 212 } 213}

print("ああああああああああああああああああ")の上(//ここで応答)で電話を受けており、その上のself.provider.reportNewIncomingCall(with: UUID(), update: update, completion: { error in })
で電話のUIが表示されます。
しかしこれだとUIが表示されるだけで、許可しても拒否しても電話が繋がってしまいます。

22行目にある
func provider(_ provider: CXProvider, perform action: CXAnswerCallAction) {action.fulfill()} //通話開始
が電話で応答ボタンを押したとき(つまり許可されたとき)の関数だと思います。

電話を許可したときだけ(//ここで応答)の処理が実行されるようにしたいのですが、具体的な方法がわかりません。

どなたか教えていただけると幸いです。
よろしくお願いします。

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問