发送推送通知ios聊天到离线用户,openfire xmpp



我有一个使用openfire的ios聊天应用程序,我需要做的是在消息(1)由于任何原因无法传递时发送推送通知,(2)应用程序处于挂起状态,即不能自己生成通知。

我已经在stackoverflow和其他地方阅读了大多数相关的问题/建议,我已经总结了一些解决我的问题的方法。我不是ios开发者,前几天也不知道openfire和xmpp,所以我担心我对事情的理解可能不完整,我的解决方案可能有缺陷。

请确认我对它的理解,并建议如果我错过了什么,或者如果有更好的方法。还请建议实施下面列出的特定解决方案有多复杂。

这里的挑战是确定何时需要推送以及在何处启动流程,因此

1)一种方法是使用XMPP的xep-0184实现来检查消息是否被传递。要做到这一点,我们应该在ios数据库中有一些带有消息的已交付标志,当从另一端接收到已交付的响应时,该标志会更新。因此,我们需要在一段时间后检查此标志,如果交付的状态为false,则使用该消息启动推送过程。看起来是一个复杂的解决方案(等待回复)。有一些时间滞后的检查标志…不太好)

2)更直接的方法是在openfire中做一些事情,当openfire无法传递消息时,它将其存储在离线表中,我们可以在该部分做一些拦截并启动消息的推送过程。这看起来是正确的方法,但我真的害怕在明火中得到那么多并改变一些东西(这可能也很容易,有一点与明火一起工作的人可以告诉?)

这是我最后的办法,但这不是解决办法。但如果我不能在预期的时间范围内(从现在起一周)正确地做到这一点,我们计划为所有消息发送推送通知。Oppenfire将负责正常的聊天,而推送将从我们的服务器为每条消息发送,但当应用程序在前台时,我们做一些事情来处理不需要显示的额外推送消息,否则每当有消息时都会收到推送。你们觉得这种临时的方式如何(我们当然必须尽快改变这一点),这是可行的(或者我在这里也遗漏了一些东西)。

注:有人能告诉我Whatsapp和其他流行应用是如何处理这个问题的吗?

非常感谢您的帮助

XMPP在整个XMPP会话期间需要持久的套接字连接或"持久的" BOSH连接。我认为你的挑战在于iOS不允许你在后台运行应用和socket。当你的iOS应用进入后台时,iOS会终止你的套接字连接,而你的Openfire服务器会终止你的XMPP会话。这意味着用户将脱机。这也是为什么该用户的传入消息会进入离线存储的原因。

很抱歉这个回复,但你建议的所有3个解决方案都是可怕的hack;-)。如果你想要想出一个好的解决方案,你就必须深入研究XMPP和iOS。一周的时间是很短的。

有谁能告诉我Whatsapp和其他流行的应用程序是如何处理这个问题的吗?

它们保持XMPP会话存活。这只适用于高度修改的XMPP服务器,一些"XMPP客户端代理"之间保持会话运行,而你的应用程序在后台,或组合或两者兼而有之。

我有一个解决办法。

- (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];

最新更新