Skip to content

[iOS 13] callKit displayed from AppDelegate.m before incoming call listeners #107

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
ahmadworks opened this issue Sep 26, 2019 · 22 comments · Fixed by #205
Closed

[iOS 13] callKit displayed from AppDelegate.m before incoming call listeners #107

ahmadworks opened this issue Sep 26, 2019 · 22 comments · Fixed by #205
Labels
good first issue Good for newcomers help wanted Extra attention is needed

Comments

@ahmadworks
Copy link

After updating to 3.0.3 and updating my code to meet iOS 13 requirements so CallKit is reported from AppDelegate. But the problem is that when app is closed or in background, the callKit displays very fast before my call class get loaded. So the callKit is shown on screen before listeners are ready and if I accept or reject the call immediately nothing happened. I need to wait for 3 seconds until call listeners are ready then I can accept or reject.

How can I delay the callKit in AppDelegate until my call class is fully loaded?

@manuquentin
Copy link
Contributor

Hi @ahmadworks.
It's the normal behaviour since in ios 13 we should report all calls coming from a VoIP push.
Please refer to the doc about it and the corresponding PR.

@ahmadworks
Copy link
Author

I don't think this should be the normal behaviour even after iOS 13, I can report to call but the call should appear on screen only after the app knows how to deal with the call. in current case what should happen if user quickly tapped answer before the app knows how it should handle the answer and reject.

@danjenkins
Copy link
Collaborator

@ahmadworks this is needed for ios13 so we need to think collectively about how to work around that issue. I think from my perspective we need the native side to know that the JS bridge isn't up yet and so wait until it is and then emit the event of "yes someone accepted the call"

@Prussich
Copy link

Prussich commented Oct 1, 2019

@danjenkins also to emit UUID data of active CallKit call (for example, to update the incoming call display). Because RN doesn't know the current UUID call after the bridge is up. didDisplayIncomingCall not called (error "Sending 'RNCallKeepDidDisplayIncomingCall' with no listeners registered.)

@manuquentin
Copy link
Contributor

@Prussich you have to listen to the events at the very beginning of the loading of your app (eg. in the index.ios.js). You'll next have to wait for you WebRTC call to be set up before really answer it.

@bmp123

This comment has been minimized.

@danjenkins
Copy link
Collaborator

@bmp123 please create a new issue for that :)

@Prussich
Copy link

Prussich commented Oct 2, 2019

@manuquentin
As I see it:

  1. App wake up after receive VoIP-Push.
  2. App calling reportNewIncomingCall from VoIP-push delegate (as quickly, as Apple asks)
...
NSString *uuid = [[[NSUUID UUID] UUIDString] lowercaseString];
...
[RNCallKeep reportNewIncomingCall:uuid handle:handle handleType:@"generic" hasVideo:false localizedCallerName:callerName fromPushKit: YES];

RN bridge still not live. And there are no CallKeep listeners yet.
3) RN bridge is started. The RN part with CallKeep listeners starts up.

But, RNCallKeepDidDisplayIncomingCall was not called and RNCallKeep doesn't know which uuid was used in reportNewIncomingCall:uuid in native part.

Please correct me if everything is wrong and you can know in the RN part which UUID of the incoming call was used before in the native part of the application.

@Prussich
Copy link

Prussich commented Oct 4, 2019

@manuquentin I also try to listen to the events at the very beginning of the loading of my app:

At the top of index.ios.js:

const onAnswerCallAction = ({callUUID}) => {
    RNFS.writeFile(path, '\n[' + moment().locale('en').format('YYYY-MM-DD HH:mm:ss') + ']: ' + '[index]: onAnswerCallAction from App start\n', 'utf8');
};

const onIncomingCallDisplayed = ({error, callUUID, handle, localizedCallerName, fromPushKit}) => {
    RNFS.writeFile(path, '\n[' + moment().locale('en').format('YYYY-MM-DD HH:mm:ss') + ']: ' + '[index]: onIncomingCallDisplayed from App start:' + callUUID + '\n', 'utf8');
};

RNCallKeep.setup(options);
RNCallKeep.addEventListener('answerCall', onAnswerCallAction);
RNCallKeep.addEventListener('didDisplayIncomingCall', onIncomingCallDisplayed);

and I don't see any event records in log file about "onIncomingCallDisplayed". In the native part, sending the onIncomingCallDisplayed event fires earlier than there is a subscription to the event in JS. Any ideas how to fix this?

@manuquentin
Copy link
Contributor

@Prussich there is a timeout to work around this issue here.
The app will wait 5s in release and 10s in debug before sending the event.

Here the event triggered too soon event with this workaround ?

@Prussich
Copy link

Prussich commented Oct 4, 2019

Good idea! But it work around for the outgoing call (RNCallKeepDidReceiveStartCallAction event).
I 'll try to make the same implementation with the timeout for incoming calls for the RNCallKeepDidDisplayIncomingCall event in RNCallKeep.m.

@pravinjohn
Copy link

Hello, please do share if anyone got a solution for this. Thanks!

@danwhite-ipc
Copy link

Would it not be possible create a method AnswerCall(UUID) which calls [action fulfill]; currently called within performAnswerCallAction, this way the app should show connecting until your app has managed to reconnect and retrieve the call and actually answer the call. I am not that familiar with native iOS code otherwise I would attempt to see if the concept is possible.

@konradkierus
Copy link
Contributor

For anyone interested - please check my proof of concept to solve this issue
softwarehutpl@b7df3b4

The idea is to gather events which should be sent through JS bridge if it isn't ready. Once JS part is ready then send didLoadWithEvents with all gathered events.
Next, on JS part, events needs to be handled depending of the project needs. For example, you may be interested in checking of only last "end call" action but it's worth having "did display call" action as well in order to get all push/call-related data.

Disclaimer:

  1. It wasn't fully tested yet.
  2. It may not be necessary to wrap all events.
  3. It may require some examples in README of how to use didLoadWithEvents event.

@manuquentin
Copy link
Contributor

Thanks @konradkierus,
Can you make a PR with these changes ? I'll be happy to test the,.

@konradkierus
Copy link
Contributor

@manuquentin sure, please check #169

@mariouzae
Copy link
Contributor

mariouzae commented Mar 27, 2020

I see sometimes the JS Bridge doesn't start after receive a VoIP PN. It receives the VoIP PN, I report the new incoming call but the app never starts. It seems the JS Bridge thread is paused until you take some action on the CallKit screen.

Even if I wait for a long time, I don't see the app starting.

CallKeep: 3.0.9
RN: 0.59.10
iOS: 13.3.1

Does anyone have this issue too?

@zxcpoiu
Copy link
Member

zxcpoiu commented Mar 28, 2020

@mariouzae

You can try NOT calling completion() first. If you marked completion() and you've see your js bridge worked, then you might encounter the similar issue.

react-native-webrtc/react-native-voip-push-notification#52

This PR is a try which aims to solve calling completion() too early to stop JS initialization issue

@manuquentin
Copy link
Contributor

Should be fixed in #205

@danjenkins
Copy link
Collaborator

A lot of work has gone into this now.... closing and if people still have large issues... then they should re-open a new issue

@danwhite-ipc
Copy link

Do you know when #205 is due to be merged?

@danjenkins
Copy link
Collaborator

@danwhite-ipc nope - have you tried running it and seeing if it helps solve your problem?

manuquentin added a commit that referenced this issue Jul 21, 2020
Handle issue with JS not initialized on start to fix #107
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
good first issue Good for newcomers help wanted Extra attention is needed
Projects
None yet
10 participants