iOS VOIP
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.