Twilio SDKを使った音声通話アプリ開発
はじめに
前回の記事で述べた通りに、今日はTwilio Video SDKを使用してiOS版音声通話アプリを開発する方法を説明させていただきます。
概して言えば、Twilio Videoは、リアルタイムビデオチャット機能や音声通話機能、画面共有機能などを作るための色々なサービスを提供するプラットフォームとして知られており、世界で高く評価されています。
https://www.g2.com/products/twilio/reviews
https://www.trustradius.com/products/twilio-video/reviews
この記事ではVideo APIを使用して音声通話アプリを開発してみましょう。
Twilioでのプロジェクト作成
Twilloでアカウントを登録します。
コンソールページを開きます。
こちらで「TwilioDemoChat」という名前または任意の名前のプロジェクトを作成します。
プロジェクト作成が終わったら、ウェルカムページが表示されます。
「Other」を選択し、ダッシュボードページに遷移して、プロジェクトの作成手順を完了しましょう。
後で使用できるように、アカウントSIDと認証トークンをファイルに保存しておきます。
APIキー作成
こちらで参照してください。
新しいAPIキーは、1回だけ表示されるので、慎重に保管しておいてください。
アクセストークン作成
こちらで2つの新しいアクセストークンを作成します。その理由としては、2人のユーザー(TwilioDemoChatRoomUser1およびTwilioDemoChatRoomUser2)がTwilioDemoChatRoomという同じルームに参加するケースを検証するためです。「Generate Access Token」ボタンをクリックしてアクセストークンを取得し、iOSアプリに使用するために保存しておきます。
注意事項:リリース環境では、これがサーバー側によって実施されます。サーバー側でルームに参加するユーザーにつきアクセストークンを生成します。そのアクセストークンは、Twilioサーバーに対してユーザーを認証するための短期認証です。
iOSでの音声通話アプリ開発
チュートリアルを参照してください。
TwilioDemoChatという新しいプロジェクトを作成します。
CocoaPods構成
プロジェクトのルートディレクトリにPodFileという空ファイルを作成し、以下のコードを入れます。
platform :ios,'11.0' use_frameworks! def install_pods pod 'TwilioVideo' pod 'MBProgressHUD' end target 'TwilioDemoChat' do install_pods end
ターミナルアプリを開き、プロジェクトルートで次のコマンドを実行することでTwilioVideo SDKをインストールします。
pod install
アプリ側は音声通話のため端末のマイクロを使用するので、端末のマイクにアクセスする権限をinfo.plistファイルに追加する必要があります。
NSMicrophoneUsageDescription このサンプルにて音声通話機能に端末のマイクロを使います。
Twilio導入
まず、ルームへの参加を処理するTwilioController.swiftコントローラーを作成します。
import UIKit import TwilioVideo import MBProgressHUD let TWILIO_TEST_ROOM = "TwilioDemoChatRoom" let TWILIO_ACCESS_TOKEN_1 = "「アクセストークン作成」で作成されたアクセストークン" let TWILIO_ACCESS_TOKEN_2 = "「アクセストークン作成」で作成されたアクセストークン" let kTwilioController = TwilioController.shared public enum RoomStatus{ case Connected case Disconnected case ParticipantConnected case ParticipantDisconnected case Error } public typealias RoomStatusUpdatedHandler = (RoomStatus) -> (Void) class TwilioController: NSObject { static let shared = TwilioController() var room:Room? = nil var connected = false var roomStatusHandler:RoomStatusUpdatedHandler? private var localAudioTrack = LocalAudioTrack() //TWILIO_TEST_ROOM定数でルームへ接続を行ないます。 func connectToRoom(handler:RoomStatusUpdatedHandler?) { roomStatusHandler = handler //各端末ごとにアクセストークンを変更します。 let connectOptions = ConnectOptions(token: TWILIO_ACCESS_TOKEN_2) { (builder) in builder.roomName = TWILIO_TEST_ROOM //cấu hình âm thanh if let audioTrack = self.localAudioTrack { builder.audioTracks = [ audioTrack ] } } room = TwilioVideoSDK.connect(options: connectOptions, delegate: self) } func disconnectFromRoom() { room?.disconnect() } // MARK: プライベートメソッド private func toastMessage(message:String){ print("toastMessage \(message)") DispatchQueue.main.asyncAfter(deadline: .now() ) { let hud = MBProgressHUD.showAdded(to: UIApplication.shared.keyWindow!, animated: true) hud.mode = .text hud.label.text = message hud.removeFromSuperViewOnHide = true hud.hide(animated: true, afterDelay: 2) } } } extension TwilioController : RoomDelegate{ //ユーザーがルームに接続した時のイベント func roomDidConnect(room: Room) { connected = true roomStatusHandler?(.Connected) } //ユーザーがルームを出た時のイベント func roomDidDisconnect(room: Room, error: Error?) { connected = false roomStatusHandler?(.Disconnected) } //ネットワーク接続エラーまたはタイムアウト等でルームに参加できない時のイベント func roomDidFailToConnect(room: Room, error: Error) { connected = false roomStatusHandler?(.Error) } //他者がルームに参加した時のイベント func participantDidConnect(room: Room, participant: RemoteParticipant) { let message = "participant \(participant.identity) connected" toastMessage(message: message) roomStatusHandler?(.ParticipantConnected) } //参加者がルームを出た時のイベント func participantDidDisconnect(room: Room, participant: RemoteParticipant) { let message = "participant \(participant.identity) disconnected" toastMessage(message: message) roomStatusHandler?(.ParticipantDisconnected) } }
このコントローラーには、主な関数が二つあります。
・connectToRoom()はTWILIO_TEST_ROOM定数とアクセストークン(TWILIO_ACCESS_TOKEN_1またはTWILIO_ACCESS_TOKEN_2)で指定された特定のルームに接続します。
端末で実行する場合は、端末ごとに異なるアクセストークンを設定してください。また、この関数は次のイベント処理をも行ないます。
- Connected:ユーザーがルームに接続した時のイベント
- Disconnected:ユーザーがルームを出たときのイベント
- ParticipantConnected:他者がルームに参加した時のイベント
- ParticipantDisconnected:参加者がルームを出た時のイベント
- roomDidFailToConnect:ネットワーク接続エラーまたはタイムアウト等でルームに参加できない時のイベント
・disconnectFromRoom()はルームを出ます
つぎに、以下のような簡単な画面のCallViewControllerビューコントローラーを作成します。
次のコードをCallViewController.swiftファイルに入れます。
import UIKit import MBProgressHUD class CallViewController: UIViewController { @IBOutlet weak var joinButton: UIButton! @IBOutlet weak var roomTxt: UITextField! //ルームの参加ステータスが変わったら、ボタンの名前が更新されます。 private var joined = false{ didSet{ if joined { joinButton.setTitle("End call", for: .normal) }else{ joinButton.setTitle("Join", for: .normal) } } } override func viewDidLoad() { super.viewDidLoad() roomTxt.text = TWILIO_TEST_ROOM } @IBAction func joinRoom(_ sender: Any) { if !joined{ MBProgressHUD.showAdded(to: self.view, animated: true) kTwilioController.connectToRoom { (status) -> (Void) in if status == .Connected { self.joined = true } if status == .Disconnected{ self.joined = false } MBProgressHUD.hide(for: self.view, animated: true) } }else{ kTwilioController.disconnectFromRoom() } } }
ユーザーが参加したいルームの名前を入力するためのテキストフィールドと、ルームに参加または退出するためのボタンがあります。このテキストフィールドはTwilioDemoChatRoomと命名し、変更不可とします。このボタンは参加ステータスによって名前が変更され、connectToRoom()かdisconnectFromRoom()を呼び出します。
では、2台のiOS端末で実行して動作を確認しましょう。尚、このアプリはシミュレーターに対応していません。
実行にあたって端末ごとにアクセストークンを必ず変更しておいてください。
参照元: