Twilio Voice Swift Quickstart for iOS
iOSでVoiceを始めよう:
- Quickstart - クイックスタートアプリを実行する
- Access Tokens - アクセストークンを使用
- Managing Audio Interruptions - 音声の中断の管理
- Managing Push Credentials - プッシュ認証情報の管理
- More Documentation - Voice iOS SDKに関連するその他のドキュメント
- Issues and Support - ファイリングの問題と一般的なサポート
Quickstart
クイックスタートアプリケーションを使い始めるには、次の手順に従います。
手順1〜6により、アプリケーションは電話をかけることができます。
残りの手順7〜10では、アプリケーションはAppleのVoIPサービスを使用してプッシュ通知の形式で着信通話を受信できるようになります。
- TwilioVoice frameworkをインストールする
- Voice API keyを作成する
- アプリで使用するアクセストークンを生成するようにサーバーを構成する
- TwiML applicationを作成する
- アプリケーションサーバーを設定する
- アプリを実行する
- VoIP Service Certificateを作成する
- VoIP Service Certificateを使ってPush Credentialを作成する
- XcodeのプロジェクトにVoIPpush通知の設定をする
- 着信を受ける
- clientからclientに電話をかける
- clientからPSTNに電話をかける
1. TwilioVoice frameworkをインストールする
Carthage
Cartfileに次の行を追加します。
github "twilio/twilio-voice-ios"
carthage bootstrap
を実行します (SDKをアップデートしている場合は carthage update
を実行します)
対象のapplication targetの Build Phases
タブにて, +
アイコンをクリックして、 New Run Script Phase
を選びます。 Run Scriptにshell(ex: /bin/sh
)を指定し , 以下の内容のscriptを追加します:
/usr/local/bin/carthage copy-frameworks
“Input Files”の下に、使用したいframeworkのパスを追加します:
$(SRCROOT)/Carthage/Build/iOS/TwilioVoice.framework
Cocoapods
quickstartのフォルダ内でpod install
を実行すると、Cocoapodsがworkspaceを作成します。
また、必ず Cocoapods v1.0 以降を使用してください。
Cocoapodsのインストールが完了し,SwiftVoiceQuickstart.xcworkspace
を開くとSwiftを用いた基本的なquickstartプロジェクトとCallKit quickstartプロジェクトが見つかります。
Note: TwilioVoice の最新版を取得するには、pod repo update master
を実行し CocoaPods Master Spec Repo から最新版を取得する必要があるかもしれません。
2. Voice API keyを作成する
Voice API Keys ページに移動して新しいAPI keyを作成してください:
作成したAPI_KEY
と API_KEY_SECRET
をメモをとってください。 次のステップで必要となります。
3. アプリで使用するアクセストークンを生成するようにサーバーを構成する
サーバー用のスタータープロジェクトの1つをダウンロードします。
- voice-quickstart-server-java
- voice-quickstart-server-node
- voice-quickstart-server-php
- voice-quickstart-server-python
サーバーのREADMEに記載されている手順に従って、アプリケーションサーバーをローカルで起動し、パブリックインターネット経由でアクセスできるようにします。consoleから取得できる Twilio Account SID と先ほどメモをとった API_KEY
と API_SECRET
を置き換えてください。
ACCOUNT_SID = 'AC***'
API_KEY = 'SK***'
API_KEY_SECRET = '***'
4. TwiML applicationを作成する
次にTwiMLアプリケーションを作成する必要があります。TwiML applicationは TwiML呼び出し先に設定されているパブリックURLを参照します。
iOSアプリがTwilioを呼び出すと、TwilioはこのURLにWebhookを用いてリクエストを送信し、アプリケーションサーバーはTwiMLを生成してResponseを返し、返ってきたResponseに沿ってTwilioは応答します。
TwiMLアプリケーションを作成するには TwiML app pageにアクセスしてください。
新しいTwiML applicationを作成し, アプリケーションサーバーの/makeCall
エンドポイントをVoice Request URLに設定します。(あなたのアプリケーションサーバーがPHPで書かれている場合、最後に .php
拡張子が必要です)。
ご覧の通りRequest URLにはngrokのパブリックアドレスを使用しています。
TwiML Applicationの設定を保存し, TwiML Application SID(AP
から始まる長い識別子)を取得します。
5. アプリケーションサーバーを設定する
残りの APP_SID
設定情報をサーバーのコードに入れましょう。
ACCOUNT_SID = 'AC***'
API_KEY = 'SK***'
API_KEY_SECRET = '***'
APP_SID = 'AP***'
それが終わったら、サーバーを再起動して新しい設定情報を使用します。今度はテストする時が来ました。
ブラウザを開き、アプリケーションサーバーのAccess Tokenを取得するためのURLをご覧ください。
Access Token endpoint: https://{YOUR_SERVER_URL}/accessToken
(あなたのアプリケーションサーバーが、PHPで書かれている場合は、最後に.php拡張子をつける必要があります)
すべてが正しく設定されていれば、長い文字列と数字が表示されるはずです。これがTwilioアクセストークンです。iOSアプリはTwilioに接続するためにこのようなトークンを使用します。
6. アプリを実行する
それではSwiftVoiceQuickstart.xcworkspace
に戻りましょう。baseURLString
をngrokのパブリックURLで更新します。
import UIKit
import AVFoundation
import PushKit
import TwilioVoice
let baseURLString = "https://3b57e324.ngrok.io"
let accessTokenEndpoint = "/accessToken"
let identity = "alice"
let twimlParamTo = "to"
class ViewController: UIViewController, PKPushRegistryDelegate, TVONotificationDelegate, TVOCallDelegate, AVAudioPlayerDelegate, UITextFieldDelegate {
アプリをビルドして実行します
テキストフィールドを空のままにして、callボタンを押して通話を開始します。お祝いメッセージが聞こえます。別のclientまたは番号への発信は、手順11および12で説明されています。切断するには、"Hang Up"をタップします。
7. VoIP Service Certificateを作成する
Programmable Voice SDKはAppleのVoIPサービスを使用して、着信呼び出しを受信したことをアプリケーションに通知します。ユーザーに着信を受けさせる場合は、アプリケーションでVoIPサービスを有効にしてVoIP Services Certificateを生成する必要があります。
Apple Developer portalへアクセスして、以下を行う必要があります:
- 証明書を作成できるようにApple Developer Programの会員になる。
- 対象のApp IDで“Push Notifications”サービスが有効になっていることを確認してください。
- App IDに対応するプロビジョニングプロファイルを作成します。
- Certificates - > Productionに移動し、右上の
+
をクリックして新しい証明書を追加して、このアプリのApple VoIP Services Certificateを作成します。
8. VoIP Service Certificateを使ってPush Credentialを作成する
Keychain Accessを使用してVoIP Service Certificateを生成したら、それをTwilioにアップロードして、Twilioがあなたに代わってアプリにプッシュ通知を送信できるようにする必要があります。
VoIPサービス証明書をKeychain Accessから.p12ファイルとしてエクスポートしてから、opensslコマンドを使用して.p12ファイルから証明書と秘密鍵を抽出します。
.p12が書き出しのオプションではない場合は、Keychain Accessの検索バーにvoip
を入力して、証明書を書き出すときに必ず両方の項目を選択してください。
$> openssl pkcs12 -in PATH_TO_YOUR_P12 -nocerts -out key.pem
$> openssl rsa -in key.pem -out key.pem
$> openssl pkcs12 -in PATH_TO_YOUR_P12 -clcerts -nokeys -out cert.pem
Push Credentials pageに移動して新しいPush Credentialを作成します。証明書と秘密鍵を貼り付けます。plaintextとしてキーを貼り付ける必要があります:
-
cert.pem
の-----BEGIN CERTIFICATE-----
から-----END CERTIFICATE-----
まで貼り付ける必要があります。 -
key.pem
の-----BEGIN RSA PRIVATE KEY-----
から-----END RSA PRIVATE KEY-----
まで貼り付ける必要があります。
「Sandbox」オプションを必ずチェックしてください。これは重要。生成したVoIP Service Certificateは、本番環境でもAppleのsandbox infrastructureでも使用できます。このチェックボックスをオンにすると、開発プロビジョニングプロファイルに適したApplesandbox infrastructureにプッシュが送信されます。
アプリのストア送信準備が整ったら、「APS Environment:production」でplistを更新し、同じVoIP Certificateを使用して「Sandbox」オプションをチェックせずに別のPush Credentialを作成します。
それでは、サーバーのコードに戻り、Push Credential SIDを更新しましょう。Push Credential SIDがアクセストークンに埋め込まれます。
PUSH_CREDENTIAL_SID = 'CR***'
9. Xcodeプロジェクト設定にプッシュ通知の設定をする
プロジェクトの Capabilities タブで,“Push Notifications”を有効化します。
Xcode 8以前では、バックグラウンドモードで “Voice over IP” と “Audio, AirPlay Picture in Picture” の両方の機能を有効にします。
Xcode 9以降では、“Audio, AirPlay and Picture in Picture”機能が有効になっていることと、"audio"と"voip"を含む"UIBackgroundModes"がアプリのplistにあることを確認してください。
<key>UIBackgroundModes</key>
<array>
<string>audio</string>
<string>voip</string>
</array>
10. 電話を受ける
これで着信を受ける準備が整いました。アプリをRebuildして、アプリケーションサーバーのエンドポイント /placeCall にアクセスします。 https://{YOUR_SERVER_URL}/placeCall
(あなたのアプリケーションサーバーがPHPで書かれている場合、最後に .php
拡張子が必要です)
これによりTwilio REST APIリクエストがトリガーされ、モバイルアプリへのインバウンドコールが行われます。アプリが通話を受け付けると、お祝いのメッセージが聞こえます。
11. client から client に発信する
clientからclientへの発信を行うには、2つのデバイスでアプリケーションを実行する必要があります。 追加のデバイスでアプリケーションを実行するには、新しいデバイスを登録するときに必ずアクセストークンに別のIDを使用してください。例えば, identity
を bob
に変更してアプリを実行します。
let accessTokenEndpoint = "/accessToken"
let identity = "bob"
let twimlParamTo = "to"
テキストフィールドを使用して通話受信者のIDを指定してから、“Call”ボタンをタップして発信します。 TwilioVoice.call()
メソッドで使用されるTwiMLパラメーターはサーバーで使用されている名前と一致する必要があります。
12. client から PSTN に発信する
検証済電話番号を一つ用意します。検証済電話番号はTwilioから外線発信できるあなたの電話番号が使えます。この番号はTwilioに移植されていないので、この電話番号のためにTwilioに支払う必要はありません。
clientから発信するためには, まずhttps://jp.twilio.com/console/phone-numbers/verified から検証済電話番号を取得します。 サーバーコードの CALLER_NUMBER
を検証済電話番号に置き換えます。サーバーを再起動させて、新しい設定値を使用します。TwiML applicationのVoice Request URLはパブリックなアプリケーションサーバーのエンドポイント/makeCall
を指定する必要があります。
Access Tokens
access tokenはサーバーコンポーネントのjwtにより作成されます。
作成されたaccess tokenにはProgrammable Voiceのgrant
、あなたが指定した identity
、有効期限を設定するtime-to-live
が含まれます。time-to-live
の初期値は1時間でTwilio helper ライブラリを使用して最大24時間まで設定することができます。
用途
iOS SDKでは、access tokenは次の目的で使用されます:
-
TwilioVoice.call(...)
経由で外線発信する -
TwilioVoice.registerWithAccessToken(...)
とTwilioVoice.unregisterWithAccessToken(...)
経由で着信時のVoIP Push Notificationsの登録、解除。登録されると着信時にTVOCallInvite
経由で承認するか拒否するか選ぶことができます。着信を受けるときはaccess tokenは必要ありません。TVOCallInvite
は内部的にaccess tokenを保持しており、それは私たちのインフラストラクチャにアクセスすることができます。
有効期限切れ
前述のように、アクセストークンは最終的に期限切れになります。アクセストークンが期限切れになった場合、私たちのインフラストラクチャは登録時に TVOCallDelegate
を介して TVOErrorAccessTokenExpired
/ 20104
エラーまたはcompletionエラーを返します。
アクセストークンの有効期限を適切に管理するテクニックは数多くあります:
- 発信呼び出しを行う前に、必ずアクセストークンサーバーから新しいアクセストークンを取得してください。
-
TVOErrorAccessTokenExpired
/20104
エラーが発生するまでアクセストークンを保持し、エラーが発生した後に新しいトークンを取得してください。 - アクセストークンを要求されたときのタイムスタンプと一緒に保存しておくと、サーバーで使用されている「有効期限」に基づいて、トークンがすでに期限切れになっているかどうかを事前に確認できます。
- 発信呼び出しに関連付けられた
UIApplication
またはUIViewController
が作成されるたびにアクセストークンをフェッチします。
Managing Audio Interruptions
iOSのバージョンが異なると AVAudioSession 割り込みの処理方法が若干異なります。このセクションでは、Programmable Voice iOS SDKが音声の中断を管理し、中断が終了した後に通話の音声を再開する方法について説明します。 iOSでは、中断が終了したことを示すために必要な通知が提供されないため、SDKが通話音声を自動的に再開できない場合があります。
Programmable Voice iOS SDKがオーディオの中断をどのように処理するか
- SDKは自身を
TwilioVoice.initialize()
の中でAVAudioSessionInterruptionNotification
のオブザーバーとして登録します。 - 通知が発生し、中断の種類が
AVAudioSessionInterruptionTypeBegan
の場合、SDKは自動的にオーディオデバイスを無効にし、アクティブな通話を保留にします。 - SDKが
AVAudioSessionInterruptionTypeEnded
で通知を受け取ると、SDKはオーディオデバイスを再度有効にしてアクティブな通話のオーディオを再開します。 - iOS 8と9では、
AVAudioSessionInterruptionTypeEnded
による割り込み通知が常に発生するわけではないため、SDKは通話音声を自動的に再開できません。これは既知の問題であり、別の方法はUIApplicationDidBecomeActiveNotification
を使用して中断後にアプリが再びアクティブになったときに音声を再開することです。
異なるiOSバージョンでの通知
以下は、音声の中断を引き起こし、Voice SDKの通話中に再開するためのさまざまな手順で受信したシステム通知の一覧です。 (アプリがアクティブなVoice SDK通話中であると仮定します)
シナリオ | 中断通知の開始 | 中断終了の通知 | 通話の再開? | Note |
---|---|---|---|---|
PSTN割り込み | ||||
A. PSTN割り込み PSTN着信通話を受け入れる 電話相手が電話を切る |
iOS 9 iOS 10 iOS 11 |
iOS 9 iOS 10 iOS 11 |
iOS 9 iOS 10 iOS 11 |
|
B. PSTN割り込み PSTN着信通話を受け入れる 自分が電話を切る |
iOS 9 iOS 10 iOS 11 |
iOS 9 iOS 10 iOS 11 |
iOS 9 iOS 10 iOS 11 |
|
C. PSTN割り込み PSTNを拒否 |
iOS 9 iOS 10 iOS 11 |
iOS 9 iOS 10 iOS 11 |
iOS 9 iOS 10 iOS 11 |
|
D. PSTN割り込み PSTNを無視 |
iOS 9 iOS 10 iOS 11 |
iOS 9 iOS 10 iOS 11 |
iOS 9 iOS 10 iOS 11 |
|
E. PSTN割り込み 自分が応答する前に相手が電話を切る |
iOS 9 iOS 10 iOS 11 |
iOS 9 iOS 10 iOS 11 |
iOS 9 iOS 10 iOS 11 |
|
そのほかのAudio Interruption (例えばYouTubeアプリ) |
||||
F. YouTubeアプリに切り替えてビデオを再生する ビデオを停止 Voiceアプリに戻る |
iOS 9 iOS 10 iOS 11 |
iOS 9 iOS 10 iOS 11 |
iOS 9 iOS 10 iOS 11 |
中断終了通知はiOS 9では発生しません。 iOS 10/11でVoiceアプリに切り替えた後、数秒まで割り込み終了通知は発生しません。 AVAudioSessionInterruptionOptionShouldResume フラグは false です。 |
G. YouTubeアプリに切り替えてビデオを再生する ビデオを停止せずにVoiceアプリに戻る |
iOS 9 iOS 10 iOS 11 |
iOS 9 iOS 10 iOS 11 |
iOS 9 iOS 10 iOS 11 |
中断終了通知はiOS 9では発生しません。 iOS 10/11でVoiceアプリに切り替えた後、数秒まで割り込み終了通知は発生しません。 AVAudioSessionInterruptionOptionShouldResume フラグは false です。 |
H. YouTubeアプリに切り替えてビデオを再生する ホームボタンを2回押してYouTubeアプリを終了する Voiceアプリに戻る |
iOS 9 iOS 10 iOS 11 |
iOS 9 iOS 10 iOS 11 |
iOS 9 iOS 10 iOS 11 |
Voiceアプリがアクティブ状態に戻るまで、中断終了通知は発生しません。AVAudioSessionInterruptionOptionShouldResume フラグは false です。 |
CallKit
iOS 10以降では、CallKit(統合されている場合)は、一連のデリゲートメソッドを提供することで中断を処理し、アプリケーションが適切なオーディオデバイスの処理と状態の遷移で応答できるようにします。
Notifications & 割り込み中のコールバック
CallKitフレームワークへの呼び出しを報告するときに CXCallUpdate
オブジェクトの supportsHolding
フラグを有効にすることで、別のPSTNまたはCallKit対応の呼び出しがあるときに**"Hold&Accept"** オプションが表示されます。 “Hold&Accept” オプションを押すと、一連のシナリオとコールバックが起こります:
-
provider:performSetHeldCallAction:
delegateメソッドはCXSetHeldCallAction.isOnHold = YES
で呼び出されます。ここで音声通話を保留にして、操作を実行します。 -
AVAudioSessionInterruptionNotification
はAVAudioSessionの中断が始まったことを示すために起動されます。 - CallKitはあなたのアプリのAVAudioSessionを無効にし、
provider:didDeactivateAudioSession:
コールバックを起動します。あなたはTwilioVoice.audioEnabled = NO
を呼び出してSDKオーディオデバイスを無効にする必要があります。 - 割り込んだ電話が終了した時、
AVAudioSessionInterruptionNotification
を通知します。システムがそれを通知した時、provider:performSetHeldCallAction:
メソッドを再度呼ぶことで、あなたは中断された通話を再開することができます。Note 割り込みコールがリモートパーティによって切断された場合、このコールバックは実行されません。 - AVAudioSessionが再度有効化されます。あなたは
provider:didActivateAudioSession:
メソッド内にて、TwilioVoice.audioEnabled = YES
を行い、再度SDKのaudio deviceを有効化する必要があります。
シナリオ | 中断後に音声を再開しますか? | Note |
---|---|---|
A. 保留 & 承認 自分が電話を切る |
iOS 10 iOS 11 |
|
B. 保留 & 承認 相手が電話を切る |
iOS 10 iOS 11 |
割り込みが終了してもprovider:performSetHeldCallAction: は呼ばれません。 |
C. 保留 & 承認 システムUIで音声通話に戻る |
iOS 10 iOS 11 |
|
D. 拒否する |
iOS 10 iOS 11 |
|
割り込まれた通話に応答しないため、通話の中断は発生しません。 | ||
E. 無視する |
iOS 10 iOS 11 |
割り込まれた通話に応答しないため、通話の中断は発生しません。 |
ケース2の場合、CallKitは provider:performSetHeldCallAction:
メソッドを呼び出して通話音声を自動的に再開しませんが、システムUIは音声通話がまだ保留中であることを示します。あなたは**"Hold"**ボタンを使って呼び出しを再開することができます、あるいは CXSetHeldCallAction
を使ってプログラムで保留状態を解除することができます。アプリはまた、ユーザーの混乱を避けるために通話の「保留」状態を示すためにUI状態を更新する責任があります。
// Resume call audio programmatically after interruption
CXSetHeldCallAction *setHeldCallAction = [[CXSetHeldCallAction alloc] initWithCallUUID:self.call.uuid onHold:holdSwitch.on];
CXTransaction *transaction = [[CXTransaction alloc] initWithAction:setHeldCallAction];
[self.callKitCallController requestTransaction:transaction completion:^(NSError *error) {
if (error) {
NSLog(@"Failed to submit set-call-held transaction request");
} else {
NSLog(@"Set-call-held transaction successfully done");
}
}];
Managing Push Credentials
push認証情報はプッシュ通知チャネルのレコードです。iOSの場合、このpush認証情報はAPNS VoIPのプッシュ通知チャネルレコードです。push認証情報はMobile Push Credentialsで管理されます。
iOS SDKの TwilioVoice.registerWithAccessToken:deviceToken:completion
を介して登録が実行されるたびに、JWTベースのアクセストークンより identity
とPush Credential SID
が提供されます。電話をかけるたびにidentity
、 Push Credential SID
とdevice token
をユニークなアドレスとしてAPNS VoIP push通知を送信します。TwilioVoice.unregisterWithAccessToken:deviceToken:completion
を使うと、その identity
に対する関連付けが削除されます。
Push Credentialの更新
Appleから提供された認証情報を変更または更新する必要がある場合は、consoleでPush Credentialを選択し、次に示すPush Credentialページのテキストボックスに新しいcertificate
とprivate key
を追加します。
Push Credentialの削除
作成したアプリケーションが使用されていない場合を除き、プッシュ資格情報を削除することはお勧めしません。
APNS VoIP証明書がもうすぐ期限切れになるか期限切れになった場合は、Push Credentialを削除しないでください。 代わりに、「Push Credentialの更新」セクションに従ってPush Credentialを更新する必要があります。
Push Credentialが削除されるとこのPush Credentialで行われた関連登録はすべて削除されます。将来的にこの削除されたPush CredentialのPush Credential SIDを使用して登録されたidentity
を参照しようとすると失敗するでしょう。
確実にPush Credentialを削除したい場合は、選択したPush CredentialページでDelete this Credential
をクリックしてください。
Push Credentialを削除した後、新しいアクセストークンを生成するときには必ずPush Credential SIDを削除または置き換えてください。
More Documentation
あなたは以下のgetting startedとAppleの最新ドキュメントより、たくさんのドキュメントを見つけることができます。
Twilio Helper Libraries
TwiMLとProgrammable Voice Calls APIの使用方法の詳細については、TwiMLクイックスタートをご覧ください。:
- TwiML Quickstart for Python
- TwiML Quickstart for Ruby
- TwiML Quickstart for PHP
- TwiML Quickstart for Java
- TwiML Quickstart for C#
Issues and Support
あなたが見つけた問題をGithubで提出してください: Voice Swift Quickstart.
問題を報告する際にPersonally Identifiable Information(PII)または機密アカウント情報(APIキー、資格情報など)を共有していないことを確認してください。
Voice SDKに関する一般的なお問い合わせはfile a support ticketをご覧ください。
License
MIT