Running a VOIP (PJSIP) service in the background

2019-03-31 18:53发布

问题:

My app has just been rejected by Apple as it does not properly implement background running and it is a VOIP app using iOS.

My odd code that kept it running was

[self performSelectorOnMainThread:@selector(keepAlive) withObject:nil waitUntilDone:YES];
[application setKeepAliveTimeout:KEEP_ALIVE_INTERVAL handler: ^{
  [self performSelectorOnMainThread:@selector(keepAlive) withObject:nil waitUntilDone:YES];
}];

Which I know is wrong

I then followed the

http://blog.dkaminsky.info/2013/01/27/keep-your-ios-app-running-in-background-forever/ which is the VOIP hack to get it running all the time. Again I think this is wrong.

I basically just need to call one method to keep PJSIP alive.

How should I do this properly?

UPDATE

I have looked at the Apple guide, it appears this is correct

[application setKeepAliveTimeout:KEEP_ALIVE_INTERVAL handler: ^{
        [self performSelectorOnMainThread:@selector(keepAlive) withObject:nil waitUntilDone:YES];
        NSLog(@"Fire");
    }];

However I am not sure how to configure PJSIP TCP port to run in the background.

APPLE : Configure one of the app’s sockets for VoIP usage.

The runs fine in the background its just Apple rejecting it

2.16

We found that your app uses a background mode but does not include functionality that requires that mode to run persistently. This behavior is not in compliance with the App Store Review Guidelines.

We noticed your app declares support for VoIP in the UIBackgroundModes key in your Info.plist but does not support incoming calls from the connected VoIP service.

If your application does not support incoming calls from it's connected VoIP service, the voip background mode is not appropriate. As indicated in the iOS Programming Guide, this key is for applications that need to monitor sockets for incoming calls:

"Rather than keep VoIP apps awake all the time, the system allows them to be suspended and provides facilities for monitoring their sockets for them. When incoming traffic is detected, the system wakes up the VoIP app and returns control of its sockets to it."

Please look into using the "audio" value in the UIBackgroundModes key of your Info.plist file. Using the audio background mode will keep current out-going VoIP calls open while your app is in the background.

It would be appropriate to add VoIP features or remove the "VoIP" setting from the UIBackgroundModes key.For discrete code-level questions, you may wish to consult with Apple Developer Technical Support. Please be sure to:

Update 2

PJSIP has told me that the sockets are marked for VOIP and so I have no idea why this is being rejected

回答1:

you should check section in "Declaring Your App’s Supported Background Task". in link iOS App Programming Guide

Implementing a VoIP App

A Voice over Internet Protocol (VoIP) app allows the user to make phone calls using an Internet connection instead of the device’s cellular service. Such an app needs to maintain a persistent network connection to its associated service so that it can receive incoming calls and other relevant data. Rather than keep VoIP apps awake all the time, the system allows them to be suspended and provides facilities for monitoring their sockets for them. When incoming traffic is detected, the system wakes up the VoIP app and returns control of its sockets to it.

To configure a VoIP app, you must do the following:

Enable support for Voice over IP from the Background modes section of the Capabilities tab in your Xcode project. (You can also enable this support by including the UIBackgroundModes key with the voip value in your app’s Info.plist file.)

Configure one of the app’s sockets for VoIP usage.

Before moving to the background, call the setKeepAliveTimeout:handler: method to install a handler to be executed periodically. Your app can use this handler to maintain its service connection.

Configure your audio session to handle transitions to and from active use.

Including the voip value in the UIBackgroundModes key lets the system know that it should allow the app to run in the background as needed to manage its network sockets. An app with this key is also relaunched in the background immediately after system boot to ensure that the VoIP services are always available.

“Tips for Developing a VoIP App.”



回答2:

Hei, that's helped me: The thing is, that typically SIP signalling uses UDP as a transfer protocol, but Apple allows persistent connections only with TCP protocol. So, here are the steps:
1) Figure out, if your SIP Server supports SIP signalling with TCP ( for example, sip2sip does, ekiga doesn't ).
2) Get rid of UDP connection in pjsua, insert somewhere

app_config.no_udp = PJ_TRUE;
app_config.no_tcp = PJ_FALSE;

3) If you use outbound proxy, put ";transport=TCP" at the end of url

cfg->cfg.outbound_proxy_cnt = 1;
cfg->cfg.outbound_proxy[0] = pj_str("sip:proxy.sipthor.net;transport=tcp");

4) Add ";transport=TCP" all accounts and register server url, i.e for example: +a sip:username@sip2sip.info;transport=TCP sip:sip2sip.info;transport=TCP sip2sip.info username password

Hope, that helps.



回答3:

Apple is very concerned over what your app says it does and what it actually does. It seems like your application actually does not handle incoming VoIP calls although you mention it so in your plist.

You can either

a) Remove the VoIP setting from the plist OR

b) Add the functionality to incoming calls in your app

Cheers !!!



标签: ios voip pjsip