Newer
Older
QuentinArguillere
committed
//
// ProviderDelegate.swift
// CallTutorial
//
// Created by QuentinArguillere on 05/08/2020.
// Copyright © 2020 BelledonneCommunications. All rights reserved.
//
import Foundation
import CallKit
import linphonesw
import AVFoundation
class CallKitProviderDelegate : NSObject
{
private let provider: CXProvider
let mCallController = CXCallController()
var tutorialContext : CallKitExampleContext!
var incomingCallUUID : UUID!
init(context: CallKitExampleContext)
{
tutorialContext = context
let providerConfiguration = CXProviderConfiguration()
providerConfiguration.supportsVideo = true
providerConfiguration.supportedHandleTypes = [.generic]
providerConfiguration.maximumCallsPerCallGroup = 1
providerConfiguration.maximumCallGroups = 1
provider = CXProvider(configuration: providerConfiguration)
super.init()
provider.setDelegate(self, queue: nil) // The CXProvider delegate will trigger CallKit related callbacks
}
func incomingCall()
{
NSLog("Callkit incomingCall -- Is main thread ? \(Thread.isMainThread ? "yes" : "no") ")
incomingCallUUID = UUID()
let update = CXCallUpdate()
update.remoteHandle = CXHandle(type:.generic, value: tutorialContext.incomingCallName)
provider.reportNewIncomingCall(with: incomingCallUUID, update: update, completion: { error in }) // Report to CallKit a call is incoming
}
func stopCall()
{
NSLog("Callkit stopCall -- Is main thread ? \(Thread.isMainThread ? "yes" : "no") ")
let endCallAction = CXEndCallAction(call: incomingCallUUID)
let transaction = CXTransaction(action: endCallAction)
mCallController.request(transaction, completion: { error in }) // Report to CallKit a call must end
}
QuentinArguillere
committed
}
// In this extension, we implement the action we want to be done when CallKit is notified of something.
// This can happen through the CallKit GUI in the app, or directly in the code (see, incomingCall(), stopCall() functions above)
extension CallKitProviderDelegate: CXProviderDelegate {
func provider(_ provider: CXProvider, perform action: CXEndCallAction) {
NSLog("Callkit CXEndCallAction -- Is main thread ? \(Thread.isMainThread ? "yes" : "no") ")
QuentinArguillere
committed
do {
if (tutorialContext.mCall?.state != .End && tutorialContext.mCall?.state != .Released) {
try tutorialContext.mCall?.terminate()
}
} catch { NSLog(error.localizedDescription) }
tutorialContext.isCallRunning = false
tutorialContext.isCallIncoming = false
action.fulfill()
}
func provider(_ provider: CXProvider, perform action: CXAnswerCallAction) {
NSLog("Callkit CXAnswerCallAction -- Is main thread ? \(Thread.isMainThread ? "yes" : "no") ")
// The audio stream is going to start shortly: the AVAudioSession must be configured now.
// It is worth to note that an application does not have permission to configure the
// AVAudioSession outside of this delegate action while it is running in background,
// which is usually the case in an incoming call scenario.
tutorialContext.mCore.configureAudioSession();
try tutorialContext.mCall?.accept()
tutorialContext.isCallRunning = true
} catch {
print(error)
}
action.fulfill()
}
func provider(_ provider: CXProvider, perform action: CXSetHeldCallAction) {}
func provider(_ provider: CXProvider, perform action: CXStartCallAction) {
// This tutorial is not doing outgoing calls. If it had to do so,
// configureAudioSession() shall be called from here, just before launching the
// call.
// tutorialContext.mCore.configureAudioSession();
// tutorialContext.mCore.invite("sip:bob@example.net");
// action.fulfill();
}
func provider(_ provider: CXProvider, perform action: CXSetMutedCallAction) {}
func provider(_ provider: CXProvider, perform action: CXPlayDTMFCallAction) {}
func provider(_ provider: CXProvider, timedOutPerforming action: CXAction) {}
func providerDidReset(_ provider: CXProvider) {}
func provider(_ provider: CXProvider, didActivate audioSession: AVAudioSession) {
NSLog("Callkit didActivateaudiosession -- Is main thread ? \(Thread.isMainThread ? "yes" : "no") ")
// The linphone Core must be notified that CallKit has activated the AVAudioSession
// in order to start streaming audio.
Christophe Deschamps
committed
tutorialContext.linphoneAsyncHelper.postOnCoreQueue {
self.tutorialContext.mCore.activateAudioSession(actived: true)
}
}
func provider(_ provider: CXProvider, didDeactivate audioSession: AVAudioSession) {
// The linphone Core must be notified that CallKit has deactivated the AVAudioSession.
Christophe Deschamps
committed
tutorialContext.linphoneAsyncHelper.postOnCoreQueue {
self.tutorialContext.mCore.activateAudioSession(actived: false)
}