Hello, colleagues.
I am reaching out to the community with an issue that is likely quite common. Unfortunately, I have not been able to resolve it independently and would like to confirm if my approach is correct.
Core Problem: VoIP push notifications are not delivered to the application when it is in the background or terminated. After reviewing existing discussions on the forum, I concluded that the cause might be related to CallKit not having enough time to register. However, in my case, I am using AppDelegate, and in theory, CallKit registration should occur quickly enough. Nevertheless, the issue persists.
Additional Question: I would also like to clarify the possibility of customizing the CallKit interface. Specifically, I am interested in adding custom buttons (for example, to open a door). Please advise if such functionality is supported by CallKit itself, or if a different approach is required for its implementation.
Thank you in advance for your time and attention to my questions. For a more detailed analysis, I have attached a fragment of my code below. I hope this will help clarify the situation.
Main File
@main
struct smartappApp: App {
@UIApplicationDelegateAdaptor private var delegate: AppDelegate
@StateObject private var navigationManager = NavigationManager()
init() {
print("Xct")
if !isRunningTests() {
DILocator.instance
.registerModules([
ConfigModule(),
SipModule(),
AuthModule(),
NetworkModule(),
CoreDataModule(),
RepositoryModule(),
DataUseCaseModule(),
SipUseCaseModule()
])
}
}
func application(_ application: UIApplication,
didReceiveRemoteNotification userInfo: [AnyHashable: Any],
fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
print("Axtest")
completionHandler(.newData)
}
var body: some Scene {
App Delegate File
class AppDelegate: UIResponder, UIApplicationDelegate {
private let voipRegistry = PKPushRegistry(queue: .main)
private var provider: CXProvider?
func application(_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
setupPushKit()
setupCallKit()
return true
}
public func regist(){
setupPushKit()
setupCallKit()
}
private func setupPushKit() {
voipRegistry.delegate = self
voipRegistry.desiredPushTypes = [.voIP]
DispatchQueue.main.async {
self.voipRegistry.pushToken(for: .voIP)
}
}
// MARK: - CallKit Setup
private func setupCallKit() {
let configuration = CXProviderConfiguration(localizedName: "MyApp")
configuration.maximumCallGroups = 1
configuration.maximumCallsPerCallGroup = 1
configuration.supportsVideo = true
configuration.iconTemplateImageData = UIImage(named: "callIcon")?.pngData()
provider = CXProvider(configuration: configuration)
provider?.setDelegate(self, queue: .main)
}
// MARK: - Background Launch Handling
func application(_ application: UIApplication,
didReceiveRemoteNotification userInfo: [AnyHashable: Any],
fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
print("Axtest")
completionHandler(.newData)
}
}
extension AppDelegate: PKPushRegistryDelegate {
func pushRegistry(_ registry: PKPushRegistry,
didUpdate pushCredentials: PKPushCredentials,
for type: PKPushType) {
APNsImpl().registerToken(token: pushCredentials.token.map { String(format: "%02.2hhx", $0) }.joined())
}
func pushRegistry(_ registry: PKPushRegistry,
didReceiveIncomingPushWith payload: PKPushPayload,
for type: PKPushType) {
guard type == .voIP else {
return
}
print("call kit")
let payloadDict = payload.dictionaryPayload
let update = CXCallUpdate()
update.remoteHandle = CXHandle(type: .phoneNumber, value: "dsfsdfddsf")
update.hasVideo = payloadDict["hasVideo"] as? Bool ?? false
provider?.reportNewIncomingCall(with: UUID(),
update: update,
completion: { error in
if let error = error {
print("Failed to report incoming call: \(error.localizedDescription)")
} else {
print("Successfully reported incoming call")
}
})
}
}