ios 后台唤醒应用_IOS 后台保持连接

当iphone应用程序进行网络编程时,切到后台后,socket连接会断掉,ios的设计就是这样。

但是好在apple公司也没有那么绝,还是有一些东西可以在后台运行的(backgroundmodes),

比如:音乐 GPS  Voip Locationupdates等

我们以voip为例:

这里我们可以将NSStream指定voip的属性,从而可以避免程序切到后台的时候socket连接中断。

可以分为两步:

1.在info.plist文件中,增加voip选项,如

2. 设置NSStream的属性,如

在IOS中,sockets是用流或者更高级的结构,设置一个VOIP的socket,你只需要在通常的设置中添加一个特殊的key来标明这个接口是用于连接VOIP服务的,下表列出了流的接口和设置:

设置流接口用于voip接口

NSInputStream 和NSOutputStream 对于 Cocoa streams, 使用 setProperty:forKey: 方法添加

NSStreamNetworkServiceType 属性给 stream. 改属性的值设为 NSStreamNetworkServiceTypeVoIP.

[readStream setProperty:NSStreamNetworkServiceTypeVoIP forKey:NSStreamNetworkServiceType];

这样,当程序切到后台的时候,这个socket连接还会被保持。

另外,iphone都是通过wifi或者gprs上网的,那么当socket连接空闲一段时间后,这个连接有可能被路由器关闭,为了保持连接,我们需要不停发送'心跳包'(保持连接状态)。

由于iphone上的程序切到后台后,程序会被挂起,那么也就无法定时发送心跳包,所以这个问题只能由服务端来解决。普通的办法就是服务器每隔一定时间给每个客户端发送一个心跳包,以维持这个连接。每当客户端接收到心跳包的时候,客户端会被IOS唤醒,获得一小段CPU时间,然后再次进入挂起状态。

解决方法:

通过设置以下属性可以保持socket连接和数据的继续传输

1.需要在Info.plist文件中添加UIBackgroundModes中的VOIP键值;

2.设置流属性

CFReadStreamRef和CFWriteStreamRef通过如下方法设置kCFStreamNetworkServiceType属性为kCFStreamNetworkServiceTypeVoIP;

CFReadStreamSetProperty(theReadStream, kCFStreamNetworkServiceType, kCFStreamNetworkServiceTypeVoIP);

CFWriteStreamSetProperty(theWriteStream, kCFStreamNetworkServiceType, kCFStreamNetworkServiceTypeVoIP);

NSInputStream 和NSOutputStream通过如下方法设置NSStreamNetworkServiceType属性为NSStreamNetworkServiceTypeVoIP;

[self.stream setProperty: NSStreamNetworkServiceTypeVoIP forKey:NSStreamNetworkServiceType];

3.这里有一个问题,就是客户端是通过心跳来和服务端保持连接,心跳是由定时器触发的,当我退到后台以后,定时器方法被挂起,那么通过如下设置来在后台运行定时器

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

- (void)applicationDidEnterBackground:(UIApplication

*)application{

UIApplication*

app = [UIApplication sharedApplication];

__block

UIBackgroundTaskIdentifier bgTask;

bgTask

= [app beginBackgroundTaskWithExpirationHandler:^{

dispatch_async(dispatch_get_main_queue(),

^{

if

(bgTask != UIBackgroundTaskInvalid)

{

bgTask

= UIBackgroundTaskInvalid;

}

});

}];

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,

0),

^{

dispatch_async(dispatch_get_main_queue(),

^{

if

(bgTask != UIBackgroundTaskInvalid)

{

bgTask

= UIBackgroundTaskInvalid;

}

});

});

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值