# VoIP-пуши

В iOS 8 Apple представила [PushKit](https://developer.apple.com/library/prerelease/ios/documentation/NetworkingInternet/Reference/PushKit_Framework/index.html), а также VoIP-пуши — новый тип push-уведомлений. Помимо стандартной функциональности push-уведомлений, VoIP-пуш позволяет приложению выполнять код перед отображением уведомления пользователю.

<Aside type="caution" title="Важно">
Вы можете создать VoIP-сертификат только в production-режиме, а не в development-режиме. Поэтому в конфигурации iOS-приложения в Pushwoosh всегда следует использовать **Production** gateway для VoIP-сертификатов.
</Aside>


**1.** Добавьте модуль PushwooshVoIP в ваш проект.

**Swift Package Manager**
<img src="/ios-voip-1.webp" alt=""/>

<Aside type="caution" title="Важно">
Модули ```PushwooshFramework```, ```PushwooshCore```, ```PushwooshBridge``` и ```PushwooshLiveActivities``` **обязательны**.
</Aside>

**Cocoapods**
```bash
# Uncomment the next line to define a global platform for your project
# platform :ios, '9.0'

target 'MyApp' do
  # Comment the next line if you don't want to use dynamic frameworks
  use_frameworks!

  pod 'PushwooshXCFramework'
  pod 'PushwooshFramework/PushwooshVoIP'

end
```

**2.** На вкладке ```Signing & Capabilities``` добавьте возможность **Voice over IP**, установив соответствующий флажок, как показано на скриншоте ниже:
<img src="/ios-voip-2.webp" alt=""/>

**3.** Инициализируйте модуль ```PushwooshVoIP```, как показано в коде ниже.

```swift
import UIKit
import PushwooshFramework
import PushwooshVoIP
import CallKit
import PushKit

@main
class AppDelegate: UIResponder, UIApplicationDelegate, PWVoIPCallDelegate {

    func application(_ application: UIApplication,
                     didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

        /// Инициализирует модуль Pushwoosh VoIP.
        ///
        /// - Параметры:
        ///   - supportVideo: Логическое значение, указывающее, поддерживаются ли видеозвонки.
        ///   - ringtoneSound: Имя файла пользовательского рингтона для входящих вызовов (например, `"mySound.caf"`).
        ///   - handleTypes: Тип поддерживаемого дескриптора вызова. Возможные значения:
        ///     - `1` – Общий
        ///     - `2` – Номер телефона
        ///     - `3` – Адрес электронной почты
        Pushwoosh.VoIP.initializeVoIP(true, ringtoneSound: "mySound.caf", handleTypes: 1)

        // Установите делегата для получения событий VoIP-звонков
        Pushwoosh.VoIP.delegate = self

        return true
    }

    // MARK: - Обязательные колбэки PWVoIPCallDelegate

    func voipDidReceiveIncomingCall(payload: PushwooshVoIP.PWVoIPMessage) {
        // Обработка входящего VoIP-пуша
    }

    func pwProviderDidReset(_ provider: CXProvider) {
        // Обработка сброса провайдера
    }

    func pwProviderDidBegin(_ provider: CXProvider) {
        // Обработка активации провайдера
    }
}

```

**4.** Протокол ```PWVoIPCallDelegate``` определяет обязательные и необязательные колбэки для обработки жизненного цикла VoIP-звонков и взаимодействий с CallKit.

```swift
@objc public protocol PWVoIPCallDelegate: NSObjectProtocol {

    /// Вызывается при получении входящего VoIP-пуша.
    @objc func voipDidReceiveIncomingCall(payload: PushwooshVoIP.PWVoIPMessage)

    /// Необязательно: Вызывается, когда входящий вызов был успешно передан в CallKit.
    @objc optional func voipDidReportIncomingCallSuccessfully(voipMessage: PushwooshVoIP.PWVoIPMessage)

    /// Необязательно: Вызывается, если не удалось передать входящий вызов в CallKit.
    @objc optional func voipDidFailToReportIncomingCall(error: Error)

    /// Необязательно: Вызывается при начале нового исходящего вызова.
    @objc optional func startCall(_ provider: CXProvider, perform action: CXStartCallAction)

    /// Необязательно: Вызывается при завершении активного вызова.
    @objc optional func endCall(_ provider: CXProvider, perform action: CXEndCallAction, voipMessage: PushwooshVoIP.PWVoIPMessage?)

    /// Необязательно: Вызывается при ответе на входящий вызов.
    @objc optional func answerCall(_ provider: CXProvider, perform action: CXAnswerCallAction, voipMessage: PushwooshVoIP.PWVoIPMessage?)

    /// Необязательно: Вызывается при включении или выключении звука вызова.
    @objc optional func mutedCall(_ provider: CXProvider, perform action: CXSetMutedCallAction)

    /// Необязательно: Вызывается при удержании или снятии с удержания вызова.
    @objc optional func heldCall(_ provider: CXProvider, perform action: CXSetHeldCallAction)

    /// Необязательно: Вызывается при воспроизведении DTMF-тона.
    @objc optional func playDTMF(_ provider: CXProvider, perform action: CXPlayDTMFCallAction)

    /// Вызывается при сбросе провайдера CallKit.
    @objc func pwProviderDidReset(_ provider: CXProvider)

    /// Вызывается при запуске провайдера CallKit.
    @objc func pwProviderDidBegin(_ provider: CXProvider)

    /// Необязательно: Предоставляет экземпляр контроллера вызовов CallKit.
    @objc optional func returnedCallController(_ controller: CXCallController)

    /// Необязательно: Предоставляет экземпляр провайдера CallKit.
    @objc optional func returnedProvider(_ provider: CXProvider)

    /// Необязательно: Вызывается при активации аудиосессии.
    @objc optional func activatedAudioSession(_ provider: CXProvider, didActivate audioSession: AVAudioSession)

    /// Необязательно: Вызывается при деактивации аудиосессии.
    @objc optional func deactivatedAudioSession(_ provider: CXProvider, didDeactivate audioSession: AVAudioSession)
}
```

**5.** Загрузите ваш VoIP-сертификат в Pushwoosh Control Panel в соответствии с [Руководством по настройке](/ru/developer/first-steps/connect-messaging-services/ios-configuration/ios-platform-configuration/) и выберите **Production** gateway.

Вот и всё!

<Aside type="note">
В отличие от стандартных push-уведомлений, VoIP-пуши не воспроизводят звуки и не отображают оповещения. Однако они пробуждают ваше приложение в фоновом режиме, что позволяет вам запланировать локальное уведомление.
</Aside>

## Поделитесь с нами своим мнением

Ваши отзывы помогают нам улучшать наш продукт, поэтому мы будем рады, если вы поделитесь с нами своим мнением о процессе интеграции SDK. Если вы столкнетесь с какими-либо трудностями, пожалуйста, сообщите нам об этом [через эту форму](https://docs.google.com/forms/d/e/1FAIpQLSd_0b8jwn-V_JmoPLIxIFYbHACCQhrzidOZV3ELywoQPXRSxw/viewform).