MENU

CallKitとTwilioを組み合わせたiPhone/iPad用IP電話アプリの開発方法

URLをコピーする
URLをコピーしました!

1.初めに

無料で電話をかけられたらいいなと思いませんか?そうは言っても、いちから電話の仕組みを実装していくのは大変な気がするし・・・、そもそも、そんなこと出来るの!?って感じですよね。

その1つの解として、 株式会社 KDDI ウェブコミュニケーションズが提供している、コミュニケーションAPIの「Twilio」を利用すると言う方法があります。「Twilio」を利用すると、電話、SMSのほか、ビデオ、チャットなどの通信手段をアプリケーションに簡単に埋め込む事ができます。

電話と言っても、実際はプッシュ通知みたいなものじゃないの?って思うかもしれませんが、幸い、CallKitという電話の機能(VoIP 機能)をアプリから直接利用出来るフレームワークが、iOS10から一般の開発者に開放されました。これは開発者にとってはけっこうなインパクト(・o・)でした。

何故なら、それまでプッシュ通知経由で無理やり実現していた事が普通に出来るようになったからです。どういう事かというと、CallKitはPushKitと組み合わせて使うことで、普通の電話がかかってきたのと同じ画面(UI)を利用出来て、また普通の電話と同じように、画面のロック中でも受信する(電話に出る)ことが出来るようになったのです。その結果、飛躍的に通話系アプリのユーザ体験(UX)の改善にも繋がりました。わざわざロックを解除したり、通知をタップして、なんてことをしなくて良くなったんです。

2.アプリOKOS(オコス)を開発しました

弊社では「Twilio」と、CallKitを使用し、決まった時間帯に電話をかけるアプリ「OKOS」(オコス)を開発しました。現在はユーザが予約した時間帯に、自動的にサーバーから電話をかけて、電話を取ると録音した音声が流れるようにしています。将来的には人対人の通話機能も実装する予定です。

一例ですが、下の画像はCallKitでiOSの電話機能を利用することによって表示出来るようになった受信画面です。
後で説明する、映画のキャンペーンのものですが、いきなり↓こんな電話が掛かってきたらファンなら気絶ものでしょ!

【iOS版受信画面(広瀬すずさん主演の『ちはやふる -結び-』)】

CallKitを使用したアプリとして、iOS版のOKOSをリリースしています。なおCallKitとは関係ありませんが、Android版OKOSもリリースしています(Androidは以前から電話の機能にアクセスできていました)。
クラウド型モーニングコールアプリ『OKOS (オコス) 』をリリース

この記事で説明したいこと

今回は主にOKOS iOS版でどうやって電話をかけているか、Twilio + iOSネイティブアプリ(CallKit、etc) + サーバーサイドの技術的な側面に焦点を当てて、以下の順番で説明しようと思います。

  • 1.初めに
  • 2.アプリOKOSを開発しました
  • 3.OKOSってどんなアプリ
  • 4.OKOSの構成
  • 5.Twilioとは
  • 6.Twilioでサーバーから電話をかけるために必要な設定
  • 7.Apple Developer Programで必要な設定
  • 8.サーバー側の実装のポイント説明
  • 9.Swift3を使用した、実装のポイント説明
  • 10.OKOSの今後の展望
  • 11.結び

3.OKOSってどんなアプリ

技術的な説明をする前に、OKOS(オコス)がどんなアプリか見てみましょう。

OKOSアプリの説明

OKOSはとてもシンプルなコールアプリです。お試しモーニングコール、各種キャンペーンコールを用意しており、コール登録すると、指定された時間帯(日本時間)に電話がかかってきます。コールには電話料金はかかりません。またOKOS2.0から登場したプレミアムコールでは、猫さんコール、武将コールなど特別なコールを用意しています。

【キャンペーンコール予約画面】


【プレミアムコール予約画面】

映画とのコラボレーション

OKOSでは、キャンペーンの1つとして、映画とのコラボレーションを行いました。映画キャンペーンに登録すると、様々な俳優さんの音声で電話がかかってくるようにしました。

過去に実施した映画キャンペーンコラボ

  • 1.映画『君の膵臓をたべたい』浜辺美波さん・北村匠海さん
  • 2.映画『鋼の錬金術師』アル(水石亜飛夢さん)・グラトニー(内山信二さん)
  • 3.映画『坂道のアポロン』中川大志さん・小松菜奈さん・真野恵里菜さん・野間口徹さん・山下容莉枝さん
  • 4.映画『ちはやふる -結び-』広瀬すずさん

映画キャンペーンに登録すると俳優さんの実名で電話が掛かってくるので、スクショを撮ってTwitterにアップする人が続出し、けっこうな人気を博しました。


【Android版受信画面(広瀬すずさん主演の『ちはやふる -結び-』)】

映画キャンペーンに関して詳しくは以下をご覧下さい。
プレスリリース「映画『ちはやふる -結び-』(3/17公開)とモーニングコールアプリ「OKOS」のコラボキャンペーン!主演の広瀬すずさんから電話で公開日をお知らせします!」

直近では、武田玲奈さん主演の『人狼ゲーム インフェルノ』映画コラボを展開しています。(2018年3月現在)

【キャンペーン予約画面】

ユーザ参加型のイベント

ユーザ参加型のイベントとして、コケコッコー選手権を開催しました。
コケコッコー選手権概要

4.OKOSの構成

さて、ここからはOKOSの技術的な説明に入ります。
まずは、概要を把握するために、簡単に、システム構成を図示します。

【システム構成図】

図の説明

登場人物

1.通話者(コール予約をして電話に出る人、iOS、Androidのスマホが対象)
2.サーバーシステム(利用者情報や、予約情報の保持、定期的に電話をかけるようにTwilioに働きかける)
3.Twilio(電話をかける)

処理

通話者が、4.自分の聴きたいキャンペーンの予約を行い。それに基づいて、定期的に、5.サーバー側からTwilioにリクエストし、Twilioが通話者に電話をかけることになります。

処理のシーケンスはホントはもっと細かく複雑ですが、ざっくり言うと上記の仕組みだけで、定期的にサーバーから電話をかけることが出来ます。

5.Twilioとは

さて、Twilioが沢山でてきましたが、Twilioってなんぞやの説明を少しします。

Twilioの来歴

Twilio(トゥイリオ)は合衆国のサンフランシスコにある企業の名前ですが、2008年に電話や、テキストメッセージの送受を簡単に行えるWebAPIサービスを公開しており、そのサービス自体を指してTwilioと呼んでいます。日本でもサービスが提供されており、KDDIウェブコミュニケーションズがその代理店となっています。OKOSでは、KDDIウェブコミュニケーションズ提供のAPIを利用しています。

Twilioで出来ること

Twilioはコミュニケーションに必要な様々な機能をAPIで提供しています。例えば以下が上げられます。

  • ・プログラムからブラウザ、アプリ等に電話をかけられる
  • ・アプリ間、ブラウザ間で電話がかけられる
  • ・かかったきた電話に自動で応答出来る
  • ・電話番号を交換せずに通話可能
  • ・電話番号を使用せずにIDを使用して通話可能
  • ・多様なAPIが用意されている
  • ・TwiMLというXML言語が用意されており、組み合わせてインタラクティブな音声通話アプリケーションと メッセージングアプリケーションの開発が出来る
  • ・最近ではチャットやビデオ通話などのコミュニケーションに使用出来るAPIも提供されている
  • ・料金は使った分のみ

実際にTwilioを使った感じでは、言うほど簡単でもないです。というのも、サンプルを動かすのは簡単に出来ますし、サンプルの範囲内で何かを開発しようとすれば簡単ですが、そこから外れて、やりたい事をやろうとすると、それなりに調べてやらないと出来ないからです。

ただし、電話の仕組みを一から実装するよりは遥かに簡単に出来ます。また、豊富なサンプルがあり、多くの言語に対応していて、サポートの方も懇切丁寧に質問に答えてくれますので、つまずいても何とかなります。

中の人が…

機能が結構なペースで追加されてるなと思っていたところ、最近Twilio+IoTのワークショップに出る機会がありました。その時に、Twilioの中の人と話したところ、これからはコミュニケーションを便利にするあらゆることを実装していくと言われてました。

参考サイト:
https://twilio.kddi-web.com/availability/

6.Twilioでサーバーから電話をかけるために必要な設定

Twilioがどんなサービスか掴めましたか?ここからは、実際にOKOSで実現している、サーバーからアプリへの電話発信の話に絞り、Twilioで電話をかける方法を説明していきます。(ブラウザ間通話、アプリ間通話もプロトタイプでは作っているのですが、ここでは、割愛します)

目次

1. Twilioをサーバーサイドプログラムで利用し電話をかける方法

Twilioをプログラムと連携するためには、まず以下が必要となります。

1.1 Twilioのアカウント開設
1.2 サーバーサイドプログラムで利用するためのトークンなどの生成と設定

1.1 Twilioのアカウント開設

まず必要なものとして、Twilioのアカウントがあります。取得の方法は簡単ですので端折ります。
https://twilio.kddi-web.com/

アカウントを作成しログインすると、ダッシュボードが以下のようになっています。

【ダッシュボード画面】

1.2 サーバーサイドプログラムで利用するためのトークンなどの生成と設定

図示すると以下のような手続きが必要となります。


【生成と設定フロー】

1.2.1 トークンの取得方法

Twilioから電話するためには、下記をサーバーサイドプログラムに埋め込む必要があります。
(a)アカウントSID(ACで始まる)
(b)APIキー(SKで始まる)
(c)APIシークレットキー(接頭文字がない)
(d)アプリケーションSID(APで始まる)(アプリ側から電話をかけたりする場合に必要、将来を見越してセット)
(e)クレデンシャルSID(CRで始まる)

(a)〜(d)の取得方法

(a)アカウントSIDはダッシュボードより取得できます。
上記、「ダッシュボード画像」のProject infoのアカウントSIDです。

(b)APIキーおよび、(c)APIシークレットキーの取得
左メニューより
「#」クリック、電話番号画面表示→ツール→APIキーと進みAPIキーを作成しますが、この時に同時にシークレットキーも作成されますので、忘れないようにメモ帳などにコピペしておいて下さい。


【APIキー一覧画面】


【新規APIキー作成画面】


【APIキー作成直後の画面】

(d)アプリケーションSIDはTwiML Appsより取得します。
「#」クリック、電話番号画面表示→ツール→TwiMLAppsと進みプラスボタンで生成します。

【TwiML Apps一覧画面】

分かりやすい名前を入れて保存します

【新規TwiML Apps作成画面】

この画面にAPで始まるアプリケーションSIDが表示されています。

【TwiML Apps編集画面】

(e)の取得方法

(e)クレデンシャルSID(CRで始まる)
TwilioはAppleのVoIPサービスを使用して、アプリケーションに電話をかけます。そのために必要なクレデンシャルSIDを生成する際に、VoIPサービス証明書が必要となります。VoIPサービス証明書の生成はまず、Apple側で行う必要があります。

以下証明書の生成を詳しく見ていきます。

7.Apple Developer Programで必要な設定

アプリではAppleのVoIPサービスを使用して、着信コールを受信しますので、Apple Developer Programでの設定を行います。

クレデンシャルSIDの生成

Apple Developer Programで、証明書とプライベートキーを取得後、Twilioのダッシュボードにプッシュクレデンシャル追加でTwilioからVoIPが使用可能となります。ここでは、プッシュクレデンシャルSIDの生成に絞って説明します。

  • 1.CSRファイルの作成
  • 2.開発用証明書[VoIP Services Certificate(.cer)]の作成
  • 3.APNs用証明書(.p12)の作成
  • 4.p12ファイルから証明書と秘密鍵を抽出
  • 5.TwilioのクレデンシャルSIDを生成
  • 6.プロビショニングプロファイルの作成(割愛)

証明書取得のためにApple Developer Programの登録(有償)が必要となります。ここでは登録の仕方は割愛します。

1.CSRファイルの作成

まずCSR(証明書署名要求)ファイルの作成(CertificateSigningRequest.certSigningRequest)を行います。macで作成します。

macより「キーチェーンアクセス」を開いて、
メニューバーの「キーチェーンアクセス」>「証明書アシスタント」>をクリックします。

【キーチェーンアクセス画面】

証明書アシスタント画面で、メールアドレスと、通称を入れて、続けるボタンを押します。

【証明書アシスタント画面1】

鍵ペアを以下のようにして続けるを押します。

【証明書アシスタント画面2】

ディスク上にCSRファイルが作成されます。

【証明書アシスタント画面3】

2.次に開発用証明書[VoIP Services Certificate(.cer)]を作成

2.1 Apple Developer Programにログインし、「Certificates, Identifiers & Profiles」に進みます。
2.2 開発用ですがVoIPはProductionの配下となっています。ひとまず左側のCertificatesより、Developmentを選択します(どれでもいいです)。
2.3 右上の「+」ボタンを押します。

【開発用証明書の作成画面1】

2.4 VoIP Services Certificateを選択します。

【開発用証明書の作成画面2】

2.5 利用するアプリのIDを選択します。

【開発用証明書の作成画面3】

2.6 最初に作成した、CSR(証明書署名要求)ファイルを選択しContinueを押せば開発用証明書[VoIP Services Certificate(.cer)]が作成されます。

【開発用証明書の作成画面4】

3.APNs用証明書(VoIP Services Certificate.p12)を作成します。

3.1 VoIP Services Certificate(.cer)をダブルクリックします。
3.2 macのキーチェーンアクセスに登録されるので、キーチェーンアクセスを開きます。該当の証明書のところで右クリックします(秘密鍵と間違えないようにして下さい。)


【キーチェーンアクセス画面1】

3.3 右クリック画面で書き出すを選びます。

【キーチェーンアクセス画面2】

3.4 パスワードを入力しOKを押します。

【キーチェーンアクセス画面3】

3.5 パスワードを入力し許可を押下で、ディスク上にAPNs用証明書が作成されます。

【キーチェーンアクセス画面4】

4.p12ファイルから証明書(cert.pem)と秘密鍵(key.pem)を抽出します

$ PATH_TO_YOUR_P12=/ディスク上のパス/voip_services.p12
$ 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

5.TwilioのクレデンシャルSIDを取得します

p12ファイルから証明書(cert.pem)と秘密鍵(key.pem)が生成出来たので、Twilioのモバイルプッシュクレデンシャルに、証明書と秘密鍵をセットしクレデンシャルSIDを取得します。

5.1 Programmable Voice→SDK→モバイルプッシュクレデンシャル一覧画面でプラスボタンを押します。

【モバイルプッシュクレデンシャル一覧画面】

5.2 各項目をセットする
わかりやす名前は、後でみて分かりやす名前にして下さい。OKOSでは、okos_yyyymmddのようにしています

5.2.1 iOS版なので、TYPEはAPN
5.2.2 証明書、プライベートキーは取得したものをセット
5.2.3 サンドボックスにチェックを付けて、保存して下さい(※本番リリース用の場合は外して下さい)。
生成したVoIPサービス証明書は、プロダクション環境でも、Appleのサンドボックスでも使用できます。このチェックボックスをオンにすると、開発プロビジョニングプロファイルに適したアップルのサンドボックスにプッシュを送信するようにTwilioに指示します。

【モバイルプッシュクレデンシャル追加画面】

5.2.4クレデンシャルSIDが表示されます。

【保存後の画面】

6.プロビショニングプロファイルの作成

開発用の証明書なので、アプリを動かすには、AppID、開発用証明書、端末を紐付ける必要がありますが、ここでは割愛します。

8.サーバー側の実装のポイント説明

前提

今回はサーバーサイドにPHPを利用していますので、下記よりPHPのライブラリを取得します。

Twilioで生成した以下が必要となります

(a)アカウントSID(ACで始まる)
(b)APIキー(SKで始まる)
(c)APIシークレットキー(接頭文字がない)
(d)アプリケーションSID(APで始まる)(アプリ側から電話をかけたりする場合に必要、将来を見越してセット)
(e)クレデンシャルSID(CRで始まる)

OKOSのテストコールをサンプルに説明します

テストコールは、クライアントのボタンをタップしたら、サーバー側から電話をかける仕様です。受信後、サーバー側の音声を再生します。ネイティブの電話のUIが立ち上がるので、ほんとに電話が掛かってくるのと同じユーザ体験が出来るところがみそです。

アプリインストール時のシーケンス

アプリインストール時の処理では、サーバーからTwilioを通じて特定の端末に電話を発信する為の準備を行います。
各々の役割と順番をシーケンス図に示します。

【アプリインストール時のシーケンス画面】

1.1 アプリ:初回起動時にサーバーにアクセス
1.2 サーバー:端末識別キーをサーバで発行
OKOSでは電話番号を使わずに、端末を識別出来る一意となるキー(以下、端末識別キー)をサーバー側で発行して、
その端末識別キーを持つ端末に対して電話をかけることにしています。
1.3 アプリ:取得後、端末識別キーをサーバーに送り、アクセストークン要求
1.4 サーバー:端末識別キーを組み込んだアクセストークンを発行
Twilioが端末を特定して電話をかけるには、その端末識別キーとTwilioで生成したトークンを
組み合わせて端末別にアクセストークンを発行し、アクセストークンをTwilio側に持たせる必要があります。
(アクセストークンは端末識別キーを利用して作成しますので、ここでTwilioが端末を特定出来ることとなります)
1.5 アプリ:アクセストークンを取得しTwilioに設定する

上記を行うことで、サーバーからTwilioを通じて特定の端末に電話を発信する準備が出来ました。
それでは、どのようにしてサーバー側から電話をかけられるのかを説明していきます。

2.ライブラリ組み込み

まず、Twilioがサーバーで利用出来るようにSDKを組み込みます。

2.1 サーバーにTwilioライブラリを組み込む
サーバーサイドにCakePHP3を利用していますので、下記よりPHPのAPIを取得します。
https://github.com/twilio/twilio-php

今回は直接twilio-php-master.zipをダウンロードします。サーバーサイドは、CakePHP3で作っていますのでvenderのフォルダの下に、twilioフォルダを作成しtwilio-php-master.zipを展開し、CakePHP3で利用出来るようにパスを通します(通し方は割愛)。以下のように置いてます(twilio-phpのバージョンによってファイルは変わると思われます)


【CakePHP3のVenderフォルダ】

3.端末識別キー生成用の処理(サーバーAPI:端末識別キーAPI)

端末識別用の一意のキーを生成するAPIです。Twilioのライブラリとは関係ないので割愛します。

4.AccessTokenの生成用の処理(サーバーAPI:アクセストークン取得API)

Twilio関連の処理はCakePHP3のComponentとして作成しています。Controllerに組み込み、RestAPIとして使用可能にしています。以下は抜粋です(CakePHPの書き方をしています)。

# AccessTokenの生成
# 予めVoiceGrantクラスと、Twimlクラスをインスタンス化します。
/*初期処理*/
// VoiceGrantインスタンス化
$this->voiceGrant = new VoiceGrant();
// Twimlインスタンス化
$this->twiml = new Twiml();

# TwilioのAccessTokenクラスを使用して、トークンを作成します。
// トークン設定
$this->token = new AccessToken(
"アカウントSID",
"APIキー", //Programmable Voice 設定>APIキー
"APIキー作成時のシークレットキー",
3600,
"端末識別キー" //クライアントから渡される、最初に生成した端末識別キー
);
// TwiML AppsアプリケーションSIDセット(利用する
$this->voiceGrant->setOutgoingApplicationSid("TwiML AppsアプリケーションSID");
// pushクレデンシャルをセット(着信通知を受信するために登録するときに使用する資格情報)
$this->voiceGrant->setPushCredentialSid(”クレデンシャルSID”);
// Add grant to token
$this->token->addGrant($this->voiceGrant);
// アクセストークン生成
$this->token->toJWT();

5.コール時のシーケンス

テストコールは、電話発信APIをアプリ側からリクエストすることで、ユーザの任意のタイミングで電話をかけさせることが出来ます。それぞれの役割、順番をシーケンス図に示します。


【テストコール時のシーケンス画像】

5.1 コール処理その1(サーバーAPI:電話発信API Twilioに電話発信をリクエストする)
クライアントからテストコールの要求を受けて、Twilioにリクエストする時の処理です。

// 発信元特定用の情報
$this->callerId = 'XXXXX';

// クライアント
$this->client = new Client(
"APIキー", //Programmable Voice 設定>APIキー
"APIキー作成時のシークレットキー",
"アカウントSID",
null,
null,
null
);

// コールパラメータの指定
$option = array(
'url' => '再生する音声ファイルのURL(https)', //電話をかける時にTwilioから呼ばれるURL
'statusCallbackMethod' => 'POST',
'statusCallback' => "コールバックのURL(https)"
'statusCallbackEvent' => array(
'initiated', 'ringing', 'answered', 'completed' //コールバック時のイベント
),
'Timeout' => 60 // タイムアウト秒数
);

// コールの取得
$calls = $this->client->calls;

// コール開始
$call = $calls->create(
'client:' . "端末識別キー" //クライアントから渡される、最初に生成した端末識別キー"
'client:' . $this->callerId, // 発信元特定用の情報
$option //コールパラメータの指定
);

// 発信後の一位となるIDを取得する
$sid = $call->sid;

$sidをCakePHPのViewでechoしてます。この時点で電話がかかります。

5.2 コール処理その2(サーバーAPI:電話をかける時にTwilioから呼ばれるAPI)
アプリ側で電話を取ると、Twilio側からAPIが呼ばれ、TwiMLを返します。

// Twimlインスタンス化
$this->twiml = new Twiml();
// 音声ファイルのURLをセットします。
$this->twiml->play($url);
// xml形式でTwimlを返す
$twiml = $this->twiml->__toString();

下記のようなXMLがレスポンスとしてTwilio返り最終的にアプリで音声が再生されます。

<?xml version="1.0" encoding="UTF-8"?><Response><Play>https://xxxxx/xxxx.mp3</Play></Response>

5.3 補足、TwiMLに関して
Twilioには、TwiMLというXMLで作る言語が用意されています。通話の着信やSMSの受信時にTwilioが行うべきことを指示するために使用される一連の命令文です。
TWIML:TWILIO マークアップ言語

9.Swift3を使用したiOSでの実装の要点説明

OKOSに電話がかかってくる、実装の要点を説明します。

1.要点

1.1 サーバーからTwilioを通して、特定のデバイスに電話を掛けられるようにアプリを実装します
※前述のアプリインストール時のシーケンスを再度載せます。
1.1.1 初回起動時のAPNsのデバイストークン登録
1.1.2 OKOSサーバーから初回起動時の端末識別キーの取得
1.1.3 OKOSサーバーからTwilioアクセストークンを取得
1.1.4 Twilioにアクセストークンを登録

1.2 電話のUIの表示、着信、切断などが出来るようにアプリを実装します
CallKit、PushKitフレームワークにある、Delegateを継承し、メソッドを実装することで可能となります。
PKPushRegistryDelegate, TVONotificationDelegate, TVOCallDelegate, CXProviderDelegateを継承します。

実際に作る場合は、下記のサンプルアプリ
を参考にして下さい。
「Twilio Voice Swift Quickstart for iOS」
https://github.com/twilio/voice-quickstart-swift#quickstart

もう少し具体的に見ていきましょう。

2.iOSで、Twilioが使えるように、XCodeにTwilioのVoiceフレームワークをPodでインストールします

参考URL:https://jp.twilio.com/docs/api/voice-sdk/ios

podファイル

source 'https://github.com/cocoapods/specs'

target 'TARGET_NAME' do
use_frameworks!

pod 'TwilioVoice', '~> 2.0'
end

3.Xcodeの初期設定(プロジェクト名TwilioCollaboは適当です)

CallKitを使用するための設定をします。

3.1 Push NotificationをON
プロジェクトのTARGETS>Capabilitiesタブで「プッシュ通知を有効にする」Push NotificationをONにします

【Push NotificationをONにする画像】

3.2 Background ModesをON
プロジェクトのTARGETS>CapabilitieタブでBackground ModesをONにします

【Background ModesをONにする画像】
3.3 voipとaudio設定
Xcode 9以降は、Voice over IPがなくなっているので、info.plistのUIBackgroundModesに、voipとaudio設定が必要です

【voipとaudio設定画像】

3.4 ターゲットの設定
CallKitはiOS10以上でしか使えません

【デプロイメントターゲットを10.0にする】

4.AppDelegate

TwilioクライアントにはAPNsのデバイストークンが必要なので、アプリ初回起動時に、APNsへのプッシュ通知登録を行い、デバイストークンを取得します(ソースは割愛)。

func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {

5.受信画面の作成

最初に起動する画面のViewControllerに電話の受信処理を記述することとします。最低限下記のライブラリ、フレームワークのインポートが必要です。

import UIKit
import AVFoundation
import PushKit
import CallKit
import TwilioVoice

5.1 MainViewControllerの作成
最初に起動する画面のViewControllerの名前をここではMainViewControllerとします。
以下のようにPKPushRegistryDelegate, TVONotificationDelegate, TVOCallDelegate,CXProviderDelegateを継承します。

class MainViewController: UIViewController, PKPushRegistryDelegate, TVONotificationDelegate, TVOCallDelegate, CXProviderDelegate,

5.2 MainViewControllerの初期処理
ほぼサンプル通りです。
VoIP プッシュ通知受信、通話のインタフェース人数などの設定、着信,発信,切断時の挙動
に関するクラスのインスタンス化、委譲の設定を行います。

required init?(coder aDecoder: NSCoder) {
// VoIP プッシュ通知を受けたときの処理用
voipRegistry = PKPushRegistry.init(queue: DispatchQueue.main)

TwilioVoice.sharedInstance().logLevel = .verbose
// 受信画面に表示されるタイトルを設定
let configuration = CXProviderConfiguration(localizedName: CommonConst.CALL_TITLE)
configuration.maximumCallGroups = 1
configuration.maximumCallsPerCallGroup = 1

// CXProvider、CXCallControllerをインスタンス変数に格納
callKitProvider = CXProvider(configuration: configuration)
callKitCallController = CXCallController()

super.init(coder: aDecoder)

callKitProvider.setDelegate(self, queue: nil)

voipRegistry.delegate = self
voipRegistry.desiredPushTypes = Set([PKPushType.voIP])

}

5.3 CXProviderDelegateのメソッドの実装
MainViewControllerにメソッドを追加し、必要な場合に処理を書きます。

PKPushRegistryDelegateのメソッドの実装
MainViewControllerにメソッドを追加し、必要な場合に処理を書きます。

//起動時
func pushRegistry(_ registry: PKPushRegistry, didUpdate credentials: PKPushCredentials, forType type: PKPushType) {
NSLog("pushRegistry:didUpdatePushCredentials:forType:")
if (type != .voIP) {
return
}

// 端末識別キーをサーバーから取得
// 端末識別キーをサーバーに送り、Twilioにセットするアクセストークン取得する
// Twilioが端末を識別し、VoIPプッシュ出来るように、アクセストークンと、初回起動時に取得したデバイストークンをセットする
TwilioVoice.sharedInstance().register(withAccessToken: accessToken, deviceToken: deviceToken) { (error) in

//着信時
func pushRegistry(_ registry: PKPushRegistry, didReceiveIncomingPushWith payload: PKPushPayload, forType type: PKPushType) {
NSLog("pushRegistry:didReceiveIncomingPushWithPayload:forType:")

if (type == PKPushType.voIP) {
TwilioVoice.sharedInstance().handleNotification(payload.dictionaryPayload, delegate: self)
}
}

5.4 TVONotificaitonDelegateのメソッドの実装
着信時に電話にでたり、発信者の名前を表示出来るように、
MainViewControllerにメソッドを追加し、必要な場合に処理を書きます。

//着信時
// MARK: TVONotificaitonDelegate
func callInviteReceived(_ callInvite: TVOCallInvite) {
NSLog("callInviteReceived:")

if (self.callInvite != nil && self.callInvite?.state == .pending) {
NSLog("Already a pending incoming call invite.");
NSLog(" >> Ignoring call from %@", callInvite.from);
return;
} else if (self.call != nil) {
NSLog("Already an active call.");
NSLog(" >> Ignoring call from %@", callInvite.from);
return;
}

self.callInvite = callInvite

// 発信者の情報を取得する
let from: String = (self.callInvite?.from)!

// 着信時の処理
// 発信者の名前をセットする
let callHandle = CXHandle(type: .generic, value: from)

let callUpdate = CXCallUpdate()
callUpdate.remoteHandle = callHandle
callUpdate.supportsDTMF = true
callUpdate.supportsHolding = false
callUpdate.supportsGrouping = false
callUpdate.supportsUngrouping = false
callUpdate.hasVideo = false

// ココに入ったらCallKitの電話受信画面が表示される
callKitProvider.reportNewIncomingCall(with: uuid, update: callUpdate) { error in
if let error = error {
NSLog("Failed to report incoming call successfully: \(error.localizedDescription).")
return
}
// RCP: Workaround per https://forums.developer.apple.com/message/169511
TwilioVoice.sharedInstance().configureAudioSession()
}
}

以上、サーバー側、アプリ側の実装の要点をかいつまんで説明しました。
Twilioで簡単に電話出来ることがわかったでしょうか?

※ソースの説明は要点のみですので、このまま書いても動きません。
もし疑問がある場合はご一報下さい。

OKOSの紹介、CallKit、Twilioの説明、電話をかけるためのソースの紹介は以上です。
OKOSは以下からダウンロード出来ますので、インストールして実際にご使用下さい。

OKOS iOS版ダウンロード

OKOS Android版ダウンロード

10.OKOSの今後の展望

さて、OKOSもリリースして数ヶ月が過ぎました、認知度も高まり、ユーザ数も増えつつあります。今後も盛り沢山な内容を構想中です。ここで少し、次の展開を紹介しておきましょう。キャンペーンや予約コールだけではなく、もっと恒常的に使いたいと言う要望に答えて以下のコンテンツを追加していく予定です。

  • ●天気予報、占いなど恒常的に使用出来るコンテツの追加
  • ●ブラウザで電話する機能
  • ●OKOSのプログレッシブウェブアプリ(Progressive Web Apps)化
  • ●自然言語処理などAIとの連携
  • ●スマートスピーカーなどIoT連携
  • ●これから上映予定の映画のキャンペーン
  • ●コケコッコー選手権2018のようなイベント

11.結び

駆け足ですが、Twilioを利用して無料で電話をかける方法について概観してきました。TwilioにはOKOSで使っている機能だけではなく、まだまだ多様な機能があります。Twilioは、IP電話のサービスから始まり、VideoやChatの機能までカバーするようになるとともに、最近では、「Twilio Studio」というノンプログラマでもコミュニケーションワークフローを構築出来るツールや、「Twilio Flex」というコンタクトセンター構築のためのクラウドアプリケーションプラットフォームなどを発表しています。
凄く攻めてる感がありますよね。

弊社でもOKOSで、またはOKOSとは別に、Twilioの機能を利用し、コミュニケーションを中心に据えた役に立つプロダクトを開発したいと考えています。ブログも随時追記していく予定です。

最後に、この記事を読まれて、興味をお持ちになった方は下記までご連絡下さい。
OKOSへのお問い合わせ

読んでいただきありがとうございました。

よかったらシェアしてね!
URLをコピーする
URLをコピーしました!
目次
閉じる