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