IOS 后台执行代码(voip socket)

酒鬼 2012-03-01

如何使应用被切到后台,应用中的网络连接仍然接收数据并维持存活(像QQiphone一样);

其实按IOS官方文档一步一步做就可以实现上述功能;

这里主要说一下我按文档遇到的问题,以及将原来的C/C++程序(主要是网络层)简单的修改一下就可以支持IOS后台运行的方法.

1.在xxxxInfo.plist添加以支持后台运行

<key>UIBackgroundModes</key>

<array>

<string>voip</string>

</array>

2.在applicationDidEnterBackground中设置存活回调(系统保证在600内会调用一次//todosendkeeplive

[[UIApplicationsharedApplication]setKeepAliveTimeout:600handler:^{//todosendkeeplive}];

*注:这里最少600秒否则失败

3.在applicationWillEnterForeground中取消存活回调

[[UIApplicationsharedApplication]clearKeepAliveTimeout];

4.创建网络连接,这一步可以按官方文档提供的三种方法全创建,并设置属性(如NSStreamNetworkServiceTypeVoIP.....)

但这里说一下移植原有c/c++网络层的代码的会有两个问题:

a>IOS并没有提到直接把一个存在的socket设置后台接收属性

b>一般原有c/c++网络层的程序很多会使用一个线程阻塞接收数据,而ios里的流(NSStream)如果阻塞read过75秒后就超时,还不能更改这个值,而用IOS推荐的方式(Run-Loop)使用NSstream又会改变程序结构(收到事件方式);

下面是解决方案,关键在用CFStreamCreatePairWithSocket在已有的socket上创建输入输出流

CFReadStreamRefreadStream;

CFWriteStreamRefwriteStream;

CFStreamCreatePairWithSocket(NULL,m_socket,&readStream,&writeStream);

miStream=(NSInputStream*)readStream;

moStream=(NSOutputStream*)writeStream;

if(miStream==nil)

returngloox::ConnStreamError;

[miStreamsetProperty:NSStreamNetworkServiceTypeVoIPforKey:NSStreamNetworkServiceType];

[moStreamsetProperty:NSStreamNetworkServiceTypeVoIPforKey:NSStreamNetworkServiceType];

//[miStreamscheduleInRunLoop:[NSRunLoopcurrentRunLoop]forMode:NSDefaultRunLoopMode];

//[moStreamscheduleInRunLoop:[NSRunLoopcurrentRunLoop]forMode:NSDefaultRunLoopMode];

[miStreamopen];//这两句不写可能都能正常工作,我没试

[moStreamopen];//这两句不写可能都能正常工作,我没试

其实上面的代码只做一件事,就是告诉IOS在当前应用不在前台的时候接管这个socket,

其他的(原c/c++代码)都不动,该用socketrecv就recv该send就send,不用管

miStream和mStream,只是别忘了关闭连接的时候释放它们;

*注这里会遇到个大问题,必须是真机socket才会在后台运行时接收数据(用官方文档的方式实也一样),这个害S人,我试了可都不止一天,还以为是其他哪不对……

相关推荐