3

I'm trying to make pushkit voip messages work when the application is closed. The calls work and get displayed when app is in the foreground or in the background. But after the user force kills the app, when the notification gets recieved, the app terminates with signal 9 (killed by user/ios).

How can I fix this issue?

I've got background fetch, voip, audio and push notifications enabled in my app. Also tried removing all the Unity methods, putting the Callkit call in the PushRegistry method, creating a new provider when recieving a notification, even subscribing to the UIApplicationDidFinishLaunchingNotification event, but nothing worked. I've made it so the app is compliant to showing a call when recieving a voip notification. Here's my code:

@objcMembers class CallPlugin: UIResponder, UIApplicationDelegate, PKPushRegistryDelegate, CXProviderDelegate {

static var Instance: CallPlugin!
var provider: CXProvider!
var registry:PKPushRegistry!
var uuid:UUID!
var callController: CXCallController!

//class entry point
public static func registerVoIPPush(_ message: String) {
    Instance = CallPlugin()

    //Pushkit
    Instance.registry = PKPushRegistry(queue: DispatchQueue.main)
    Instance.registry.delegate = Instance
    Instance.registry.desiredPushTypes = [PKPushType.voIP]

    //Callkit
    let providerConfiguration = CXProviderConfiguration(localizedName: "testing")
    providerConfiguration.supportsVideo = true
    providerConfiguration.supportedHandleTypes = [.generic]
    Instance.provider = CXProvider(configuration: providerConfiguration)
    Instance.provider.setDelegate(Instance, queue: nil)        

    UnitySendMessage("ResponseHandler", "LogNative", "registration success")
}

//Get token
func pushRegistry( _ registry: PKPushRegistry, didUpdate credentials: PKPushCredentials, for type: PKPushType) {
    if type == PKPushType.voIP {
        let deviceTokenString = credentials.token.map { String(format: "%02.2hhx", $0) }.joined()
        UnitySendMessage("ResponseHandler", "CredentialsRecieved",deviceTokenString)
    }
}       

//Get notification
func pushRegistry( _ registry: PKPushRegistry, didReceiveIncomingPushWith payload: PKPushPayload, for type:PKPushType, completion: @escaping () -> Void) {

    //UnitySendMessage("ResponseHandler", "LogNative", "Got something push")
    reportInComingCallWith(uuidString: "111", handle: "Paul", isVideo: false)
    completion()
}

//show the call
func reportInComingCallWith(uuidString:String,handle:String,isVideo:Bool) {
    //UnitySendMessage("ResponseHandler", "LogNative", "attempting call")
    let callUpdate = CXCallUpdate()        
    callUpdate.remoteHandle = CXHandle(type: .generic, value: handle)        
    callUpdate.hasVideo = false

    uuid = NSUUID() as UUID

    provider.reportNewIncomingCall(with: uuid as UUID, update: callUpdate){ (error) in
        if let error = error {
            UnitySendMessage("ResponseHandler", "LogNative", "error in starting call"+error.localizedDescription)
        }
    }
}
  • This is your problem and solution. [answer](https://stackoverflow.com/a/61011477/8956604) – Kasım Özdemir Apr 09 '20 at 21:26
  • Do you get a crash log or stack trace or exception message? @KasımÖzdemir that shouldn't be their problem since they are reporting an incoming call – Paulw11 Apr 09 '20 at 21:29
  • Problem is the same. So when the app get banned in 2 to 3 attempts then it stops receiving voip. You have to uninstall and re-install app. – Kasım Özdemir Apr 09 '20 at 21:45
  • @KasımÖzdemir I'm aware of the app getting banned and how it gets fixed by re-installing, but that is not the problem here. When you get banned, the app stops receiving the push. My app does not stop getting them, it just crashes instead with a SIG-9 when it happens. Even on the first attempt after re-installing. I don't think it's an entitlement issue, since I do call Callkit when I get a VOIP push – Paul Vinogradov Apr 09 '20 at 23:43
  • @Paulw11 I have no crash reports, since I haven't uploaded this to the production appstore.yet. The debugger does not really show me anything, since the app crashes right away, debugger only sees signal 9. Maybe there is a way to see local logs of previous crashes of the app, but I'm not aware of those. This being a Unity app and not native swift, does not make things much easier to check – Paul Vinogradov Apr 09 '20 at 23:46
  • You can open your device log in the Mac console app and see if there is anything useful there. – Paulw11 Apr 10 '20 at 00:41
  • @Paulw11 checked the device logs, getting a "Termination reason 0xbaadca11", which is a callkit error, but before that a thread crashes with "0x56000080 address size fault". I'm assuming this is because the class does not get initialized in the appdelegate, but a bit later in the application. This is because I'm using this in a Unity application. I've updated my app to call the initialization from the DidFinishLaunchingWith options event, but the app gets closed right after it hits that event, even on a print statement – Paul Vinogradov Apr 13 '20 at 10:11

1 Answers1

0

The issue was that my app was not creating the delegate and pushregistry objects in time for the notification to get fully handled.

I solved it by overriding the app delegate and putting the notification initializations in WillFinishLaunching, like so:

-(BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(nullable NSDictionary<UIApplicationLaunchOptionsKey,id> *)launchOptions{
   [CallPlugin registerVoIPPush:@"hmm"];
   [super application:application willFinishLaunchingWithOptions:launchOptions];
   return true;
}

That way everything is ready for the notification to be handled. I tried to put this in DidFinishLaunching first, but it was already too late for the notification and IOS was killing my application by then.

  • I have the same issue and i am using Cordova for this. In the plugins i am using i dont see "willFinishLaunchingWithOptions" method. Did you write it from scratch? – alext Sep 21 '20 at 08:51
  • Yes, this implementation is my own. You can just add it or any other app delegate method and override it in the main appController – Paul Vinogradov Sep 22 '20 at 23:20