UnbluCallKitApi

protocol UnbluCallKitApi

Interface to the iOS CallKit bridge.

This protocol abstracts the interaction with Apple’s CallKit and PushKit frameworks, allowing the UnbluCallKitModule to be decoupled from UnbluCoreSDK via late binding. The provider can be supplied explicitly through UnbluNotificationApi.setCallKitProvider(_:) If no provider is supplied and the CallKit module is not linked, the no-op fallback NoCallKitModule is used instead.

During UnbluNotificationApi initialization, the provider is queried through isEnabled() and isCallKitSupported():

  • If isEnabled() returns false, the SDK disables PushKit support (UnbluNotificationApi.pushKitEnabled = false) and exits the CallKit setup path early.
  • If isCallKitSupported() returns false, the SDK also disables PushKit support and skips PushKit registration and CallKit voice initialization for that session.
  • When PushKit support is disabled, the SDK stops advertising the nativeInboundCall capability to the core/web layer.
  • When PushKit registration is skipped, no PushKit token is obtained or emitted to the backend through registerPushKitNotificationToken(...).
  • In that state, inbound call UI can still be driven through the local notification / webview fallback path that is used when no PushKit token is available.

Conforming types are responsible for:

  • Registering for VoIP push notifications via PushKit.
  • Creating and configuring a CXProvider to present the native call UI.
  • Reporting incoming, outgoing, and unsuccessful calls to CallKit.
  • Ending calls and updating the CallKit call state accordingly.
  • Forwarding PushKit and CallKit delegate callbacks back into UnbluNotificationApi.

Expected implementation contract:

  • registerForPushKit() must create/configure a PKPushRegistry, set the provider instance as its delegate and request .voIP pushes.
  • The provider must forward PushKit callbacks to UnbluNotificationApi.instance: pushRegistry(token:), pushRegistryInvalidate(), and pushRegistry(payload:completion:).
  • The provider must forward CXProviderDelegate actions to UnbluNotificationApi.instance.provider(answerCallUUID:), UnbluNotificationApi.instance.provider(endCallUUID:), and UnbluNotificationApi.instance.providerDidReset().
  • For outgoing calls, the built-in implementation also fulfills CXStartCallAction and reports the call as connecting and connected immediately.
  • Setup methods such as newCXProvider(_:) should be safe to call repeatedly; call-reporting methods should use the provided UUID unchanged so later SDK callbacks refer to the same call.

CallKit is not supported in China (see isCallKitSupported()). When CallKit is unavailable, the SDK falls back to local notifications for incoming calls.

  • Creates a new instance of the CallKit API provider.

    Declaration

    Swift

    init()
  • Returns true if this provider should be used by the SDK, or false to disable the CallKit integration path.

    If this returns false during UnbluNotificationApi initialization, the SDK sets UnbluNotificationApi.pushKitEnabled to false and aborts the remaining CallKit setup.

    Implement this as a static capability switch for your provider. Return true only when your custom CallKit bridge is fully wired and ready to receive the later setup calls.

    Declaration

    Swift

    func isEnabled() -> Bool
  • Registers the application for VoIP push notifications via PKPushRegistry.

    This should be called early in the app lifecycle (typically from application(:didFinishLaunchingWithOptions:)) to ensure the app can receive incoming call pushes even when not running. The SDK calls `newCXProvider(:)` before invoking this method, and the built-in implementation calls it again defensively.

    When the SDK calls this method, the implementation should:

    • Create or reuse a single PKPushRegistry.
    • Assign itself as PKPushRegistryDelegate.
    • Set desiredPushTypes to .voIP.
    • Ensure later delegate callbacks are forwarded to UnbluNotificationApi.instance.

    Declaration

    Swift

    func registerForPushKit()
  • Creates and configures a new CXProvider instance for presenting the native call UI.

    • iconName: The name of an image resource in the app bundle to use as the CallKit provider icon template. Pass nil to omit the icon.

    When the SDK calls this method, the implementation should create the provider lazily, configure it once, assign the provider delegate, and ignore later calls if the provider already exists.

    Declaration

    Swift

    func newCXProvider(_ iconName: String?)

    Parameters

    iconName

    The name of an image resource in the app bundle to use as the CallKit provider icon template. Pass nil to omit the icon.

  • Reports a new incoming call to CallKit, which presents the native incoming call UI.

    • callId: A unique identifier for the call.
    • handlerName: The display name or phone number of the caller. If the value consists only of digits, spaces, dashes, and a leading +, it is treated as a phone number.
    • callType: The type of the call. Use “VIDEO” for video calls; any other value is treated as an audio-only call.
    • completion: Called when the report completes. A non-nil Error indicates failure (e.g., the system rejected the call report).

    When the SDK calls this method, the implementation should translate the Unblu call data into a CXCallUpdate, report it with the same callId, and invoke completion exactly once as soon as CallKit accepts or rejects the report. Do not answer or end the call from here; those later actions are driven by CXProviderDelegate callbacks and endIncomingCall(with:_:).

    Declaration

    Swift

    func reportNewIncomingCall(callId: UUID, handlerName: String, callType: String, _ completion: @escaping ((any Error)?) -> Void)

    Parameters

    callId

    A unique identifier for the call.

    handlerName

    The display name or phone number of the caller. If the value consists only of digits, spaces, dashes, and a leading +, it is treated as a phone number.

    callType

    The type of the call. Use “VIDEO” for video calls; any other value is treated as an audio-only call.

    completion

    Called when the report completes. A non-nil Error indicates failure (e.g., the system rejected the call report).

  • Reports an outgoing call to CallKit so it appears in the native call UI and call log.

    • callId: A unique identifier for the call.
    • handlerName: The display name or phone number of the callee.
    • hasVideo: Whether the outgoing call includes video.

    When the SDK calls this method, the implementation should start a CXStartCallAction transaction for callId, populate the remote handle from handlerName, set the video flag from hasVideo, and report any CallKit failure as a failed call in the native UI. The built-in implementation then fulfills the resulting CXStartCallAction in the provider delegate and reports the call as connecting and connected immediately.

    Declaration

    Swift

    func reportOutgoingCall(callId: UUID, handlerName: String, hasVideo: Bool)

    Parameters

    callId

    A unique identifier for the call.

    handlerName

    The display name or phone number of the callee.

    hasVideo

    Whether the outgoing call includes video.

  • Reports an unsuccessful call to CallKit.

    This briefly presents the incoming call UI and immediately ends the call, ensuring compliance with PushKit’s requirement that every VoIP push results in a CallKit report.

    • uuid: The unique identifier of the unsuccessful call.
    • completion: Called after the placeholder incoming call has been reported to CallKit. In the built-in implementation, the actual end-call request is triggered immediately afterward and does not delay this callback.

    When the SDK calls this method, the implementation should report a placeholder incoming call to CallKit, invoke completion from the report callback, and then request endIncomingCall(with:_:) for the same UUID.

    Declaration

    Swift

    func reportUnsuccessfulCall(_ uuid: UUID, _ completion: @escaping () -> Void)

    Parameters

    uuid

    The unique identifier of the unsuccessful call.

    completion

    Called after the placeholder incoming call has been reported to CallKit. In the built-in implementation, the actual end-call request is triggered immediately afterward and does not delay this callback.

  • Ends an active incoming call and removes the CallKit call UI.

    • call: The unique identifier of the call to end.
    • unanswered: If true, the call is reported as unanswered (missed); if false, it is reported as ended by the remote party.

    When the SDK calls this method, the implementation should request a CXEndCallAction for the given UUID. In the built-in implementation, if that request fails, it falls back to CXProvider.reportCall(with:endedAt:reason:), using .unanswered when unanswered is true and .remoteEnded otherwise.

    Declaration

    Swift

    func endIncomingCall(with call: UUID, _ unanswered: Bool)

    Parameters

    unanswered

    If true, the call is reported as unanswered (missed); if false, it is reported as ended by the remote party.

  • Indicates whether CallKit is supported in the current runtime environment, for example, because of regional restrictions.

    If this returns false during UnbluNotificationApi initialization, the SDK sets UnbluNotificationApi.pushKitEnabled to false and skips PushKit registration and CallKit voice initialization for that session.

    Implement this as an environment check only. It should return false when system, regional, or product constraints mean the provider must not use CallKit at all.

    Declaration

    Swift

    func isCallKitSupported() -> Bool