CallKitProviderDelegate.swift 4.56 KiB
//
//  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
// 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") ")
		do {
			if (tutorialContext.mCall?.state != .End && tutorialContext.mCall?.state != .Released)  {
				try tutorialContext.mCall?.terminate()
7172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
} 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") ") do { // 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. 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. tutorialContext.linphoneAsyncHelper.postOnCoreQueue { self.tutorialContext.mCore.activateAudioSession(actived: false) } } }