CallKit – jak go skonfigurować?

CallKit – jak go skonfigurować?

iOS 10 dostarcza wiele nowych funkcji. Jedną z nich jest CallKit, framework, który pozwala naszej aplikacji na ścisłą integrację z interfejsem użytkownika w telefonie. Aplikacje mogą wykorzystywać CallKit, aby umożliwić użytkownikom odbieranie połączeń przychodzących oraz realizację połączeń wychodzących za pomocą interfejsu użytkownika dostarczanego przez telefon. Połączenie VoIP może zostać wyciszone lub zawieszone. Możliwe jest również prowadzenie wideo połączenia.

Przygotowanie projektu

Pierwszym krokiem jest przygotowanie do odbierania powiadomień VoIP.

Background modes - Voice over IP

Konfiguracja powiadomień VoIP

Aby skonfigurować aplikację do odbierania powiadomień, należy zaimportować framework PushKit do naszego pliku AppDelegate oraz utworzyć obiekt PKPushRegistry. Należy również pamiętać o ustawieniu delegata nowo utworzonego obiektu jako self i ustawieniu jego typu jako VoIP:

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey : Any]? = nil) -> Bool {
        let pushRegistry = PKPushRegistry(queue: DispatchQueue.main)
        pushRegistry.delegate = self
        pushRegistry.desiredPushTypes = [.voIP]

        return true
    }

Do przechowywania danych uwierzytelniających na serwerze dla aktywnego użytkownika oraz do przetwarzania pushy wykorzystywane są funkcje

func pushRegistry(_ registry: PKPushRegistry, didUpdate credentials: PKPushCredentials, forType type: PKPushType) {
            //Store push credentials on server for the active user.
    }

func pushRegistry(_ registry: PKPushRegistry, didReceiveIncomingPushWith payload: PKPushPayload, forType type: PKPushType) {
    }

Obsługa otrzymanych powiadomień

Ostatnim krokiem jest parsowanie danych otrzymanych z funkcji didReceiveIncomingPushWith, która potrafi między innymi wybudzić telefon ze stanu blokady urządzenia.

func pushRegistry(_ registry: PKPushRegistry, didReceiveIncomingPushWith payload: PKPushPayload, forType type: PKPushType) {
        guard type == .voIP else { return }

        if let uuidString = payload.dictionaryPayload["UUID"] as? String,
           let handle = payload.dictionaryPayload["handle"] as? String,
           let hasVideo = payload.dictionaryPayload["hasVideo"] as? Bool,
           let uuid = UUID(uuidString: uuidString)
        {
             // Handle incoming call
        }
}

Konfiguracja CallKit

Pierwszym krokiem jest utworzenie klasy do obsługi połączeń przychodzących poprzez rozszerzenie klasy CXProviderDelegate.

final class ProviderDelegate: NSObject, CXProviderDelegate {
    private let provider: CXProvider
}

Następnym etapem jest konfiguracja dostawcy.

static var providerConfiguration: CXProviderConfiguration {
        let localizedName = NSLocalizedString("APPLICATION_NAME", comment: "name")
        let providerConfiguration = CXProviderConfiguration(localizedName: localizedName)

        providerConfiguration.supportsVideo = true

        providerConfiguration.maximumCallsPerCallGroup = 1

        providerConfiguration.supportedHandleTypes = [.phoneNumber]

        if let iconMaskImage = UIImage(named: "wideo") {
            providerConfiguration.iconTemplateImageData = UIImagePNGRepresentation(iconMaskImage)
        }

        providerConfiguration.ringtoneSound = "Ringtone.caf"

        return providerConfiguration
}

Ostatnim etapem jest dostarczenie inicjalizatora, dodanie funkcji reportIncomingCall odpowiadającej za przekazanie połączenia przychodzącego do systemu oraz dodanie funkcji providerDidReset wywoływanej gdy dostawca zostanie zrestartowany.

init() {
        provider = CXProvider(configuration: type(of: self).providerConfiguration)
        super.init()
        provider.setDelegate(self, queue: nil)
}

func reportIncomingCall(uuid: UUID, handle: String, hasVideo: Bool = false, completion: ((NSError?) -> Void)? = nil) {
        // Construct a CXCallUpdate describing the incoming call, including the caller.
        let update = CXCallUpdate()
        update.remoteHandle = CXHandle(type: .phoneNumber, value: handle)
        update.hasVideo = hasVideo

        // Report the incoming call to the system
        provider.reportNewIncomingCall(with: uuid, update: update) { error in
            completion?(error as? NSError)
        }
}

func providerDidReset(_ provider: CXProvider) {
        print("Provider did reset")
        /*
            End any ongoing calls if the provider resets, and remove them from the app's list of calls,
            since they are no longer valid.
         */
    }

Jest to tylko wstęp i jeśli chcielibyście dowiedzieć się więcej na ten temat, polecam tę stronę. Znajduje się tutaj dużo informacji oraz przykładowa aplikacja.

Wojtek

Wojtek Byczkowski

iOS Developer

Wycena projektu

Opowiedz nam o swoim projekcie i napisz, jak możemy Ci pomóc.

Dlaczego warto rozwijać z nami projekty?

Logo Mobile Trends Awards

Mobile Trends Awards 2021

Wygrana w kategorii
ŻYCIE CODZIENNE

Nagroda Legalnych Bukmacherów

Nagroda Legalnych Bukmacherów 2019

Najlepsza aplikacja mobilna

Mobile Trends Awards logo

Mobile Trends Awards 2023

Wygrana w kategorii
MCOMMERCE ROZWÓJ

23

opinie klientów

Clutch logo