Upgrade to PRO for Only $50/Year—Limited-Time Offer! 🔥

実践 Advanced CallKit 〜快適な通話の実現に向けて〜

実践 Advanced CallKit 〜快適な通話の実現に向けて〜

iOSDC Japan 2024 Day0で発表した資料です。

https://fortee.jp/iosdc-japan-2024/proposal/2e0cad57-121c-48c0-9c31-63433e5ea3da

GO Inc. dev

August 26, 2024
Tweet

More Decks by GO Inc. dev

Other Decks in Programming

Transcript

  1. © GO Inc. 実践 Advanced CallKit 〜快適な通話の実現に向けて〜 2024.08.22 17:20 ~

    / Track C 開発本部 ソフトウェア開発統括部 ユーザーシステム開発部 ユーザーシステム1グループ/ 髙橋秀宗 GO株式会社
  2. © GO Inc. 2 自己紹介 GO株式会社 iOSエンジニア / 髙橋秀宗 2022年12月に入社後、タクシーアプリ『GO』のユーザーアプ

    リの開発を担当 直近はiOSアプリ開発に必要なBackend APIの開発も担当し、仕 事の幅を広げている 最近AirPods Proをお洗濯する実績を解除。ぐぬぬ。 @h1d3mun3
  3. Index © GO Inc. 1. CallKit + Twilio Voiceでの通話 2.

    CallKitの紹介 3. Twilio Voiceの紹介 4. 『GO』での活用事例 5. Advanced CallKit 6. おわりに 9
  4. © GO Inc. 着信に応答する時のCallKitとTwilio Voiceの責務 14 • CallKit ◦ 新規着信の登録

    ◦ 通話を接続して良いかの問い合わせ ◦ 通話に接続して良いと返却 • Twilio Voice ◦ VoIP通知受信を通知 ◦ 着信を通知
  5. © GO Inc. CallKitとは 16 • VoIPアプリをより標準の通話アプリのように実装するためのFramework ◦ iOS10より利用可能 ◦

    下記が実現可能 ▪ 標準電話アプリのようなUIでの着信の応答 ▪ 通話履歴に着信を残し標準アプリ経由で発信 • 通話の発信・応答・終話・ミュート/アンミュート・保留・マージなど の音声通話操作の責務を担当
  6. © GO Inc. 着信に応答する時に必要になる情報 17 • UUID ◦ 個別の通話をUUIDで表現 •

    CXProvider ◦ システムへの通話登録用クラス ▪ 新規の通話や通話の終了をシステムにリクエスト
  7. © GO Inc. // 新規の着信通話を非同期で登録 func reportNewIncomingCall(with: UUID, update: CXCallUpdate,

    completion: ((any Error)?) -> Void) 新規着信の登録で使うCXProviderのメソッド 19
  8. © GO Inc. • 通話のメタ情報を保持 ◦ 発信者の名前 ◦ ビデオはあるか ◦

    保留をサポートするか ◦ 通話のグループ化・グループ化解除をサポートするか ◦ …etc CXCallUpdateとは 20
  9. © GO Inc. let uuid = call.uuid let update =

    CXCallUpdate() 〜〜〜updateを設定〜〜〜 provider.reportNewIncomingCall( with: uuid, update: callUpdate) { [weak self] error in 〜〜〜 } 新規着信の登録のコード 21
  10. © GO Inc. func provider(_ provider: CXProvider, perform action: CXAnswerCallAction)

    { guard isReady else { // 処理を失敗させたい時はfail()を呼び出す action.fail() return } action.fulfill() // 処理を進める時はfulfill()を呼び出す registCall(of: action.callUUID) } 通話を接続する場合のコード 22 「特定の通話に応答する」と いう行為を表すCXActionと いう抽象クラスの具象クラス
  11. © GO Inc. CXActionとは 23 • CXActionとは通話に対する操作を抽象化したクラス ◦ CXAnswerCallActionの他にも複数種類あり、代表的なものとして 下記がある

    ▪ CXStartCallAction: 通話を発信 ▪ CXEndCallAction: 通話を終話 • これらの更新処理を1つにまとめたCXTransactionというクラスも存在
  12. © GO Inc. TwilioVoiceSDKでの登場人物 27 • Call ◦ 通話を表す •

    CallInvite ◦ 通話になる前の着信状態を表す → CallKitだとUUIDで管理していたものに具象クラスがある
  13. © GO Inc. VoIP通知受信を通知する時に使う関数 28 class func handleNotification( _ payload:

    [AnyHashable : Any], delegate: NotificationDelegate, delegateQueue: dispatch_queue_t? ) -> Bool
  14. © GO Inc. VoIP通知受信を通知する時のコード 30 // PushKit経由で通知されたVoIP通知のPayloadをSDKに投げる let payload =

    payload.dictionaryPayload _ = TwilioVoiceSDK.handleNotification( payload.dictionaryPayload, delegate: self, delegateQueue: nil)
  15. © GO Inc. 着信を通知してもらい、システムに登録するコード 32 func callInviteReceived(callInvite: CallInvite) { let

    uuid = callInvite.callSid let callUpdate = CXCallUpdate() provider.reportNewIncomingCall( with: callInvite.uuid, update: callUpdate) { [weak self] error in // システムへの登録成功🎉 } }
  16. © GO Inc. • 『GO』には下記利用シーンを想定してアプリから複数台のタクシーを 配車することができる複数台配車機能がある ◦ イベントでの大人数での移動 ◦ 接待時の代理手配

    • ほとんど同じタイミングで複数の車両がお客様のもとに向かうケースが ある ◦ 1つの『GO』アプリに複数の着信が来る可能性がある 複数の着信と通話を同時に管理する必要 37
  17. © GO Inc. 下記のような状況においてもCallInviteとCallを適切に管理できなければな らない 1. 乗務員Aから着信 2. ユーザーが着信に応答 3.

    乗務員Aとの通話中に乗務員Bから着信 4. 乗務員Bの着信に応答 複数の着信と通話を同時に管理する必要 39
  18. © GO Inc. 下記のような状況においてもCallInviteとCallを適切に管理できなければな らない 1. 乗務員Aから着信 ←CallInviteとCallの状況は? 2. ユーザーが着信に応答

    ←CallInviteとCallの状況は? 3. 乗務員Aとの通話中に乗務員Bから着信 ←CallInviteとCallの状況は? 4. 乗務員Bの着信に応答 ←CallInviteとCallの状況は? 複数の着信と通話を同時に管理する必要 40
  19. © GO Inc. 下記のような状況においてもCallInviteとCallを適切に管理できなければな らない 1. 乗務員Aから着信 ←CallInviteとCallの状況は? 2. ユーザーが着信に応答

    ←CallInviteとCallの状況は? 3. 乗務員Aとの通話中に乗務員Bから着信 ←CallInviteとCallの状況は? 4. 乗務員Bの着信に応答 ←CallInviteとCallの状況は? 複数の着信と通話を同時に管理する必要 41 各種Delegate等の通知をもとにCallInviteとCallの情報を常に正しい状態 に保つ必要がある
  20. © GO Inc. CallInviteとCallを正しい状態に保てないとどうなるか... 42 • CallInviteとCallを最新状態に保てないと下記問題が発生 ◦ システムに登録されている着信に応答したいができない ◦

    システムに登録されている通話を終話したいができない → システムに登録されている着信 / 通話に対して操作ができなくなってし まう
  21. © GO Inc. • よくある通話の保留と同じく、現在成立している通話を保留する ◦ 自分の声は相手には伝わらない ◦ 相手の声は自分には伝わらない •

    CallKitのデフォルト機能だと相互に無音になってしまい、保留状態に 入ったことがわかりにくい 保留 49
  22. © GO Inc. let callUpdate = CXCallUpdate() 〜〜〜中略〜〜〜 callUpdate.supportsHolding =

    true 〜〜〜中略〜〜〜 provider.reportNewIncomingCall(with: callInvite.uuid, update: callUpdate) { error in 〜〜〜中略〜〜〜 } システムに通話を登録する時に保留を有効にする 51
  23. © GO Inc. let callUUID = UUID() let desiredState: Bool

    = true let action = CXSetHeldCallAction(call: callUUID, onHold: desiredState) callController.request(CXTransaction(action: action), completion: { error in // このClosure内部で結果が取得可能 print(error) } 保留 52
  24. © GO Inc. CXProviderで複数の通話を同時に成立させられるように設定 55 let configuration = CXProviderConfiguration() //

    maximumCallGroupsを2以上に設定すると通話を複数成立させられる configuration.maximumCallGroups = 2 configuration.maximumCallsPerCallGroup = 2 let provider = CXProvider(configuration: configuration)
  25. © GO Inc. 通話を入れ替える 56 let holdAction = CXSetHeldCallAction(call: talkingCall.uuid!,

    onHold: true) let unHoldAction = CXSetHeldCallAction(call: holdingCall.uuid!, onHold: false) callController.request(CXTransaction(actions: [holdAction, unHoldAction]), completion: { error in // 〜〜〜中略〜〜〜 })
  26. © GO Inc. 連絡先の通知を許可するについて 62 • いわゆるホワイトリスト ◦ 追加した連絡先にだけ通知を許可 •

    着信を許可するパターンは4モード ◦ 全ての人 ◦ 通知あり連絡先のみ ◦ よく使う項目 ◦ 連絡先のみ • 繰り返しの着信を許可 ◦ 3分以内に2度目の着信があったら通知
  27. © GO Inc. 着信を許可するパターンについて 63 • 全ての人 ◦ 全ての通話が許可される •

    通知される連絡先のみ ◦ 集中モードで登録した連絡先と、緊急時は鳴らすに追加した連絡先からのみの着 信を許可する • よく使う項目 ◦ 通知される連絡先のみに加えて、よく使う項目に追加した連絡先からのみの着信 を許可する • 連絡先のみ ◦ 連絡先からの着信を許可する
  28. © GO Inc. 緊急時は鳴らすについて 64 • 下記手順で設定可能 ◦ 登録した連絡先を開き編集 ◦

    着信音をタップ ◦ 画面上部の「緊急時は鳴らす」のスイッチをOn
  29. © GO Inc. • 集中モードでは通知をさまざまな条件でブロックすることができる • 集中モードの拒否リストに該当した場合、着信画面が表示されない • 着信画面が表示できなかった時のケアが大切 ◦

    CXErrorCodeIncomingCallError というエラーが返ってくる ◦ GOでの取り組み ▪ 着信画面の表示エラーを検知した場合はログとして保存 • お客様から「乗務員と通話できなかった」という問い合わせ が来た時の調査目的 集中モードと着信画面の関連性まとめ 65
  30. © GO Inc. おわりに 67 • CallKit + Twilio Voiceでの通話への応答のフローを紹介

    • VoIP通話を行うために必要なCallKit、Twilioについて紹介 • 『GO』での活用事例を紹介 • 通話の保留・入れ替えやおやすみモードと通話の関係性について紹介
  31. © GO Inc. 69 After iOSDC & DroidKaigi 2024 Mobile

    LT Nightやります! 2023年09月26日 19:00 ~ 20:30 https://reiwatravel.connpass.com/event/327079/
  32. © GO Inc. 参考資料 71 • CallKit | Apple Developer

    Documentation ◦ https://developer.apple.com/documentation/callkit/ • CXProvider | Apple Developer Documentation ◦ https://developer.apple.com/documentation/callkit/cxprovider • CXCallController | Apple Developer Documentation ◦ https://developer.apple.com/documentation/callkit/cxcallcontroller • Voice SDKs | Twilio ◦ https://www.twilio.com/docs/voice/sdks • Twilio Voice Quickstart for iOS with Swift - GitHub ◦ https://github.com/twilio/voice-quickstart-ios • 実践 CallKit/PushKit ときどき🐛退治 / iOSDC 2019 ◦ https://speakerdeck.com/monoqlo/iosdc-2019