Sdílet prostřednictvím


Integrace s CallKitem

V tomto dokumentu si ukážeme, jak integrovat CallKit s vaší aplikací pro iOS.

Požadavky

Integrace CallKitu (v sadě SDK)

Integrace CallKitu v sadě Azure Communication Services sdk pro iOS zpracovává interakci s CallKitem. Abychom mohli provádět jakékoli operace volání, jako je ztlumení nebo zrušení ztlumení, blokování a obnovení, potřebujeme rozhraní API volat pouze v sadě SDK služby Azure Communication Services.

Inicializace agenta volání pomocí CallKitOptions

S nakonfigurovanou instancí CallKitOptionsmůžeme vytvořit CallAgent zpracování 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
})

Zadání informací o příjemci hovorů pro odchozí hovory

Nejprve musíme vytvořit instanci odchozích StartCallOptions() hovorů nebo JoinCallOptions() pro skupinové volání:

let options = StartCallOptions()

or

let options = JoinCallOptions()

Pak vytvořte instanci CallKitRemoteInfo

options.callKitRemoteInfo = CallKitRemoteInfo()
  1. Přiřaďte hodnotu pro callKitRemoteInfo.displayNameForCallKit přizpůsobení zobrazovaného jména pro příjemce hovoru a konfiguraci CXHandle hodnoty. Tato hodnota je přesně způsob, jakým displayNameForCallKit se zobrazuje v posledním vytáčeném protokolu volání. v posledním vytočení protokolu volání.
options.callKitRemoteInfo.displayNameForCallKit = "DISPLAY_NAME"
  1. Přiřazení hodnoty je to cxHandle , co aplikace obdrží, když uživatel zavolá zpět na tento kontakt.
options.callKitRemoteInfo.cxHandle = CXHandle(type: .generic, value: "VALUE_TO_CXHANDLE")

Zadání informací o příjemci hovorů pro příchozí hovory

Nejprve musíme vytvořit instanci CallKitOptions:

let callKitOptions = CallKitOptions(with: createProviderConfig())

Konfigurace vlastností CallKitOptions instance:

Blok, který se předá do proměnné provideRemoteInfo , bude volána sadou SDK, když přijmeme příchozí hovor, a potřebujeme získat zobrazovaný název příchozího volajícího, který potřebujeme předat do CallKitu.

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
}

Konfigurace zvukové relace

Konfigurace zvukové relace bude volána před umístěním nebo přijetím příchozího hovoru a před pokračováním hovoru po jeho blokování.

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
}

POZNÁMKA: V případech, kdy společnost Contoso již nakonfigurovala zvukové relace, neposkytují nil , ale vrací nil chybu v bloku.

callKitOptions.configureAudioSession = self.configureAudioSession

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

pokud nil je k dispozici pro configureAudioSession tuto sadu SDK, volá výchozí implementaci v sadě SDK.

Zpracování příchozí datové části nabízených oznámení

Když aplikace obdrží datovou část příchozího nabízeného oznámení, musíme ji volat handlePush , abychom ji mohli zpracovat. Událost vyvolá IncomingCall volání sady SDK služby Azure Communication Services.

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

Můžeme použít reportIncomingCall ke zpracování nabízených oznámení, když je aplikace zavřená nebo jinak.

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

Integrace CallKitu (v aplikaci)

Pokud chcete integrovat CallKit v aplikaci a nepoužívat implementaci CallKitu v sadě SDK, projděte si ukázku rychlého startu zde. Jednou z důležitých věcí, na které je potřeba se postarat, je spustit zvuk ve správný čas. To se mi líbí

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)

Ztlumení reproduktoru a mikrofonu zajistí, aby se fyzická zvuková zařízení nepoužívala, dokud CallKit nezavolá didActivateAudioSession .CXProviderDelegate Jinak se hovor může vynechat nebo zvuk nebude fungovat. Kdy didActivateAudioSession se mají spustit zvukové streamy.

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

Je také důležité ztlumit odchozí zvuk před zastavením zvuku v případech, kdy CallKit nevyvolá didActivateAudioSession. Uživatel pak může ztlumení mikrofonu ručně zrušit.

Poznámka:

V některých případech CallKit nevolá didActivateAudioSession , i když má aplikace zvýšená zvuková oprávnění, v takovém případě zvuk zůstane ztlumený, dokud nebude hovor přijat zpět. Uživatelské rozhraní musí odrážet stav reproduktoru a mikrofonu. Vzdálený účastník/s v hovoru uvidí, že uživatel má ztlumený zvuk. Uživatel bude muset v těchto případech ručně zrušit ztlumení.

Další kroky