Delen via


Integreren met CallKit

In dit document wordt uitgelegd hoe u CallKit integreert met uw iOS-toepassing.

Vereisten

CallKit-integratie (binnen SDK)

CallKit-integratie in de iOS SDK van Azure Communication Services verwerkt interactie met CallKit voor ons. Als u aanroepbewerkingen wilt uitvoeren, zoals dempen/dempen opheffen, moet u de API alleen aanroepen in de Azure Communication Services SDK.

Oproepagent initialiseren met CallKitOptions

Met een geconfigureerd exemplaar van CallKitOptions, kunnen we het maken met de CallAgent verwerking van 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
})

Gegevens van geadresseerden voor uitgaande oproepen opgeven

Eerst moeten we een exemplaar maken van StartCallOptions() uitgaande oproepen of JoinCallOptions() voor groepsoproep:

let options = StartCallOptions()

or

let options = JoinCallOptions()

Maak vervolgens een exemplaar van CallKitRemoteInfo

options.callKitRemoteInfo = CallKitRemoteInfo()
  1. Wijs waarde toe voor callKitRemoteInfo.displayNameForCallKit het aanpassen van de weergavenaam voor geadresseerden van oproepen en het configureren CXHandle van waarde. Deze opgegeven displayNameForCallKit waarde is precies hoe deze wordt weergegeven in het laatste gebelde oproeplogboek. in het laatste gebelde oproeplogboek.
options.callKitRemoteInfo.displayNameForCallKit = "DISPLAY_NAME"
  1. cxHandle De waarde toewijzen is wat de toepassing ontvangt wanneer de gebruiker terugbelt op die contactpersoon
options.callKitRemoteInfo.cxHandle = CXHandle(type: .generic, value: "VALUE_TO_CXHANDLE")

Gegevens van geadresseerden voor inkomende oproepen opgeven

Eerst moeten we een instantie van CallKitOptions:

let callKitOptions = CallKitOptions(with: createProviderConfig())

Configureer de eigenschappen van CallKitOptions het exemplaar:

Blok dat wordt doorgegeven aan variabele provideRemoteInfo wordt door de SDK aangeroepen wanneer we een binnenkomende oproep ontvangen en we moeten een weergavenaam voor de binnenkomende beller ophalen, die we moeten doorgeven aan de 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
}

Audiosessie configureren

De audiosessie wordt aangeroepen voordat u binnenkomende oproepen plaatst of accepteert en voordat u de oproep hervat nadat deze in de wachtstand is gezet.

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
}

OPMERKING: In gevallen waarin Contoso al audiosessies heeft geconfigureerd, niet opgeven nil , maar fout retourneren nil in het blok

callKitOptions.configureAudioSession = self.configureAudioSession

public func configureAudioSession() -> Error? {
    return nil
}

als nil hiervoor wordt opgegeven configureAudioSession , roept SDK de standaard implementatie aan in de SDK.

Binnenkomende pushmeldingspayload verwerken

Wanneer de app de nettolading voor binnenkomende pushmeldingen ontvangt, moeten we deze aanroepen handlePush om deze te verwerken. Azure Communication Services Calling SDK genereert de IncomingCall gebeurtenis.

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) {
}

We kunnen reportIncomingCall pushmeldingen verwerken wanneer de app wordt gesloten of anderszins.

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)
      }
  }
}

CallKit-integratie (binnen app)

Als u de CallKit in de app wilt integreren en de CallKit-implementatie niet in de SDK wilt gebruiken, raadpleegt u het snelstartvoorbeeld hier. Maar een van de belangrijkste dingen om voor te zorgen, is om de audio op het juiste moment te starten. Vind ik leuk als volgt

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)

Het dempen van luidspreker en microfoon zorgt ervoor dat fysieke audioapparaten pas worden gebruikt als de CallKit de didActivateAudioSession aanroept CXProviderDelegate. Anders wordt het gesprek mogelijk verwijderd of werkt het geluid niet. Wanneer didActivateAudioSession moeten de audiostreams worden gestart.

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()
}
    

Het is belangrijk om de uitgaande audio ook te dempen voordat u de audio stopt in gevallen waarin CallKit niet wordt aangeroepen didActivateAudioSession. De gebruiker kan vervolgens het dempen van de microfoon handmatig opheffen.

Notitie

In sommige gevallen wordt CallKit niet aangeroepen didActivateAudioSession , ook al heeft de app verhoogde audiomachtigingen, in dat geval blijft de audio gedempt totdat de oproep terug is ontvangen. En de gebruikersinterface moet de status van de luidspreker en microfoon weerspiegelen. De externe deelnemer/s in het gesprek zien dat de gebruiker ook geluid heeft gedempt. In die gevallen moet de gebruiker het dempen handmatig opheffen.

Volgende stappen