iOS 后台运行VoIP 类APP

转载文章来自: http://www.cnblogs.com/jhzhu/p/3416305.html
苹果官方原文:
There are several requirements for implementing a VoIP app: Add the UIBackgroundModes key to your app’s Info.plist file. Set the value of this key to an array that includes the voip string. 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. To ensure a better user experience on iPhone, use the Core Telephony framework to adjust your behavior in relation to cell-based phone calls; see Core Telephony Framework Reference. To ensure good performance for your VoIP app, use the System Configuration framework to detect network changes and allow your app to sleep as much as possible.

1.IOS允许App的一个Socket在App切换到后台后仍然保持连接. 这样,当有通话请求的时候,App能及时处理. 这个socket需要在应用第一次启动的时候创建, 并标记为"此socket用于VoIP服务". 这样当App切换到后台的时候,IOS会接管这个标记为"用于VoIP服务"的socket. 这个socket的响应函数(比如,一个delegate,或者是个block)会正常的响应, 就像App还在前台一样. 2.10s魔咒. 当socket有任何数据从服务端传来, 你在app里为socket写的响应函数都会做处理.但是, 你只有最多10s的时间来干你想干的事情. 也就意味着你在响应函数里新建一个大于10s的timer是没有意义的. 并且IOS并不保证给你足够10s的时间,视系统情况而定. 3.在socket的响应函数里, 你能通过NSLocalNotification来通知用户"电话来了". 除此之外, 你没法做其他任何视觉上的动作来提醒用户, 因为你的app还处于某个不知道的次元, 甚至连window都还没创建. 4.你永远也没有办法知道或者决定NSLocalNotification的样式是banner还是alert. 你也许钟爱后者, 但是决定权在用户手里. 5.允许在后台定期执行一段代码. 你可以设定一个大于等于10分钟的时间t, 和一个定期执行的handler, IOS系统会在每次经过t时间的时候调用一次这个handler. 但是IOS不保证这个handler会准时运行, 只保证在时间t范围内的某个点会执行一次. 6.我们通常用楼上的handler处理socket的断线重连操作. 因为网络不稳定, 或者用户开启飞行模式等原因, 我们用于voip服务的socket会断开连接. 在这个handler里,如果发现连接断开,我们只需要跟条目1一样的创建socket,设置一样的socket响应函数,一切又会恢复正常. 7.不建议这个handler做太多事情, 因为它也有10s魔咒.(据不完全统计,苹果所有的后台处理都有这个10s限制. 不保证绝对正确哈, 仅供参考) 8.自启服务. 当IOS重新启动, 或者你的app因为其他原因退出时, IOS会马上启动你注册为voip的app, 你可以很迅速的恢复socket连接. 但是, 从底部多任务栏中手动关闭应用除外.更"code"的说明是:当程序退出的exitcode != 0,IOS会重启你的app.经试验发现,从底部多任务栏关闭的时候,程序的exitcode == 0. 9.如果你亲爱的用户是一个典型的"app终结者",那么你还剩最后一条路来通知来电提醒:NSRemoteNotification. 你也许会被NSRemoteNotification的可靠性和实时性折腾的抓狂, 但是, 谁让你选了IOS? 你享受了封闭带来的传世体验, 也得承受封闭的限制. 10.当条目8描述的情况发生之后,app的application:didFinishLaunchingWithOptions:会被调用. 但是,请时刻提醒自己我们的app仍然处于后台. 我们以前总在这里创建window创建rootController, 但现在不必了. 现在我们需要的就是把可爱的socket连上, 像在条目1里一样,让一切回归正常(我不去写歌词真浪费了^_^). 11.在application:didFinishLaunchingWithOptions:里你能通过[application applicationState] == UIApplicationStateBackground来判断是正常启动应用还是系统自动启动, 然后决定该创建window还是创建voip的socket.

VoIP类的app允许用户使用Internet网络而不是手机的蜂窝网络打电话,因此这一类的app需要保持同它相关的服务的网络连接,用以厚道来电消息和其他数据。IOS系统不是通过一直让app处于激活状态来达到这个目的,而是同样也会将这类的app挂起,但同时会在app被挂起期间接管它的sockets,当这个sockets有数据通信时,系统会再次唤醒处于挂起状态的app,同时将sockets的控制权交还给app,以让其正常的处理来去电事件和其他数据。
一、voip应用需要有下面几个要求:
1、在Info.plist中增加UIBackgroundModes键,并将值设为voip;

2、为该app配置sockets,并注册到系统上,以便app切到后台时系统会接管这个sockets;

3、在app切到后台之前,要调用setKeepAliveTimeout:handler:方法来注册一个周期性执行的handler,用于保持app和服务器的连接;

4、配置一个音频会话(audio session)。
二、UIBackgroundModes键的voip值有三个功能:

1、告知系统在app切到后台的时候接管它的sockets;
2、这个键值的另外一个功能是允许app在后台播放音频,跟UIBackgroundModes的audio值起到的作用相同。

3、后台状态的app在系统确定voip服务可用的时候会立即重新加载(relaunched)

三、配置keep-alive handler
一个voip类的app需要周期性的被唤醒以防止失去跟服务器的连接。为了达到这个目的,iOS系统允许我们通过setKeepAliveTimeout:handler:方法来实现保持连接。通常我们都在软件切到后台以后,也就是在applicationDidEnterBackground:才需要实现保持连接的方法。Handler配置完后,系统会根据需要在time out设置的时间到期之前唤醒处于挂起状态的app,至少被调用一次handler中的方法。

1、 handler
需要说明的是,这个handler在后台执行的时候需要尽可能快的返回,因为系统只给了最多10s的时间去执行它。如果10s内没有执行完,而且没有去申请额外的执行时间,系统将会吧app挂起。

2、timeout
设置handler时,需要指定app需要的最大超时时间。IOS系统允许的最小值是600s,如果想设置个小点的值,handler的设置就会失败。系统在执行handler内容的时候,只保证超时时间到之前会执行,而不保证准确的执行时间点,系统是会根据当时的任务情况等系统条件确定一个合适的时间点,已达到延长电池寿命的目的。

你可能感兴趣的:(iOS 后台运行VoIP 类APP)