VoIP Push通信とは、普通のPush通知とは異なり、電話Call専用のPush通知です。
VoIPのPush通知を受信するには、iOSではPushKitを使用する必要があります。
また以前は、VoIP通信でも通常のPush通知のように使用できたのですが、現在はAppleの使用により、iOS13からはVoIP通信を受け取ったらCallKitを呼ぶ必要があり、そうしないと、VoIP通信が送られなくなってしまいます。
つまり、VoIPで電話を受信する機能を実装するには、PushKitとCallKitの両方を実装することが必須になります。
CallKitは着信のUIを開発するアプリで使用するものになります。例えばLINEで着信を受けたときなどは、通常の電話番号での電話着信と同じUIが表示されます。これを実現するためには、VoIP Push通知を受信 -> CallKitでUI表示と実装する必要があります。
なお、CallKitはUI表示のみなので、実際のビデオ電話などの機能を実装するには、他のモジュールと組み合わせて実装する必要があります。この辺はまた次回の記事にします。
この記事では、VoIP Push通信をPushKitを使用して受信する部分の実装について触れます。VoIP Pushを送る側は、AmazonのSNSを使用していますが、参考にaws cliによる方法と、Pusherというアプリを用いる方法も記載しています。
VoIP Push通知の実装
VoIPでPush通知を受信するには、以下が必須となります。
- VoIP専用の証明書の作成
- XcodeでPushKitの実装(受信側)
- 何かしらのPushを送る側の実装(送信側)
それぞれ順に手順を記載します。
CSRファイルの作成方法
VoIPの証明書を作成するために、後ほど必要になるCSRファイルを先に作成しておきます。(順番が前後しても問題はありません。)
Macの「キーチェーンアクセス」アプリを開き、「証明書アシスタント」->「認証局に証明書を要求」を選択します。
表示されるポップアップでは、以下の5項目の入力が求められます。
- ユーザのメールアドレス
- 通称
- CAのメールアドレス
- 要求の処理
- 鍵ペア情報を指定
ユーザのメールアドレス、通称、CAのメールアドレスはデフォルトのまま、「要求の処理」は「ディスクに保存」を選択、そして、「鍵ペア情報を指定」にチェックし、「続ける」をクリックします。
これでCertificate Signing Request (CSR)を作成出来ますので、デスクトップなど任意の場所に保存しておきます。このファイルは後ほど必要になります。
VoIP専用の証明書の作成方法
VoIP専用の証明書を作成するには、Apple Developer Accountが必要になります。SafariでApple Developer Accountにログインし、メニュー左側の「Certificates, ID & Profiles」を選択します。
次にVoIP専用の証明書を作成するために、まずはApp IDを作成します。専用のApp IDを作成しないと先に進めません。
App IDの作成方法
左側の「Identifier」を選択し、「+」ボタンをクリックします。
「App IDs」を選択し、「Continue」をクリックします。次に「App」もしくは「App Clip」が選択出来ますが、「App」を選択します。
表示された画面で、「Description」「Bundle ID」「Capabilities」を入力していきます。
「Description」には、リリースする時のアプリケーション名などを入力し、「Bundle ID」には、よく用いられる「com.domain.appname」の表記で入力します。
ここで入力した「Bundle ID」は後ほどXcodeで入力することになるので、忘れないようにメモなどをとっておきます。
最後に「Capabilities」には、Push Notificationsにチェックを入れます。そして右上の「Continue」でApp IDの作成完了です。
Certificatesの作成方法
次に、VoIP専用の証明書(Certificates)を作成していきます。
左側のメニューから「Certificates」を選択し、「+」ボタンをクリックします。
「Services」のセクションに、「VoIP Services Certificate」がありますので、こちらにチェックをして、右上の「Continue」をクリックします。
そうすると、App IDを選択する画面に遷移するので、先程作成したApp IDを選択します。
次にCSRファイルをアップロードする必要がありますので、先程作成した、CSRファイルをアップロードします。
これでVoIPの証明書が作成できたので、ダウンロードしてローカルに保存し、ダブルクリックして、キーチェーンに保存します。
キーチェーンに保存されたことを確認して完了です。
P12ファイルの作成方法
次に作成したVoIPファイルをサーバーにアップロードする必要があります。
今回はAmazon SNSを使用するので、P12ファイルが必要になります。
P12ファイルは、ダウンロードしたVoIPの証明書を、キーチェーンから右クリックで書き出すことで作成することが出来ます。
形式が.p12
になっていることを確認し、「保存」をクリックします。パスワードも合わせて入力します。
これでサーバーへアップロードするファイルの作成が完了です。
次は、AWSでAmazon SNSを設定していきます。
AWS SNSの設定方法
AWS consoleにログインし、SNSにアクセスします。
左側メニューの「プッシュ通知」を選択し、「プラットフォームアプリケーション」の作成をクリックします。
表示される画面でいくつかの設定と証明書のアップロードを行います。
「アプリケーション名」には、任意の文字列を入力します。
「プッシュ通知プラットフォーム」では、「Apple iOS/VoIP/Mac」を選択します。
今回は開発環境でのテストなので、「サンドボックスでの開発に使用されます」にチェックをいれます。
「プッシュ証明書タイプ」には、「VoIPプッシュ証明書」を選択します。
そして、証明書をアップロードし、パスワードを入力して「認証情報をファイルから読み込み」をクリックし、証明書を読み込ませます。そして最後に右下の「プラットフォームアプリケーションの作成」をクリックします。
次に、作成したプラットフォームアプリケーションに端末を特定するエンドポイントを入力する必要がありますが、エンドポイントを確認するには、XcodeでのPushKitの実装が先に必要になります。後ほどAWSに戻ってきます。
XcodeでPushKitを最低限実装する方法
TARGETSの設定
VoIPのPush通知を受信するためには、いくつか設定する必要があります。
Xcodeで「TARGET」->「Signing & Capabilities」にて、証明書を作成した時に指定した「Bundle ID」を入力します。
次に「+ Capabilities」をクリックして、「Background Modes」と「Push Notification」を追加します。
「Background Modes」では、最低限「Voice over IP」と「Background fetch」にチェックを入れます。「Background fetch」にチェックを入れることで、アプリが起動していない状態でもVoIPを受信することが出来るようになります。
Info.plistの確認
先程TARGETSで設定した内容が反映されていることを確認します。Required background modesの項目に以下の項目が表示されていない場合は、手動で追加してください。
AppDelegateの編集
次にいよいよPushKitの実装です。といっても最低限の実装のみの記載になりますが。
AppDelegate
で、PushKit
をimport
し各種設定するコードを実装していきます。
import PushKit
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_: UIApplication, didFinishLaunchingWithOptions _: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
setupPushKit()
return true
}
}
extension AppDelegate {
func setupPushKit() {
print("test: setupPushKit()")
let voipRegistry: PKPushRegistry = PKPushRegistry(queue: .main)
voipRegistry.delegate = self
voipRegistry.desiredPushTypes = [.voIP]
}
}
extension AppDelegate: PKPushRegistryDelegate {
func pushRegistry(_ registry: PKPushRegistry, didUpdate pushCredentials: PKPushCredentials, for type: PKPushType) {
print("test: didUpdate pushCredentials")
let pkid = pushCredentials.token.map { String(format: "%02.2hhx", $0) }.joined()
print("your device token: \(pkid)")
}
func pushRegistry(_ registry: PKPushRegistry, didInvalidatePushTokenFor type: PKPushType) {
print("test: didInvalidatePushTokenFor")
}
func pushRegistry(_ registry: PKPushRegistry, didReceiveIncomingPushWith payload: PKPushPayload, for type: PKPushType) {
print("test: didReceiveIncomingPushWith")
//incomingCall()
}
}
AppDelegate
を実装し、アプリを起動すると、Xcodeのデバッグ出力欄にdevice token
が表示されます。
表示されたdevice token
をAWS SNSのコンソールでエンドポイントとして設定します。
なお、VoIP Push通知を端末が受信すると、func pushRegistry(_ registry: PKPushRegistry, didReceiveIncomingPushWith payload: PKPushPayload, for type: PKPushType)
の関数が呼ばれるので、ここで確認をしていきます。
実際には、これが呼ばれたタイミングでCallKitと連携して、CallKitのUIを表示される流れになります。(詳細はまた後日記載しようと思います。)
AWS SNSでエンドポイントを登録する
AWSのコンソールに戻り、先程作成したSNSのプラットフォームアプリケーションを開き「アプリケーションエンドポイントの作成」をクリックします。
表示される画面で、先程Xcodeで取得した、device token
を入力します。
作成されたエンドポイントを選択し、「メッセージを発行」をクリックしてコンソールからVoIP送信を試してみます。
Xcodeのデバッグ出力欄に、didReceiveIncomingPushWith
と表示されれば成功です。
AWS SNSを別の方法で叩く
今回は、AWSのコンソールから1件手動でVoIP Pushを送信しましたが、実際に運用していく段階では手動では行わないと思います。
いくつか方法はあるのですが、今回はVoIP Push通知の疎通の確認の為に試した方法を2つ紹介します。
AWS Cli -> APNs -> Mobile への VoIP Push通知
コンソール以外にも、AWSのCliコマンドでSNSを送信することが出来ます。
VoIPのPush通知の際にはいくつか注意点があって、「間違ってしまうと送信されたように見えるが実際には届かない」という自体に陥ります。Appleの公式ドキュメントによると、送信内容が間違っていると遅れが出たりこっそりと破棄されてしまったりします。(辛い)
以下は疎通の確認が出来たコマンド例です。aws cliをインストールし設定が完了していることが前提となります。
aws sns publish \
--profile your_aws_user \
--target-arn arn:aws:sns:us-east-1:xxxxxxxxxxxx:endpoint/APNS_VOIP_SANDBOX/platform_name/your_endpoint \
--message-attributes '{ "AWS.SNS.MOBILE.APNS.PUSH_TYPE": {"DataType":"String","StringValue":"voip"}}' \
--message '{"APNS_VOIP_SANDBOX":"{\"aps\": {\"foo\":\"bar\"}}"}' \
--message-structure json
--profile
で使用するcliのprofileを指定しています。何もしていないと、regionを指定しろと怒られたりします。--target-arn
には、作成したエンドポイントの「ARN」を設定します。これはコンソール上で確認することが可能です。
重要なのは、--message-attributes
です。(全て重要ですが)
ここには、voip
を使用するという指定をします。間違って入力すると、VoIP Push通知は届きません。
Pusher -> APNs -> Mobile への VoIP Push通知
他にも「Pusher」というミニアプリを使う方法もあります。こちらは、AWSは関係ないですが、証明書さえあれば、ローカルPCからAPNsにVoIPのプッシュ通知送信依頼を送ることが出来ます。操作性もシンプルでわかりやすいです。
https://github.com/noodlewerk/NWPusher
こちらから最新のreleaseをダウンロードすることも可能です。
Release 0.7.5 · noodlewerk/NWPusher · GitHub
zipファイルをダウンロードしてダブルクリックすると、`.app`ファイルがあるので、それをダブルクリックすればアプリが立ち上がります。
ダウンロードすると開発者の顔(と思われる)のアイコンのアプリが使えるようになります。初見は少し怖いです。がちゃんと動きます。
作成した証明書と、device token
を入力して、Push
すると、直接APNsに飛ばしてくれます。端末にVoIPのPush通知が飛んでくれば成功です。
以上になります。少し長くなりましたが、ざっとVoIPを実装する手順を記載しました。次は、VoIPを受信したらCllKitと連携する部分を記載しようと思います。
ココナラというサービスをご存知ですか?
ココナラは、プログラミングやウェブ制作、デザインなどの専門知識を持つ人たちが、自分のスキルを活かしてサービスを提供する場所です。
初学者の方でも気軽に相談できるため、自分のスキルアップにも最適です。また、自分自身もココナラでサービスを提供することができ、収入を得ることができます。
ぜひ、ココナラに会員登録して、新しい世界を体験してみましょう!