> ## Documentation Index
> Fetch the complete documentation index at: https://documentation.onesignal.com/llms.txt
> Use this file to discover all available pages before exploring further.

# VoIP 푸시 알림

> OneSignal을 사용하여 PushKit 토큰 등록 및 VoIP 인증서로 iOS에서 VoIP 푸시 알림을 전송하고, 통화 스타일 동작을 위한 Android 대안을 알아보세요.

VoIP 푸시 알림은 앱이 백그라운드 상태이거나 종료되어 있을 때도 수신 전화 알림을 받을 수 있게 해줍니다. Apple은 VoIP 푸시를 표준 푸시 알림과 다르게 처리합니다 — 별도의 인증서 유형, 별도의 토큰(PushKit을 통해), 그리고 다른 전달 규칙을 사용합니다.

OneSignal은 VoIP 푸시 **전송**을 지원하지만, OneSignal SDK는 VoIP 토큰 등록을 처리하지 **않습니다**. 다음 작업은 직접 수행해야 합니다:

* Apple PushKit을 사용하여 앱에서 VoIP 토큰 등록
* VoIP Services Certificate로 별도의 OneSignal 앱 생성
* OneSignal REST API를 통해 토큰 등록 및 푸시 전송

### 플랫폼 차이점

| 플랫폼         | VoIP 푸시 지원 여부 | 작동 방식                              |
| ----------- | ------------- | ---------------------------------- |
| **iOS**     | Yes           | Apple PushKit 및 VoIP APNs 인증서 사용   |
| **Android** | No            | 통화 스타일 동작을 시뮬레이션하기 위해 데이터 전용 푸시 사용 |

크로스 플랫폼 통화 앱을 구축하는 경우 플랫폼별로 다른 접근 방식을 사용하게 됩니다.

***

## iOS: VoIP 푸시 알림 전송

iOS에서 VoIP 알림은 Apple PushKit을 사용하며 표준 푸시 알림과 다른 특수 전달 규칙을 따릅니다. Apple이 VoIP 푸시를 다르게 처리하므로 OneSignal은 VoIP를 위한 별도의 앱 구성을 필요로 합니다.

<Warning>
  **시작하기 전에** — 가장 흔한 VoIP 설정 실수입니다:

  1. **VoIP용 별도 OneSignal 앱을 생성하지 않는 것.** Apple은 VoIP에 다른 인증서 유형을 요구하므로 OneSignal은 VoIP 푸시를 전송하기 위한 전용 앱이 필요합니다. 기존 푸시 앱은 두 가지 모두에 사용할 수 없습니다.
  2. **잘못된 인증서 업로드.** \*\*VoIP Services Certificate(.p12)\*\*가 필요하며, 표준 APNs 푸시 인증서가 아닙니다. 잘못된 인증서를 사용하면 자동으로 전달 실패가 발생합니다.
  3. **샌드박스에서 `test_type` 누락.** 개발 빌드로 테스트할 때는 토큰을 등록할 때 반드시 `"test_type": 1`을 포함해야 합니다. 이를 생략하면 API 호출은 성공하지만 푸시가 전달되지 않습니다.
</Warning>

<Steps>
  <Step title="PushKit을 사용하여 VoIP 토큰 등록">
    Apple의 PushKit 프레임워크를 사용하여 VoIP 알림을 등록하고 VoIP 토큰을 받습니다.

    * 앱에서 PushKit 구현
    * Apple이 교체할 때 VoIP 토큰 저장 및 갱신
    * Apple의 VoIP 정책을 면밀히 준수

    <Accordion title="예시: PushKit 델리게이트 구현">
      ```swift theme={null}
      import PushKit

      class AppDelegate: NSObject, PKPushRegistryDelegate {
          func registerForVoIPPushes() {
              let registry = PKPushRegistry(queue: .main)
              registry.delegate = self
              registry.desiredPushTypes = [.voIP]
          }

          func pushRegistry(_ registry: PKPushRegistry, didUpdatePushCredentials credentials: PKPushCredentials, for type: PKPushType) {
              let token = credentials.token.map { String(format: "%02x", $0) }.joined()
              // 이 토큰을 OneSignal에 전달하세요 — 4단계 참조
          }
      }
      ```

      <Note>이것은 표준 Apple PushKit 코드입니다. OneSignal은 PushKit SDK를 제공하지 않습니다 — 토큰을 직접 등록하고 4단계에서 OneSignal에 전달합니다.</Note>
    </Accordion>

    Apple 리소스:

    * [PushKit 문서](https://developer.apple.com/documentation/pushkit)
    * [VoIP 푸시에 응답](https://developer.apple.com/documentation/pushkit/responding_to_voip_notifications_from_pushkit)
    * [Apple의 VoIP 모범 사례](https://developer.apple.com/library/content/documentation/Performance/Conceptual/EnergyGuide-iOS/OptimizeVoIP.html)
  </Step>

  <Step title="VoIP용 별도 OneSignal 앱 생성">
    Apple VoIP 푸시는 표준 푸시 알림과 다른 인증서 유형을 필요로 합니다. 하나의 OneSignal 앱은 하나의 인증서 유형만 사용할 수 있으므로 **두 개의 별도 OneSignal 앱**을 생성해야 합니다:

    * **기본 푸시 앱**: 표준 푸시 알림에 APNs 인증서 사용
    * **VoIP 푸시 앱**: VoIP 전용 알림에 VoIP Services Certificate 사용

    두 앱 모두 동일한 iOS 번들 ID를 사용해야 하며 동일한 네이티브 iOS 앱과 연결되어야 합니다. OneSignal SDK를 두 번 초기화할 필요는 **없습니다** — VoIP 앱은 API를 통해 VoIP 푸시를 전송하는 서버 측에서만 사용됩니다.

    <Note>번들 ID(예: `com.yourcompany.appname`)는 Xcode에서 타겟의 **General** 탭에서 확인할 수 있습니다.</Note>
  </Step>

  <Step title="VoIP Services Certificate 업로드">
    VoIP OneSignal 앱에서 \*\*VoIP Services Certificate(.p12)\*\*를 업로드합니다. 이것은 일반 알림에 사용하는 표준 APNs 푸시 인증서와 다른 인증서 유형입니다.

    생성 방법:

    1. [Apple Developer Portal](https://developer.apple.com/account/resources/certificates/add)로 이동합니다
    2. **VoIP Services Certificate**를 선택합니다
    3. 안내에 따라 인증서를 생성하고 다운로드합니다
    4. Keychain Access에서 열고 `.p12` 파일로 내보냅니다
    5. VoIP OneSignal 앱의 iOS 설정에 `.p12` 파일을 업로드합니다

    <Warning>
      VoIP 앱에 표준 APNs 푸시 인증서를 업로드하지 **마세요**. 잘못된 인증서 유형을 사용하면 API는 푸시 요청을 수락하지만 Apple이 이를 거부하여 알림이 전달되지 않습니다.
    </Warning>

    <Frame caption="Keychain Access의 VoIP 인증서">
      <img src="https://mintcdn.com/onesignal/jFWn5xzleD8du3j6/images/docs/6101554-Screen_Shot_2020-04-26_at_1.07.52_PM.png?fit=max&auto=format&n=jFWn5xzleD8du3j6&q=85&s=5d19f1262fdf67d5185ed8d8b4743493" alt="macOS Keychain Access에 표시된 VoIP Services Certificate" width="1868" height="1624" data-path="images/docs/6101554-Screen_Shot_2020-04-26_at_1.07.52_PM.png" />
    </Frame>

    <Frame caption="OneSignal 대시보드에 업로드된 VoIP 인증서">
      <img src="https://mintcdn.com/onesignal/0qspEXXeJ8zJbkJ-/images/docs/81a2fea-a2a2e71-Screenshot_2024-02-23_at_1.32.08_PM.png?fit=max&auto=format&n=0qspEXXeJ8zJbkJ-&q=85&s=6ee92a10fc3473c644880fa7517eb46b" alt="OneSignal 대시보드에 업로드된 VoIP Services Certificate" width="466" height="130" data-path="images/docs/81a2fea-a2a2e71-Screenshot_2024-02-23_at_1.32.08_PM.png" />
    </Frame>
  </Step>

  <Step title="OneSignal에 VoIP 토큰 등록">
    [Create User](/reference/create-user) API를 사용하여 VoIP OneSignal 앱에 VoIP 토큰을 등록합니다.

    <Warning>
      **샌드박스/개발 빌드에는 `"test_type": 1`이 필요합니다.** 이 필드를 생략하면 API 호출은 성공하고 오류가 반환되지 않지만, Apple은 해당 토큰을 프로덕션으로 처리하여 전송된 모든 푸시를 자동으로 거부합니다.
    </Warning>

    ```curl theme={null}
    curl --request POST \
         --url https://api.onesignal.com/apps/YOUR_VOIP_APP_ID/users \
         --header 'accept: application/json' \
         --header 'content-type: application/json' \
         --data '
    {
      "subscriptions": [
        {
          "type": "iOSPush",
          "token": "YOUR_VOIP_TOKEN",
          "test_type": 1
        }
      ]
    }
    '
    ```

    <Note>유효한 VoIP 토큰은 64자의 소문자 16진수 문자열입니다(예: `a1b2c3d4e5f6...`). PushKit은 iOS 시뮬레이터에서 작동하지 않으므로 유효한 토큰을 얻으려면 실제 기기를 사용해야 합니다.</Note>

    나중에 토큰을 업데이트하려면 [Update Subscription](/reference/update-subscription) API를 사용하세요.
  </Step>

  <Step title="VoIP 알림 전송">
    [Create Notification](/reference/create-message) API를 다음 매개변수와 함께 사용합니다:

    * `"apns_push_type_override": "voip"` — Apple에 이것이 VoIP 푸시임을 알립니다
    * `app_id` — VoIP 앱 ID
    * `include_subscription_ids` — 등록한 VoIP 구독 ID
    * `contents` 또는 `content_available` 중 하나가 필요합니다

    ```curl theme={null}
    curl --include \
         --request POST \
         --header "Content-Type: application/json; charset=utf-8" \
         --header "Authorization: key YOUR_REST_API_KEY" \
         --data-binary '{
      "app_id": "YOUR_VOIP_APP_ID",
      "content_available": true,
      "data": {
        "your_custom_data": "your_custom_value"
      },
      "apns_push_type_override": "voip",
      "include_subscription_ids": ["YOUR_VOIP_SUBSCRIPTION_ID"]
    }' \
    https://api.onesignal.com/notifications
    ```
  </Step>

  <Step title="VoIP 설정 확인">
    다음 경우 iOS VoIP 통합이 올바르게 작동하는 것입니다:

    1. VoIP 토큰이 **VoIP 앱**에서 iOS 푸시 구독으로 표시됩니다
    2. VoIP 푸시가 앱에서 [`pushRegistry(_:didReceiveIncomingPushWith:for:completion:)`](https://developer.apple.com/documentation/pushkit/responding_to_voip_notifications_from_pushkit)를 트리거합니다
    3. 앱이 종료되거나 백그라운드 상태일 때도 깨어납니다
  </Step>
</Steps>

***

## Android: VoIP 스타일 동작 시뮬레이션

Android는 VoIP 푸시 알림을 지원하지 않습니다. Apple PushKit과 동등한 기능이 없습니다.

대신 Android 통화 앱은 다음을 사용하여 VoIP 동작을 시뮬레이션합니다:

* 데이터 전용 푸시 알림
* 포그라운드 서비스
* 맞춤형 통화 스타일 UI

OneSignal의 일반 Android 푸시 지원과 네이티브 Android API를 결합하여 이를 달성할 수 있습니다.

**권장 접근 방식:**

* 데이터 전용 알림 전송
* 앱에서 다음과 같이 처리:
  * 포그라운드 서비스 시작
  * 통화 UI 액티비티 실행
  * 맞춤형 수신 통화 알림 표시

알림 렌더링을 가로채고 완전히 제어하려면 Android의 [Notification Service Extension](./service-extensions#notification-service-extension)을 사용하세요.

**유용한 리소스:**

* [Android 통화 앱 가이드](https://developer.android.com/guide/topics/connectivity/telecom/selfManaged)
* [수신 통화 UI 예제](https://medium.com/@dcostalloyd90/show-incoming-voip-call-notification-and-open-activity-for-android-os-10-5aada2d4c1e4)

<Info>Android 설정은 **OneSignal 전용이 아닙니다**. OneSignal은 푸시 페이로드만 전달하며 앱이 통화 동작을 처리합니다.</Info>

***

## 자주 묻는 질문

### 확인된 배달이 VoIP에서 작동하나요?

아니요. [확인된 배달](./confirmed-delivery)은 VoIP 푸시에 대해 **추적되지 않습니다**. 확인된 배달은 Notification Service Extension에 의존하는데, 이는 VoIP 알림에 대해 트리거되지 않습니다.

대신 네이티브 iOS PushKit 이벤트를 통해 수신을 추적하세요:

```swift theme={null}
pushRegistry(_:didReceiveIncomingPushWith:for:completion:)
```

이 이벤트는 기본 앱 타겟의 일부이며 별도의 확장 프로그램이 필요하지 않습니다. 자세한 내용은 [Apple의 VoIP 문서](https://developer.apple.com/documentation/pushkit/responding_to_voip_notifications_from_pushkit#3377587)를 참조하세요.

### OneSignal 대시보드에서 VoIP 알림을 전송할 수 있나요?

아니요. VoIP 알림은 `"apns_push_type_override": "voip"`와 함께 [Create Notification](/reference/create-message) API를 통해서만 전송해야 합니다. 대시보드는 이 매개변수를 지원하지 않습니다.

### VoIP 푸시가 자동으로 실패하는 이유는 무엇인가요?

VoIP 푸시는 OneSignal API에서 아무런 오류 없이 실패할 수 있습니다. 다음 체크리스트를 확인하세요:

1. **샌드박스/개발 빌드를 사용하고 있나요?** Create User API를 통해 토큰을 등록할 때 반드시 `"test_type": 1`을 포함해야 합니다. 이를 생략하면 토큰이 프로덕션으로 등록되고, Apple이 푸시를 거부하여 자동으로 실패합니다.
2. **올바른 인증서를 업로드했나요?** VoIP OneSignal 앱은 표준 APNs 푸시 인증서가 아닌 \*\*VoIP Services Certificate(.p12)\*\*를 사용해야 합니다. Keychain Access에서 두 인증서가 유사하게 보일 수 있으므로 인증서 이름이 "VoIP Services"로 시작하는지 확인하세요.
3. **올바른 OneSignal 앱으로 전송하고 있나요?** 전송 요청의 `app_id`는 기본 푸시 앱이 아닌 **VoIP 앱**이어야 합니다. `REST API Key`도 VoIP 앱에서 가져와야 합니다.
4. **VoIP 토큰이 유효한가요?** 앱이 재설치되거나 기기가 복원될 때 토큰이 만료됩니다. 토큰이 64자의 소문자 16진수 문자열이고 최근에 등록되었는지 확인하세요.
5. **앱이 `reportNewIncomingVoIPPushPayload`를 호출하나요?** iOS 13부터 Apple은 VoIP 푸시를 수신했지만 CallKit에 통화를 보고하지 않는 앱을 **종료**합니다. 이것은 Apple의 요구 사항이며 OneSignal의 제한이 아닙니다.

***

## 관련 페이지

<Columns cols={2}>
  <Card title="메시지 생성 API" icon="code" href="/reference/create-message">
    REST API를 사용하여 프로그래밍 방식으로 푸시 알림을 전송합니다.
  </Card>

  <Card title="확인된 배달" icon="circle-check" href="./confirmed-delivery">
    지원되는 플랫폼에서 푸시 알림 전달 확인을 추적합니다.
  </Card>

  <Card title="서비스 확장" icon="puzzle-piece" href="./service-extensions">
    Notification Service Extension으로 알림 처리를 맞춤화합니다.
  </Card>

  <Card title="사용자 생성 API" icon="user-plus" href="/reference/create-user">
    OneSignal API로 사용자와 구독을 등록합니다.
  </Card>
</Columns>
