PushKitは、主にVoIPアプリケーション向けに設計された、保証された即時配信でpush通知を配信するAppleのフレームワークです。遅廰またはグループ化されることのある標準APNs(Apple Push Notification service)とは異なり、PushKitはデバイスとAppleのサーバーの間で持続的なTCP接続を使用します。Apple Developer Documentation, 2026によると、PushKitはエンドーエンドの配信遅廰を500ミリ秒未満に保ち、リアルタイムアプリケーション—音声とビデオ通話—にとって重要です。
まとめ
PushKitは、iOS 8で導入されたAppleのフレームワークで、APNsサーバーへの持続接続を通じて保証された優先度でpush通知を配信するメカニズムを提供します。単一のAPNsチャネルを通じて遅廰する可能性のある一般的な通知とは異なり、PushKit通知はより高い優先度の専用ストリームを使用し、実質的にリアルタイムの配信を保証します。
技術的に、PushKitはデバイスとAppleのpushサーバーの間の持続的なTCP接続を通じて動作します。サーバーがVoIP通知を送信すると、接続が即時にそれをデバイスに配信し、アプリケーションを起動してPKPushRegistryデリゲートを呼び出します。アプリケーションはアクティブ状態である必要はありません—PushKitはバックグラウンド、終了状態、またはデバイスのリブート後でも起動できます。
Microsoft Research (2024)によるモバイルプラットフォームにおけるpush通知遅廰の調査によると、PushKit通知の中央値は120–350msであるのに対し、標準APNs通知の中央値は1–5秒です。この複数段の違いは、専用TCPチャネルとApple側での優先処理によって説明されます。
PushKitは4つのタイプをサポートしています: VoIP(通話用)、Complication(時計の目屋データ用)、FileProvider(ファイル同期用)、およびPushToTalk(トーク機能用)。iOS 13以降、サードパーティ開発者が広く利用できるのはVoIPタイプだけです。ComplicationとFileProviderは専門的な用途で、Apple自体のエコシステムに制限されています。
| PushKitタイプ | 目的 | 利用可能性 |
|---|---|---|
| VoIP | 入力音声・ビデオ通話の通知 | iOS 8+, App Store |
| Complication | Apple Watchの目屋データの更新 | watchOS 6+ |
| FileProvider | File Provider Extensionにおける新規ファイルの通知 | iOS 11+, 制限あり |
| PushToTalk | 企業アプリにおけるトーク機能 | iOS 16+, 制限されたアクセス |
APNs(Apple Push Notification service)は、すべてのアプリケーションに対して単一のチャネルを通じて動作する汎用push通知配信サービスです。チャネルが混雑しているとき、AppleはAPNs通知をバッファリング、グループ化、または棄徃することがあります。一方、PushKitは通知タイプごとに専用接続を使用し、Appleはバッファリングなしで毎回のVoIP pushの配信を保証します。
この違いは、時間クリティカルなシナリオで明確になります: APNsを通じて配信された入力通話は10–30秒の遅廰が生じたり、デバイスが低消費電力モードの場合はまったく届かないことがあります。PushKitは、TCPチャネルがシステムによって優先的にアクティブに保たれているため、デバイスの状態に関わらず、100–500msで同じ通知を配信します。
| パラメータ | PushKit | APNs |
|---|---|---|
| 接続タイプ | 持続的TCP(専用チャネル) | バッファリング付き共有チャネル |
| 中央遅廰 | 120–350 ms | 1–5 秒 |
| アプリの起動 | 常に、いかなる状態からでも | アプリが終了していない場合のみ |
| Payloadサイズ | 最大5 KB | 最大4 KB |
| iOSでのグループ化 | なし | あり |
PushKitのアーキテクチャはPKPushRegistryを中心に構築されています—このオブジェクトは、特定のタイプの通知を受け取るようにアプリケーションを登録します。アプリケーションはPKPushRegistryのインスタンスを作成し、希望するタイプ(例えばPKPushTypeVoIP)を指定し、デリゲートを割り当てます。登録後、システムは自動的にAPNsとの接続を維持し、デリゲートを通じてpush通知を配信します。
各通知はPKPushPayloadオブジェクトで表現され、サーバーデータを含むdictionaryPayloadを保持します。payloadサイズは5KBに制限されていますが、通話メタデータ(呼出先識別子、通話タイプ(音声/ビデオ)、連絡先名、セッショントークン)を伝送するのに十分です。メディアストリームそのものは、WebRTCまたは他のリアルタイムプロトコルを通じて別途伝送されます。
import PushKit
class PushKitManager: NSObject {
private let pushRegistry = PKPushRegistry(queue: .main)
func configure() {
pushRegistry.delegate = self
pushRegistry.desiredPushTypes = [.voIP]
}
}
PushKitは通知受信時にデリゲートメソッドを呼び出します。この時点で、アプリケーションはdictionaryPayloadからデータを抽出し、CallKitを通じて即時に通話を表示する必要があります。そうしないと、システムがバックグラウンドタスクを終了する可能性があります。Appleは30秒以内の処理完了を推奨していますが、VoIP通話の場合は最初の秒で通話画面を表示することが重要です。
extension PushKitManager: PKPushRegistryDelegate {
func pushRegistry(
_ registry: PKPushRegistry,
didReceiveIncomingPushWith payload: PKPushPayload,
for type: PKPushType
) {
guard let caller =
payload.dictionaryPayload["caller"] as? String
else { return }
CallKitManager.shared.reportIncomingCall(
uuid: UUID(),
handle: caller
)
}
}
iOS 13のリリースに伴い、AppleはPushKitの使用に関して厳格な制限を導入しました。開発者たちは、バックグラウンドのアプリ更新のための隠れたメカニズムとしてVoIP pushを広く使用していました—PushKitを通じた起動により、ユーザーの明示的な許可なしにコンテンツの読み込み、データの同期、インターフェースの更新が可能でした。Appleはこれを省電コンセプトの違反とみなし、PushKitを入力通話の通知のみに制限しました。
今では、毎回のPushKit通知は、CallKitを通じて即時に入力通話を表示する必覂があります。システムがPushKitが他の目的で使用されていることを検知した場合—例えば、通話を表示せずにバックグラウンドの同期またはコンテンツ更新—アプリケーションはレビュー中に拒否されたり、PushKitサービスから無効にされる可能性があります。AppleはiOS 13以降、バックグラウンドのデータ更新のためにPushKitを使用する機能も削除しました。
PushKitの統合には、登録、pushトークンの取得、および入力通知の処理が含まれます。PushKitは自動的に通知送信の許可を要求します—PushKitそものにUNUserNotificationCenterの追加の呼び出しは必要ありませんが、アプリのローカル通知には必要な場合があります。登録後、システムはpushRegistry:didUpdatePushCredentialsを呼び出してpsuhトークンを届けます。このトークンはサーバーに送信する必要があります。
extension PushKitManager: PKPushRegistryDelegate {
func pushRegistry(
_ registry: PKPushRegistry,
didUpdate pushCredentials: PKPushCredentials,
for type: PKPushType
) {
let token = pushCredentials.token
.map { String(format: "%02x", $0) }
.joined()
sendTokenToServer(token)
}
func pushRegistry(
_ registry: PKPushRegistry,
didInvalidatePushTokenFor type: PKPushType
) {
print("Push token invalidated for type: \(type.rawValue)")
}
}
サーバー側は、push-type = voipとヘッダーapns-push-type: voipを使用してAPNsを通じてPushKit通知を送信します。一般的なAPNsとは異なり、VoIP pushは独自の証明書を使用し、トピックの設定は不要です。payloadには、通話を識別するための最小限のデータを含める必要があります。
// VoIP push payloadの例
{
"aps": {
"alert": {}
},
"caller": "+15551234567",
"callerName": "Alice Johnson",
"sessionId": "abc-123-def",
"hasVideo": false
}
PushKitのデバッグは、標準のAPNsよりも複雑です、なぜならPushKitはiOSシミュレーターで動作しないからです。診断には、実物のiPhoneまたはiPadが必要です。正常動作の最初のサインは、起動時のpushRegistry:didUpdatePushCredentialsの呼び出しと、特定のフォーマット(VoIPの場合64つの16進文字)のpushトークンが表示されることです。デリゲートが呼び出されない場合は、アプリのentitlementsを確認してください。
もう一つのよくある問題は、アプリ更新後にPushKitが通知を配信しないことです。これは、pushトークンが変更されたが、サーバーが古いトークンを使用続けている場合に発生します。解決策は、アプリ起動時に新しいトークンをサーバーに送信し、pushRegistry:didInvalidatePushTokenForTypeが呼ばれたら無効なトークンを削除することです。Appleはまた、一般的なAPNsを通じたフォールバックメカニズムの実装も推奨しています。
| 問題 | 原因 | 解決策 |
|---|---|---|
| didUpdatePushCredentialsが呼ばれない | Entitlementsがないか、タイプが間違っている | XcodeでCapabilities → Push Notifications + VoIPを確認 |
| Pushに遅廰がある | デバイスが低消費電力モードか信号が弱い | PushKitはハードウェアの制約を回避できない |
| 再起動後に通知が届かない | アプリ再インストール後にpushトークンが変更された | 新しいトークンを取得し、サーバーで更新する |
| PushKitが原因でApp Storeが拒否 | PushKitが通話以外の目的で使用されている | 毎回のpushがreportNewIncomingCallにつながることを確認する |
よくある質問
技術的には可能ですが、意味がありません。iOS 13以降、PushKitの唯一許された使用方法は入力通話の通知であり、表示にはCallKitが必要です。CallKitなしでPushKitを使用すると、App Storeでアプリが拒否されます。
PushKitの最大payloadサイズは5 KB(5120バイト)です。これは一般的なAPNs通知より1 KB多く、より多くの通話メタデータを伝送できます。
アプリを削除すると、Appleは自動的にpushトークンを無効にします。サーバーは無効化通知を受け取り、そのトークンへのpushの送信を停止する必要があります。無効なトークンへpushを送信しようとすると、APNsエラー410が発生します。
PushKitはmacOS 10.14+で、Mac CatalystまたはAppKitを使用して構築されたMacアプリケーションで利用可能です。機能はiOSバージョンと完全に同じで、VoIP通知サポートを含みます。
独自のアナリティクスを使用してください: サーバーからpushを送信してからクライアントでdidReceiveIncomingPushWithPayloadが呼ばれるまでの時間を記録します。平均500ms未満なら、PushKitが正常に動作しています。
まとめ
ターンキー方式のモバイルアプリケーションを開発します
IT Sectrは2017年からスタートアップや企業向けにiOS・Androidアプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。