Search code examples
iosswiftxcodecallkitsilentpush

How do I launch an App or the Incoming Call UI when I receive a silent push notification on an iOS app?


I am trying to make an app the launches the app or the incoming call UI when a silent notification is received.

Currently I have the notifications working and I am able to send a notification and print out a log when I receive the notification

This function handels the receiving of notifications:

func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void){
    print("Enitre message \(userInfo)")

    let state: UIApplication.State = application.applicationState
    switch state {
    case UIApplication.State.active:
        print("State: App is active")
    case UIApplication.State.inactive:
        print("State: App is inactive")
    case UIApplication.State.background:
        print("State: App is running in the background")
    default:
        print("State: Unknown")
    }
    completionHandler(UIBackgroundFetchResult.newData)
}

Is it possible to open the app or incoming call UI in this function?


Solution

  • First register for VOIP Notification in

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    
            requestPushKit()
            return true
    }
    

    Import the call kit

    import CallKit
    

    Register Push kit

    fileprivate func requestPushKit() {
            let voipRegistry = PKPushRegistry(queue: DispatchQueue.main)
            voipRegistry.delegate = self
            voipRegistry.desiredPushTypes = [.voIP]
    }
    

    Delegates of VOIP(Push Kit)

    extension AppDelegate: PKPushRegistryDelegate {
    
        func pushRegistry( registry: PKPushRegistry, didUpdate pushCredentials: PKPushCredentials, for type: PKPushType) {
    
            if type == PKPushType.voIP {
                let tokenParts = pushCredentials.token.map { data -> String in
                    return String(format: "%02.2hhx", data)
                }
    
                let tokenString = tokenParts.joined()
    
                print(tokenString)
    
            }
        }
    
        func pushRegistry( registry: PKPushRegistry, didInvalidatePushTokenFor type: PKPushType) {
    
        }
    
      func pushRegistry( registry: PKPushRegistry, didReceiveIncomingPushWith payload: PKPushPayload, for type:PKPushType, completion: @escaping () -> Void) {
    
            if type == PKPushType.voIP {
                self.incomingCall()
            }
        }
    
        func pushRegistry( registry: PKPushRegistry, didReceiveIncomingPushWith payload: PKPushPayload, for type: PKPushType) {
            if type == PKPushType.voIP {
                self.incomingCall()
            }
        }
    
    }
    

    Call incomingcall Method

    fileprivate func defaultConfig() -> CXProviderConfiguration{
            let config = CXProviderConfiguration(localizedName: "My App")
            config.includesCallsInRecents = true
            config.supportsVideo = true
            config.maximumCallGroups = 5
            config.maximumCallsPerCallGroup = 10
    //        config.iconTemplateImageData = UIImagePNGRepresentation(UIImage(named: "pizza")!)
    //        config.ringtoneSound = "ringtone.caf" 
    
            return config
        }
    
    
    func incomingCall(){
            let provider = CXProvider(configuration: defaultConfig())
            provider.setDelegate(self, queue: nil)
            let update = CXCallUpdate()
            update.remoteHandle = CXHandle(type: .generic, value: "Pete Za")
            update.hasVideo = true
            provider.reportNewIncomingCall(with: UUID(), update: update, completion: { error in })
        }
    

    And Call Kit Delegates Methods

    extension AppDelegate : CXProviderDelegate {
    
        func providerDidReset( provider: CXProvider) {
    
        }
    
        func providerDidBegin( provider: CXProvider) {
    
        }
    
        func provider( provider: CXProvider, perform action: CXAnswerCallAction) {
            action.fulfill()
        }
    
        func provider( provider: CXProvider, perform action: CXEndCallAction) {
            action.fulfill()
        }
    
        func provider( provider: CXProvider, perform action: CXStartCallAction) {
    
        }
    
        func provider( provider: CXProvider, perform action: CXSetHeldCallAction) {
    
        }
    
        func provider( provider: CXProvider, timedOutPerforming action: CXAction) {
    
        }
    
        func provider( provider: CXProvider, perform action: CXPlayDTMFCallAction) {
    
        }
    
        func provider( provider: CXProvider, perform action: CXSetGroupCallAction) {
    
        }
    
        func provider( provider: CXProvider, perform action: CXSetMutedCallAction) {
    
        }
    
    //    func provider(_ provider: CXProvider, execute transaction: CXTransaction) -> Bool {
    //
    //    }
    }
    

    Still if you require anything so please let us know. :)