Intégrer à CallKit
Dans ce document, nous allons découvrir comment intégrer CallKit à votre application iOS.
Prérequis
- Compte Azure avec un abonnement actif. Créez un compte gratuitement.
- Une ressource Communication Services déployée. Créez une ressource Communication Services.
- Un jeton d’accès utilisateur pour activer le client appelant. Pour plus d’informations, consultez Créer et gérer des jetons d’accès.
- Facultatif : suivez le guide de démarrage rapide permettant d’ajouter l’appel vocal à votre application.
Intégration de CallKit (dans le SDK)
L’intégration de CallKit dans le Kit de développement logiciel (SDK) iOS Azure Communication Services gère l’interaction avec CallKit pour nous. Pour effectuer des opérations d’appel telles que le son/le son, la conservation/la reprise, nous devons uniquement appeler l’API sur le Kit de développement logiciel (SDK) Azure Communication Services.
Initialiser l’agent d’appel avec CallKitOptions
Avec l’instance configurée de CallKitOptions
, nous pouvons créer l’instance CallAgent
avec la gestion de CallKit
.
let options = CallAgentOptions()
let callKitOptions = CallKitOptions(with: createProviderConfig())
options.callKitOptions = callKitOptions
// Configure the properties of `CallKitOptions` instance here
self.callClient!.createCallAgent(userCredential: userCredential,
options: options,
completionHandler: { (callAgent, error) in
// Initialization
})
Spécifier les informations du destinataire d’appel pour les appels sortants
Tout d’abord, nous devons créer une instance d’appels StartCallOptions()
sortants ou JoinCallOptions()
d’appel de groupe :
let options = StartCallOptions()
or
let options = JoinCallOptions()
Ensuite, créez une instance de CallKitRemoteInfo
options.callKitRemoteInfo = CallKitRemoteInfo()
- Attribuez une valeur pour
callKitRemoteInfo.displayNameForCallKit
personnaliser le nom complet des destinataires d’appel et configurezCXHandle
la valeur. Cette valeur spécifiée estdisplayNameForCallKit
exactement la façon dont elle s’affiche dans le dernier journal des appels composés. dans le dernier journal des appels composés.
options.callKitRemoteInfo.displayNameForCallKit = "DISPLAY_NAME"
- Affecter la
cxHandle
valeur est ce que l’application reçoit lorsque l’utilisateur revient sur ce contact
options.callKitRemoteInfo.cxHandle = CXHandle(type: .generic, value: "VALUE_TO_CXHANDLE")
Spécifier les informations du destinataire d’appel pour les appels entrants
Tout d’abord, nous devons créer une instance de CallKitOptions
:
let callKitOptions = CallKitOptions(with: createProviderConfig())
Configurez les propriétés de l’instance CallKitOptions
:
Le bloc passé à la variable provideRemoteInfo
sera appelé par le Kit de développement logiciel (SDK) lorsque nous recevons un appel entrant et que nous devons obtenir un nom complet pour l’appelant entrant, que nous devons passer au CallKit.
callKitOptions.provideRemoteInfo = self.provideCallKitRemoteInfo
func provideCallKitRemoteInfo(callerInfo: CallerInfo) -> CallKitRemoteInfo
{
let callKitRemoteInfo = CallKitRemoteInfo()
callKitRemoteInfo.displayName = "CALL_TO_PHONENUMBER_BY_APP"
callKitRemoteInfo.cxHandle = CXHandle(type: .generic, value: "VALUE_TO_CXHANDLE")
return callKitRemoteInfo
}
Configurer la session audio
Configurez la session audio avant de placer ou d’accepter l’appel entrant et avant de reprendre l’appel une fois qu’il a été mis en attente.
callKitOptions.configureAudioSession = self.configureAudioSession
public func configureAudioSession() -> Error? {
let audioSession: AVAudioSession = AVAudioSession.sharedInstance()
var configError: Error?
do {
try audioSession.setCategory(.playAndRecord)
} catch {
configError = error
}
return configError
}
REMARQUE : Dans les cas où Contoso a déjà configuré des sessions audio ne fournissent pas mais ne retournent nil
nil
pas d’erreur dans le bloc
callKitOptions.configureAudioSession = self.configureAudioSession
public func configureAudioSession() -> Error? {
return nil
}
s’il nil
est fourni pour configureAudioSession
le kit SDK appelle l’implémentation par défaut dans le Kit de développement logiciel (SDK).
Gérer la charge utile de notification Push entrante
Lorsque l’application reçoit une charge utile de notification Push entrante, nous devons l’appeler handlePush
pour le traiter. Le Kit de développement logiciel (SDK) d’appel Azure Communication Services déclenche l’événement IncomingCall
.
public func handlePushNotification(_ pushPayload: PKPushPayload)
{
let callNotification = PushNotificationInfo.fromDictionary(pushPayload.dictionaryPayload)
if let agent = self.callAgent {
agent.handlePush(notification: callNotification) { (error) in }
}
}
// Event raised by the SDK
public func callAgent(_ callAgent: CallAgent, didRecieveIncomingCall incomingcall: IncomingCall) {
}
Nous pouvons utiliser reportIncomingCall
pour gérer les notifications Push lorsque l’application est fermée ou autrement.
if let agent = self.callAgent {
/* App is not in a killed state */
agent.handlePush(notification: callNotification) { (error) in }
} else {
/* App is in a killed state */
CallClient.reportIncomingCall(with: callNotification, callKitOptions: callKitOptions) { (error) in
if (error == nil) {
DispatchQueue.global().async {
self.callClient = CallClient()
let options = CallAgentOptions()
let callKitOptions = CallKitOptions(with: createProviderConfig())
callKitOptions.provideRemoteInfo = self.provideCallKitRemoteInfo
callKitOptions.configureAudioSession = self.configureAudioSession
options.callKitOptions = callKitOptions
self.callClient!.createCallAgent(userCredential: userCredential,
options: options,
completionHandler: { (callAgent, error) in
if (error == nil) {
self.callAgent = callAgent
self.callAgent!.handlePush(notification: callNotification) { (error) in }
}
})
}
} else {
os_log("SDK couldn't handle push notification", log:self.log)
}
}
}
Intégration de CallKit (dans l’application)
Si vous souhaitez intégrer le CallKit dans l’application et ne pas utiliser l’implémentation CallKit dans le Kit de développement logiciel (SDK), reportez-vous à l’exemple de démarrage rapide ici. Mais l’une des choses importantes à prendre en charge est de démarrer l’audio au bon moment. Comme suit
let outgoingAudioOptions = OutgoingAudioOptions()
outgoingAudioOptions.muted = true
let incomingAudioOptions = IncomingAudioOptions()
incomingAudioOptions.muted = true
var copyAcceptCallOptions = AcceptCallOptions()
copyStartCallOptions.outgoingAudioOptions = outgoingAudioOptions
copyStartCallOptions.incomingAudioOptions = incomingAudioOptions
callAgent.startCall(participants: participants,
options: copyStartCallOptions,
completionHandler: completionBlock)
Désactiver le haut-parleur et le microphone pour garantir que les périphériques audio physiques ne sont pas utilisés tant que le CallKit n’appelle pas le didActivateAudioSession
CXProviderDelegate
micro. Sinon, l’appel peut être supprimé ou l’audio ne fonctionnera pas.
Quand didActivateAudioSession
est le moment où les flux audio doivent être démarrés.
func provider(_ provider: CXProvider, didActivate audioSession: AVAudioSession) {
Task {
guard let activeCall = await self.callKitHelper.getActiveCall() else {
print("No active calls found when activating audio session !!")
return
}
try await startAudio(call: activeCall)
}
}
func provider(_ provider: CXProvider, didDeactivate audioSession: AVAudioSession) {
Task {
guard let activeCall = await self.callKitHelper.getActiveCall() else {
print("No active calls found when deactivating audio session !!")
return
}
try await stopAudio(call: activeCall)
}
}
private func stopAudio(call: Call) async throws {
try await self.callKitHelper.muteCall(callId: call.id, isMuted: true)
try await call.stopAudio(stream: call.activeOutgoingAudioStream)
try await call.stopAudio(stream: call.activeIncomingAudioStream)
try await call.muteIncomingAudio()
}
private func startAudio(call: Call) async throws {
try await call.startAudio(stream: LocalOutgoingAudioStream())
try await self.callKitHelper.muteCall(callId: call.id, isMuted: false)
try await call.startAudio(stream: RemoteIncomingAudioStream())
try await call.unmuteIncomingAudio()
}
Il est important de désactiver également l’audio sortant avant d’arrêter l’audio dans les cas où CallKit n’appelle didActivateAudioSession
pas . L’utilisateur peut ensuite activer manuellement le microphone.
Remarque
Dans certains cas, CallKit n’appelle didActivateAudioSession
pas même si l’application dispose d’autorisations audio élevées, dans ce cas, l’audio reste muet jusqu’à ce que le rappel soit reçu. Et l’interface utilisateur doit refléter l’état du haut-parleur et du microphone. Le participant/s distant dans l’appel voit également que l’utilisateur a désactivé l’audio. L’utilisateur devra désactiver manuellement le son dans ces cas.