I’m attempting to implement dependable VoIP push notifications in my iOS app in order that incoming calls are all the time acquired, even when the app is within the background or terminated. The difficulty is that whereas VoIP pushes work as anticipated within the foreground, they’re unreliable when the app is within the background or terminated. In some instances, no notification arrives in any respect.
Atmosphere:
Instruments: Swift, Xcode
Frameworks: PushKit, CallKit
What’s Occurring:
• VoIP notifications work accurately when the app is within the foreground.
• Notifications are intermittent when the app is within the background or terminated.
• No errors seem within the logs, however the pushRegistry(_:didReceiveIncomingPushWith:for:) technique isn’t invoked in these instances.
PushKit Registration:
func registerForVoIPPushes() {
self.voipRegistry = PKPushRegistry(queue: nil)
self.voipRegistry?.delegate = self
self.voipRegistry?.desiredPushTypes = [.voIP]
}
func software(_ software: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
registerForVoIPPushes()
return true
}
Push Registry Dealing with:
func pushRegistry(_ registry: PKPushRegistry,
didReceiveIncomingPushWith payload: PKPushPayload,
for sort: PKPushType) {
guard let payloadInfo = payload.dictionaryPayload["data"] as? [AnyHashable: Any] else {
print("Unidentifiable payload information acquired")
return
}
print("pushRegistry didReceiveIncomingPushWith (payloadInfo)")
guard
sort == .voIP,
let callId = payloadInfo["callId"] as? String,
let _ = payloadInfo["deviceId"] as? String,
let sender = payloadInfo["senderName"] as? String,
let sort = payloadInfo["type"] as? String
else {
print("Unknown PushKit notification acquired")
return
}
let uuid = GlobalMethods().uuidFromString(callId)
change sort {
case "NewVoipCallStarted":
CallManager.shared.processForIncomingCall(sender: sender, uuid: uuid)
case "CancelVoipCall":
CallManager.shared.cancelIncomingCall(uuid: uuid)
default:
print("Unknown sort of voIP notification acquired")
return
}
}
CallKit Integration:
func processForIncomingCall(sender: String, uuid: UUID) {
let configuration = CXProviderConfiguration()
configuration.supportsVideo = true
configuration.includesCallsInRecents = true
configuration.supportedHandleTypes = [.generic]
configuration.maximumCallsPerCallGroup = 1
configuration.includesCallsInRecents = true
supplier = CXProvider(configuration: configuration)
supplier?.setDelegate(self, queue: nil)
let replace = CXCallUpdate()
replace.remoteHandle = CXHandle(sort: .generic, worth: sender)
replace.hasVideo = true
supplier?.reportNewIncomingCall(with: uuid, replace: replace) { error in
if let error = error {
print("Error reporting incoming name: (error.localizedDescription)")
} else {
print("Incoming name efficiently reported.")
}
}
}
What I’ve Tried:
• Checked that the VoIP push certificates is legitimate and uploaded correctly.
• Examined sending VoIP pushes with Apple’s Developer Console
• Verified the payload format consists of content-available: 1 and apns-priority: 10.
• Ensured the app is registered for PushKit notifications with .voIP push sort each time the app launches.
• Confirmed the app has the Background Modes functionality enabled, together with VoIP.
• Double-checked that the server is sending pushes accurately.
• Checked if the pushRegistry(_:didReceiveIncomingPushWith:for:) technique is invoked.
Anticipated behaviour:
VoIP notifications ought to all the time arrive and invoke pushRegistry(_:didReceiveIncomingPushWith:for:),
even when the app is within the background or terminated.