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端末で実行して動作を確認しましょう。尚、このアプリはシミュレーターに対応していません。
実行にあたって端末ごとにアクセストークンを必ず変更しておいてください。
参照元:
Vietnamese
English