ios xmpp开发应用后台模式接收聊天信息

最近在使用xmppframwork来实现一个聊天应用,碰到了一个问题,应用进入后台以后,就接收不到消息了;

怎么样才能使应用被切到后台时,应用中的网络连接仍然接收数据并维持存活(像QQ iphone 一样),下面一步一步来分析。

针对iOS应用的状态,存在以下三种情况:

1)若iOS应用为活动状态,刚与服务器保持一个长连接,客户端与服务器通过此连接收发消息。
2)若iOS应用为退出状态,长连接被断开,服务器向客户端发消息则通过APNS推送消息实现。
3)若iOS应用刚刚切至后台,还没有关闭,发现长连接并没有断开,服务器通过长连接向客户端发送消息还是能发出去,但是iOS应用只有重新切至前台时才能收到消息。


针对第三种情况,有下面的疑问:

iOS应用刚切至后台时,连接还保持着,此时客户端在后台是否可以收服务器来的消息,然后用本地通知来通知用户?如果可以的话应该怎么做?还是说一旦切至后台,就必须通过APNS来通知用户?


结合苹果官方文档App Programming Guide里有关Background Execution and Multitasking的章节和satckoverflow对xmpp支持后台socket问题的解答,得出以下解决方法:

1.因为苹果只支持少数几咱类型的应用的代码可以在后台运行(例如:audio、location、voip等),所以需要在应用的(appname)-info.plist文件里,增加一个"Required background modes"的key,值设置为voip,来指定类型。

2.ios xmppframwork里已经有这方面的支持,只要初始化xmppstream时做下面设置即可:

  1. //允许后台模式(注意ios模拟器上是不支持后台socket的)  
  2.  xmppStream.enableBackgroundingOnSocket = YES;  


下面做一下测试,看看效果如何。

先在- (void)xmppStream:(XMPPStream *)sender didReceiveMessage:(XMPPMessage *)message方法里加入下面代码:

  1. //程序运行在前台,消息正常显示  
  2. if ([[UIApplication sharedApplication] applicationState] == UIApplicationStateActive)  
  3. {  
  4.   
  5. }else{//如果程序在后台运行,收到消息以通知类型来显示  
  6.     UILocalNotification *localNotification = [[UILocalNotification alloc] init];  
  7.     localNotification.alertAction = @"Ok";  
  8.     localNotification.alertBody = [NSString stringWithFormat:@"From: %@\n\n%@",@"test",@"This is a test message"];//通知主体  
  9.     localNotification.soundName = @"crunch.wav";//通知声音  
  10.     localNotification.applicationIconBadgeNumber = 1;//标记数  
  11.     [[UIApplication sharedApplication] presentLocalNotificationNow:localNotification];//发送通知  
  12. }  


真机测试,登录后切换到后台状态,然后在电脑上用spark发一条消息到iphone上,状态栏翻出通知消息,基本成功实现了。


-------------------------------------------------------------------------------------------------------------------------------------------------

补充说明

       网上查资料时,发现一个问题,如果你的应用没有实现voip,如果按上面这种方法做,有被苹果reject的危险;那么替代方法就是当应用进入后台或是已经退出后,服务器端会根据用户状态的变化,发送消息给用户,同时使用苹果apns来推送新的消息通知给用户;但我们知道,苹果的apns在即时性和可靠性方面都是不做保证的,也就是说新消息的通知传到苹果那边,苹果不保证能成功帮你推送,也不保证即时推送,所以只能找一下看有没有第三方的免费推送服务提供商。

      Google了一下,找到个叫极光推送的免费推送,正在研究中,有收获在更新...




更多 0
查看评论
7楼  yaya0835 2013-09-17 12:32发表 [回复]
请问发送消息时怎么添加XML头?
//生成<body>文档
NSXMLElement *body = [NSXMLElement elementWithName:@"body"];
NSXMLElement *type = [NSXMLElement elementWithName:@"type"];
[body addChild:type];

我发送后的XML是这样的,
<body>
<type>2</type>
</body>

可是我想发送这样的XML,就是添加一个XML头
<body>
<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<type>2</type>
</body>

怎么添加<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
Re:  KylinBL 2013-09-17 20:23发表 [回复]
回复yaya0835:这个可以用nsstring来拼接的吧,然后NSXMLElement有个 initWithXMLString的初始化方法,[[NSXMLElement alloc]initWithXMLString:@"xmlstr" error:nil];这样试试看。
Re:  yaya0835 2013-09-18 13:52发表 [回复]
回复bl1988530:谢谢~~~搞定了。。。
6楼  yaya0835 2013-09-03 12:52发表 [回复]
请问下,XMPP怎么连接外部服务器??用本机做服务器可以连接。连到外网就不行了。
5楼  blueman 2013-08-27 15:29发表 [回复]
引用“bl1988530”的评论:回复PassWordPort:你的应用被reject了?那就老老实实走ap...


已经OK了,该为apns了
4楼  blueman 2013-08-12 15:30发表 [回复]
用了voip,被苹果reject了
Re:  KylinBL 2013-08-12 17:59发表 [回复]
回复PassWordPort:你的应用被reject了?那就老老实实走apns吧~
3楼  wangcnt 2013-06-04 01:15发表 [回复]
我测试了一下把voip配置取消,而xmppStream.enableBackgroundingOnSocket = YES;不变,然后立刻进入后台,发现应用当即挂起,服务器端我的状态还是在线,但是不会从服务器那里收到任何消息,xcode也没有打印任何与服务器之间的通信数据,把值置NO,然后进入后台,服务器显示会立即显示我是离线状态。。然后我又把官方的多任务代码拿下来,
- (void)applicationDidEnterBackground:(UIApplication *)application
{
bgTask = [application beginBackgroundTaskWithExpirationHandler:^{
// Clean up any unfinished task business by marking where you
// stopped or ending the task outright.
[application endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
}];
// Start the long-running task and return immediately.
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),
^{
// Do the work associated with the task, preferably in chunks.
[application endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
});
}

  看其描述,说的是尽快地完成任务并返回,由此我想苹果的这种多任务其实是假的,是让我们做好程序被挂起之前的保存和清理工作吧,以免被挂起又被系统杀死后导致数据丢失什么的,当清理保存工作做完后立马就置bgTask为UIBackgroundTaskInvalid,应用程序就会被挂起,到第10分钟时会被强制挂起,并且就有可能随时被系统因内存原因杀死。
2楼  wangcnt 2013-05-31 23:07发表 [回复]
还有一个需要请教一下哦,就是像普通的99刀的个人账号走apns服务其实是很差劲的,很容易丢包,不知道qq,微信是怎么做到的,是不是企业版的证书要好一些呢,我感觉有这方面的因素
1楼  wangcnt 2013-05-31 23:02发表 [回复]
你好,我也正在做一个即时聊天的应用,目前也困于这个问题,不知你有什么进展,我们可以讨论一下,我今天看了下微信,就是应用进入后台然后很快再打开微信,微信的第一个模块的导航栏上会出现“正在加载”字样,我在想是不是微信在进入后台的时候是不是已经通知了服务器走apns服务推送消息,不知你有何见解。
Re:  KylinBL 2013-06-02 14:56发表 [回复]
回复wangcnt:我也是这样认为的,微信进入后台时,发送个状态给服务器,服务器根据这个状态来判断是否要走apns服务推送消息,同样当应用active时应该也是这样。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值