
シェア:
アブドゥルはVonageのデベロッパー・アドボケイト。iOSエンジニアとして消費者向け製品に携わった経歴を持つ。余暇には、サイクリング、音楽鑑賞、技術者としての道を歩み始めたばかりの人々の指導を楽しんでいる。
iOSのCallKitを使って発信電話をかける方法
所要時間:1 分
このチュートリアルでは、Vonage Client SDK と CallKit を使用して電話をかけることができる SwiftUI アプリケーションを作成します。CallKit を使うことで、iOS アプリケーションをシステムに統合することができます。発信電話をかけるとき、アプリケーションからの通話履歴は iOS の電話アプリで利用できるようになります。
前提条件
Vonage APIアカウント。まだお持ちでない方は 今すぐサインアップ.
Apple DeveloperアカウントとiOSデバイス
Xcode 12とSwift 5以上。
ココアポッドをクリックしてVonage Client SDK for iOSをインストールしてください。
概要
まず、Vonage Application、Applications、JWT Generation、Webhooksを作成するためのサーバをデプロイします。その後、Vonage Client SDKを使用して、CallKitを使用して呼び出しを行うiOSアプリケーションを適応させます。
サーバーの配置
このプロジェクトでは Vonage Cloud Runtime Marketplaceを使用します。を使用して、Vonage インフラストラクチャに Client SDK Voice サーバをデプロイします。を開きます。 Client SDK Voiceサンプルサーバー製品ページを開きます。Deploy Code "タブを開き、まだログインしていない場合は今すぐログインしてください。
配置の名前を入力し、地域を選択します。その後、"Deploy Code "ボタンをクリックしてください。
Client SDK Voice Sample Server "Deploy Code" page
Voice APIを使用するには、Vonage番号を購入し、アプリケーションに割り当てる必要があります。Assign a number "をクリックして既存の番号を表示するか、新しい番号を購入してください。完了したら、"Continue "をクリックしてください。
Assign number popup
デプロイが完了したら、「Launch」ボタンをクリックします。ブラウザにサーバーアプリケーションが表示され、サーバーの動作についての詳細を読むことができます。チュートリアルを続けるには、ユーザを作成する必要があります。ユーザーとは、Vonage Client SDKをVonage APIで実行しているアプリケーションを識別するためのものです。
Client SDK Voice Sample Server landing page
を作成します。 ユーザーAlice "というユーザーを作成し、JWTを生成します。クライアントSDKはJWTを使ってVonageと認証します。先ほどアプリケーションに割り当てたVonage番号に電話をかけると、Vonageはこのサーバにリクエストを行い、そのリクエストは コール・コントロール・オブジェクトを返します。
Generating a JWT for a user on the Client SDK Voice Sample Server
スターター・プロジェクトのダウンロード
このチュートリアルは、既存のプロジェクトの上に構築されます。Vonage Client SDKを使用して発信通話をすることに慣れていない場合は、以下のチュートリアルを参照することをお勧めします。 SwiftUIで電話をかける方法ブログの投稿を参照することをお勧めします。準備ができたら、スタータープロジェクトを GitHubからスタータープロジェクトをクローンします:
git clone git@github.com:Vonage-Community/blog-clientsdk-ios_swift-swiftui_app_to_phone.git次に、ディレクトリをプロジェクトのフォルダに移動し、以下のファイルをインストールする。 VonageClientSDKVoiceをインストールします:
cd blog-clientsdk-ios_swift-swiftui_app_to_phone
pod install完成したら、このコマンドでプロジェクトを開くことができる:
xed . スタータープロジェクトの更新
CallKitを使用して呼び出しを行うので、次のように loginIfNeeded関数を ContentView.swiftファイルの関数を更新して isUsingCallKitフラグを削除します。SDKのデフォルトはtrueです。ここで、先ほど作成したユーザー "Alice "のJWTを貼り付けることもできます:
func loginIfNeeded() {
guard status != "Connected" else { return }
client.createSession("ey...") { error, sessionId in
if let error {
self.updateStatus(error.localizedDescription)
} else {
self.updateStatus("Connected")
}
}
} VoIPバックグラウンドモードの追加
CallKit を使用するには、VoIP バックグラウンドモードを追加する必要があります。Xcodeの環境設定からApple開発者アカウントにログインしていることを確認してください。そうであれば、ターゲットを選択し 署名と機能:
Add capability button in Xcode
次に、ケイパビリティの追加ボタンとBackground Modesケイパビリティを選択します。バックグラウンド・モード機能で ボイスオーバーIP:
Adding the VoIP background mode in Xcode
CallKitフレームワークのリンク
CallKit フレームワークをプロジェクトにリンクします。 フレームワーク、ライブラリ、組み込みコンテンツの下に追加します。 一般:
Adding the CallKit framework in Xcode
プロバイダー・マネージャーの作成
次に、クラスを作成する、 ProviderManager.CallKitは、アプリとシステム間の通信を CXProvider.という名前の新しいSwiftファイル(CMD + N)を作成します。 ProviderManager:
import CallKit
import Foundation
import VonageClientSDKVoice
protocol ProviderManagerDelegate: AnyObject {
func callReported(_ providerManager: ProviderManager, callUUID: UUID)
func providerReset()
}
final class ProviderManager: NSObject {
private static var providerConfiguration: CXProviderConfiguration = {
let providerConfiguration = CXProviderConfiguration()
providerConfiguration.maximumCallsPerCallGroup = 1
providerConfiguration.supportedHandleTypes = [.generic, .phoneNumber]
return providerConfiguration
}()
private let provider = CXProvider(configuration: ProviderManager.providerConfiguration)
weak var delegate: ProviderManagerDelegate?
override init() {
super.init()
provider.setDelegate(self, queue: nil)
}
public func reportOutgoingCall(callUUID: UUID) {
provider.reportOutgoingCall(with: callUUID, connectedAt: .now)
}
public func reportFailedCall(callUUID: UUID) {
provider.reportCall(with: callUUID, endedAt: .now, reason: .failed)
}
public func reportEndedCall(callUUID: UUID) {
provider.reportCall(with: callUUID, endedAt: .now, reason: .remoteEnded)
}
}上記のコードには CXProviderの作成と、システムに対する呼び出しのステータスを報告するヘルパー関数の作成が含まれている。また ProviderManagerDelegateもここで定義されている。
を実施する。CXProviderDelegate
は CXProviderDelegateは、通話に関するシステムからの最新情報を提供する。同じファイルにデリゲートを実装する ProviderManagerを追加します:
extension ProviderManager: CXProviderDelegate {
func provider(_ provider: CXProvider, perform action: CXStartCallAction) {
provider.reportOutgoingCall(with: action.callUUID, startedConnectingAt: .now)
delegate?.callReported(self, callUUID: action.callUUID)
action.fulfill()
}
func providerDidReset(_ provider: CXProvider) {
delegate?.providerReset()
}
func provider(_ provider: CXProvider, didActivate audioSession: AVAudioSession) {
VGVoiceClient.enableAudio(audioSession)
}
func provider(_ provider: CXProvider, didDeactivate audioSession: AVAudioSession) {
VGVoiceClient.disableAudio(audioSession)
}
}ユーザーが番号を入力して通話を開始すると、アプリはCallKitに通話開始をリクエストする。このリクエストが成功すると CXStartCallActionデリゲート関数が呼び出され、発信が報告されます。ここで非常に重要なのは VGVoiceClient.enableAudio/VGVoiceClient.disableAudioがCallKitによって提供されたオーディオ・セッションで呼び出されていることに注意してください。 CXProviderDelegate.
更新CallModel
これで ProviderManagerがセットアップされたので CallModelクラスを更新します。ファイルを開き ContentView.swiftファイルの先頭にある変数を置き換える。 CallModelクラスの先頭にある変数を置き換えます:
final class CallModel: NSObject, ObservableObject, VGVoiceClientDelegate {
@Published var status: String = ""
@Published var isCalling: Bool = false
private let client = VGVoiceClient()
var number: String = ""
private var callId: (vonage: String?, callkit: UUID?)
private let callController = CXCallController()
private let providerManager = ProviderManager()
private let audioSession = AVAudioSession.sharedInstance()
...
}callIdは、VonageコールIDからCallKitコールUUIDへのマッピングを管理するためのタプルに変更されました、 providerManagerが追加されました。 callController. callControllerのインスタンスです。 CXCallControllerのインスタンスである。
更新startCall機能
この startCall関数で呼び出しを要求するように更新しなければならない。 callControllerを介して呼び出しを要求するように更新する必要があります。既存の関数を新しい関数に置き換えてください:
func startCall() {
isCalling = true
let handle = CXHandle(type: .phoneNumber, value: number)
self.callId.callkit = UUID()
let startCallAction = CXStartCallAction(call: self.callId.callkit!, handle: handle)
let transaction = CXTransaction(action: startCallAction)
callController.request(transaction) { _ in }
}CallKitはコールを識別する方法を必要とするため、この新しい関数はUUIDを作成しますが、SDKがコールをかけるまでVonageコールIDは取得できません。その後 CXStartCallActionを CXTransactionを使用して通話をリクエストします。これは CXStartCallAction関数を呼び出します。 CXProviderDelegate関数を呼び出します。
更新endCall機能
同様に endCall関数も CallKit 用に更新する必要があります。既存の関数を新しい関数に置き換えてください:
func endCall() {
client.hangup(callId.vonage!) { error in
if error == nil {
if let callkitUUID = self.callId.callkit {
let transaction = CXTransaction(action: CXEndCallAction(call: callkitUUID))
self.callController.request(transaction) { _ in }
}
}
}
}この新しい関数は CXEndCallActionアクションを作成した。 CXTransactionで使用される。通話終了をリクエストすることで、システムは通話時間を正確に計算できる。また、リモートで通話が終了した場合の処理も必要です。を更新する。 didReceiveHangupForCall関数を更新する。 VGVoiceClientDelegate関数を更新する:
func voiceClient(_ client: VGVoiceClient, didReceiveHangupForCall callId: VGCallId, withQuality callQuality: VGRTCQuality, reason: VGHangupReason) {
if let callkitUUID = self.callId.callkit {
providerManager.reportEndedCall(callUUID: callkitUUID)
}
resetState()
}この場合も、通話終了が providerManagerを介して通話終了がシステムに報告されるため、通話時間を正確に計算できる。
を実施する。ProviderManagerDelegate
最後に ProviderManagerDelegateを実装する。 providerManagerに変更を伝えることができるようにする。 CallModel:
extension CallModel: ProviderManagerDelegate {
func callReported(_ providerManager: ProviderManager, callUUID: UUID) {
client.serverCall(["to": number]) { error, callId in
if error == nil {
providerManager.reportOutgoingCall(callUUID: callUUID)
self.callId.vonage = callId
} else {
providerManager.reportFailedCall(callUUID: callUUID)
}
}
}
func providerReset() {
resetState()
}
}このデリゲート関数は providerManagerが正常にシステムにコールを報告した場合、このデリゲート関数はVonage Client SDKを使用してコールを作成します。成功時とエラー時の両方で providerManagerは、通話ステータスをシステムに報告するために使用される。これで、物理デバイス上でXcodeプロジェクトを実行することで、アプリで通話を行うことができる。iOSの電話アプリで最近の通話を見ると、通話とアプリ名が表示されているはずだ。情報アイコンをクリックすると、通話時間も表示されます。
Call log from phone app
次はどうする?
完成したプロジェクトは GitHub.Client SDKとCallKitを使うことで、さらに多くのことができるようになります。Client SDKの詳細については以下をご覧ください。 Vonage Client SDKの概要およびCallKitについては developer.apple.comでご覧いただけます。.


