Freigeben über


Integration in CallKit

In diesem Dokument erfahren Sie, wie Sie CallKit in Ihre iOS-Anwendung integrieren.

Voraussetzungen

CallKit-Integration (innerhalb des SDK)

CallKit-Integration im Azure Communication Services iOS SDK behandelt die Interaktion mit CallKit für uns. Zum Ausführen von Anrufvorgängen wie Stummschalten/Aufheben der Stummschaltung müssen wir die API nur im Azure Communication Services SDK aufrufen.

Initialisieren des Anruf-Agents mit CallKitOptions

Mit konfigurierter Instanz von CallKitOptions, können wir mit der CallAgent Behandlung von 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
})

Angeben von Anrufempfängerinformationen für ausgehende Anrufe

Zuerst müssen wir eine Instanz für StartCallOptions() ausgehende Anrufe oder JoinCallOptions() für Gruppenanrufe erstellen:

let options = StartCallOptions()

oder

let options = JoinCallOptions()

Erstellen Sie dann eine Instanz von CallKitRemoteInfo

options.callKitRemoteInfo = CallKitRemoteInfo()
  1. Weisen Sie Wert für callKitRemoteInfo.displayNameForCallKit das Anpassen des Anzeigenamens für Anrufempfänger und zum Konfigurieren des CXHandle Werts zu. Dieser angegebene displayNameForCallKit Wert ist genau, wie er im letzten gewählten Anrufprotokoll angezeigt wird. im letzten gewählten Anrufprotokoll.
options.callKitRemoteInfo.displayNameForCallKit = "DISPLAY_NAME"
  1. Weisen Sie den cxHandle Wert zu, den die Anwendung empfängt, wenn der Benutzer an diesen Kontakt zurückruft
options.callKitRemoteInfo.cxHandle = CXHandle(type: .generic, value: "VALUE_TO_CXHANDLE")

Angeben von Anrufempfängerinformationen für eingehende Anrufe

Zuerst müssen wir eine Instanz von CallKitOptions:

let callKitOptions = CallKitOptions(with: createProviderConfig())

Konfigurieren sie die Eigenschaften der CallKitOptions Instanz:

Block, der an die Variable provideRemoteInfo übergeben wird, wird vom SDK aufgerufen, wenn ein eingehender Anruf empfangen wird, und wir müssen einen Anzeigenamen für den eingehenden Anrufer abrufen, den wir an das CallKit übergeben müssen.

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
}

Konfigurieren der Audiositzung

Konfigurieren Sie die Audiositzung, bevor Sie eingehende Anrufe tätigen oder annehmen, und bevor Sie den Anruf fortsetzen, nachdem er gehalten wurde.

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
}

HINWEIS: In Fällen, in denen Contoso bereits Audiositzungen konfiguriert hat, geben nil nicht an, sondern geben fehler im Block zurück nil .

callKitOptions.configureAudioSession = self.configureAudioSession

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

falls nil angegeben configureAudioSession , ruft das SDK die Standardimplementierung im SDK auf.

Behandeln eingehender Pushbenachrichtigungsnutzlast

Wenn die App eingehende Pushbenachrichtigungsnutzlast empfängt, müssen wir sie handlePush verarbeiten. Das Azure Communication Services Calling SDK löst das IncomingCall Ereignis aus.

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

Wir können verwenden reportIncomingCall , um Pushbenachrichtigungen zu behandeln, wenn die App geschlossen oder anderweitig geschlossen wird.

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-Integration (innerhalb der App)

Wenn Sie das CallKit in die App integrieren und nicht die CallKit-Implementierung im SDK verwenden möchten, lesen Sie hier das Schnellstartbeispiel. Eine der wichtigen Dinge, die Sie sich kümmern müssen, ist jedoch, die Audiowiedergabe zur richtigen Zeit zu starten. Gefällt mir wie folgt

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)

Das Stummschalten von Lautsprechern und Mikrofonen stellt sicher, dass physische Audiogeräte erst verwendet werden, wenn das CallKit die didActivateAudioSession Einwahl CXProviderDelegateaufruft. Andernfalls funktioniert der Anruf möglicherweise nicht, oder Audio funktioniert nicht. Wann didActivateAudioSession sollten die Audiodatenströme gestartet werden.

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

Es ist wichtig, auch das ausgehende Audio stummzuschalten, bevor die Audiowiedergabe in Fällen beendet wird, in dem CallKit nicht aufgerufen wird didActivateAudioSession. Der Benutzer kann dann die Stummschaltung des Mikrofons manuell aufheben.

Hinweis

In einigen Fällen ruft CallKit nicht an didActivateAudioSession , obwohl die App über erhöhte Audioberechtigungen verfügt, in diesem Fall bleibt die Audiowiedergabe stummgeschaltet, bis der Rückruf empfangen wird. Und die Benutzeroberfläche muss den Zustand des Lautsprechers und mikrofons widerspiegeln. Der Remoteteilnehmer/die Teilnehmer im Anruf sehen, dass der Benutzer auch Audio stummgeschaltet hat. Benutzer müssen die Stummschaltung in diesen Fällen manuell aufheben.

Nächste Schritte