向 ios 发送推送通知以与离线用户聊天,openfire xmpp
Posted
技术标签:
【中文标题】向 ios 发送推送通知以与离线用户聊天,openfire xmpp【英文标题】:send push notification to ios for chat to offline user, openfire xmpp 【发布时间】:2013-04-12 09:33:30 【问题描述】:我有一个使用openfire的ios聊天应用程序,我需要做的是在消息(1)由于任何原因无法传递,(2)应用程序处于暂停状态时发送推送通知,即不能自行生成通知。
我已经阅读了关于 *** 和其他地方的大部分相关问题/建议,并且我得出的解决方案很少。我不是ios开发人员,前几天对openfire或xmpp一无所知,所以我担心我对事物的理解可能不完整,我的解决方案可能存在缺陷。
请确认我对它的理解,并建议我是否遗漏了什么或者是否有更好的方法。还请就实施下列特定解决方案的复杂程度提出建议。
这里的挑战是确定什么时候需要推送,以及在哪里启动流程,所以
1) 一种方法是使用 xmpp 的 xep-0184 实现来检查消息是否已传递。为此,我们应该在 ios 数据库中有一些带有消息的传递标志,当从另一端接收到传递的响应时更新。所以我们需要在一段时间后检查这个标志,如果传递状态为假,则使用消息启动推送过程。看起来是一个复杂的解决方案(等待响应..检查标志有一些时间延迟..不是很令人印象深刻)
2) 更直接的方法是在 openfire 中做一些事情,当 openfire 无法传递消息时,它会将其存储在离线表中,我们可以对该部分进行一些拦截并使用消息启动推送过程。这看起来是正确的方法,但我真的很害怕在 openfire 中得到那么多并改变一些东西(这也可能很容易,用过 openfire 的人可以告诉我们吗?)
3) 这是我最后的手段,这不是一个解决方案。但如果我不能在预期的时间范围内(现在是一周后)正确地做到这一点,我们计划为所有消息。 oppenfire 会处理正常的聊天,而我们的服务器会为每条消息发送一个推送,但是当应用程序处于前台时,我们会做一些事情来处理不需要显示的额外推送消息,否则只要有一个推送就会收到信息。你们如何看待这种临时的方法(我们当然必须尽快改变它),这是否可行(或者我在这里也遗漏了一些东西)。
附:谁能告诉 Whatsapp 和其他流行的应用程序是如何处理这个问题的?
非常感谢您的帮助。
【问题讨论】:
感谢提及 xep-0184 协议! 参考此链接***.com/questions/30253948/… 【参考方案1】:XMPP 在整个 XMPP 会话期间需要持久的套接字连接或“持久的”BOSH 连接。我认为您的挑战是 iOS 不允许您在后台运行您的应用程序和套接字。每当您的 iOS 应用程序进入后台时,iOS 都会终止您的套接字连接,并且您的 Openfire 服务器会终止您的 XMPP 会话。这意味着用户离线。这也是该用户的传入消息进入离线存储的原因。
对此回复感到抱歉,但您建议的所有 3 个解决方案都是可怕的 hack ;-)。如果你想提出一个好的解决方案,你必须深入研究 XMPP 和 iOS。 1 周的时间很短。
谁能告诉 Whatsapp 和其他流行的应用程序是如何处理这个问题的?
它们使 XMPP 会话保持活动状态。这仅适用于经过高度修改的 XMPP 服务器,它们之间的一些“XMPP 客户端代理”可以在您的应用程序处于后台时保持会话运行,或两者兼而有之。
【讨论】:
谢谢亚历克斯。到目前为止我所了解的,当应用程序被 ios 置于挂起状态时(在后台运行 10 分钟后),它不能再执行任何代码,但是当它在后台时,应该能够接收消息并在内部生成通知(不是推送)。你说这不可能??我死了!! :( ...所以,对于whatsapp,ios也必须终止套接字连接,但正如你所说,他们正在通过xmpp客户端代理处理它?对吧? 请在此处阅读有关 iOS 应用状态的信息:developer.apple.com/library/ios/#documentation/iphone/… @Alex 错误答案,Whats 应用程序使用服务器来跟踪用户何时离线并使用推送通知,你不能让你的应用程序永远存在 当我在我的 openfire 服务器上离线时如何从服务器发送推送通知 @DivineDesert 嘿,你能告诉如何从服务器端离线管理或编码(推送)通知意味着当服务器端知道对方没有收到消息,所以我们必须通过推送通知他/她......而对方用户离线?【参考方案2】:我有一个解决方案。
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
self.ary_UserStatus = [NSMutableArray array];
NSMutableArray *ary_TempFromUserDefaults = [NSMutableArray array];
ary_TempFromUserDefaults = [[NSUserDefaults standardUserDefaults] valueForKey:@"KejdoUserStatus"];
if ([ary_TempFromUserDefaults count]>0)
self.ary_UserStatus = [[NSUserDefaults standardUserDefaults] valueForKey:@"KejdoUserStatus"];
self.df_UserStatus = [[NSDateFormatter alloc] init];
[self.df_UserStatus setDateFormat: @"hh:mm a MM/dd/yyyy"];
- (void)xmppStream:(XMPPStream *)sender didReceivePresence:(XMPPPresence *)presence
DDLogVerbose(@"%@: %@ - %@", THIS_FILE, THIS_METHOD, [presence fromStr]);
NSString *str_UserName = [[presence from] user];
NSString *str_LastSeenDate = [self.df_UserStatus stringFromDate:[NSDate date]];
NSMutableDictionary *mdic_UserPresence = [[NSMutableDictionary alloc] init];
[mdic_UserPresence setValue:str_UserName forKey:@"Name"];
[mdic_UserPresence setValue:str_LastSeenDate forKey:@"Date"];
[mdic_UserPresence setValue:[presence type] forKey:@"Type"];
if ([self.ary_UserStatus count]>0)
int index;
BOOL IS_exist=FALSE;
for (int i=0; i<[self.ary_UserStatus count]; i++)
NSString *str_UserFromArray = [[self.ary_UserStatus objectAtIndex:i] valueForKey:@"Name"];
if ([str_UserName isEqualToString:str_UserFromArray])
IS_exist = TRUE;
index = i;
[[NSUserDefaults standardUserDefaults] setObject:str_UserName forKey:@"Status"];
else
if (IS_exist)
[self.ary_UserStatus replaceObjectAtIndex:index withObject:mdic_UserPresence];
else
[self.ary_UserStatus addObject:mdic_UserPresence];
else
[self.ary_UserStatus addObject:mdic_UserPresence];
[[NSUserDefaults standardUserDefaults] setObject:self.ary_UserStatus forKey:@"KejdoUserStatus"];
[[NSUserDefaults standardUserDefaults] synchronize];
[[NSNotificationCenter defaultCenter] postNotificationName:@"UserStatusChangeNotification" object:self];
无论您在聊天中向其他用户发送消息的任何位置。这样做
if(appDelegate.ary_UserStatus.count>0)
for (int i=0; i<[appDelegate.ary_UserStatus count]; i++)
if ([jid.user isEqualToString:[NSString stringWithFormat:@"%@",[[appDelegate.ary_UserStatus objectAtIndex:i] valueForKey:@"Name"]]])
if ([[[appDelegate.ary_UserStatus objectAtIndex:i] valueForKey:@"Type"] isEqualToString:@"available"])
// Do something like table reload.
break;
else
[self sendPushNotification];
else
[self sendPushNotification];
【讨论】:
以上是关于向 ios 发送推送通知以与离线用户聊天,openfire xmpp的主要内容,如果未能解决你的问题,请参考以下文章