Подтвердить что ты не робот

Отправить push-уведомление для ios для чата для автономного пользователя, openfire xmpp

У меня есть приложение для чата ios, которое использует openfire, что мне нужно сделать, это отправить push-уведомление, когда сообщение (1) не может быть доставлено по какой-либо причине, (2) приложение находится в состоянии приостановлено, т.е. не может генерировать уведомление самостоятельно.

Я прочитал большинство связанных с этим вопросов/предложений по этому вопросу в stackoverflow и в других местах, и я пришел к выводу о нескольких решениях моей проблемы. Я не разработчик ios и не знаю ничего о openfire или xmpp до двух дней, поэтому я боюсь, что мое понимание вещей может быть неполным, и мои решения могут быть ошибочными.

Просьба подтвердить мое понимание этого и предложить, если я что-то упускаю или если есть лучший подход. Пожалуйста, также сообщите о том, насколько сложно будет реализовать конкретное решение, перечисленное ниже.

Задача здесь состоит в том, чтобы определить, когда требуется нажать и где процесс должен быть запущен, поэтому

1) одним из способов является использование xpp-реализации xep-0184 для проверки доставки сообщения. Чтобы сделать это, мы должны иметь некоторый флаг доставки с сообщением в базе данных ios, который обновляется, когда полученный ответ получен из другого конца. Поэтому нам нужно проверить этот флаг через некоторое время, и если поставленный статус является ложным, инициируйте процесс push с сообщением. Похоже, это сложное решение (дождитесь ответа.. отметьте флаг с некоторой задержкой времени) не очень впечатляет)

2). Более прямой подход заключается в том, чтобы что-то сделать в openfire, когда openfire не может доставить сообщение, которое хранит его в автономной таблице, мы можем сделать некоторый перехват в этой части и инициировать процесс push с сообщением. Это похоже на правильный подход, но я действительно боюсь получить что-то внутри openfire и что-то изменить (может быть, тоже легко, кто-то, кто немного поработал с openfire, может сказать?)

3) Это мое последнее средство, и это не решение. Но если я не смогу сделать это правильно в ожидаемый промежуток времени (через неделю), мы планируем отправить push-уведомление для всех Сообщения. oppenfire будет вести обычную чат, в то время как на каждое сообщение будет отправлено push с нашего сервера, но когда приложение находится на переднем плане, мы делаем что-то, чтобы обрабатывать дополнительные push-сообщения, которые не должны отображаться, иначе push будет получен всякий раз, когда есть сообщение. Что вы, ребята, думаете об этом временном пути (мы, разумеется, должны изменить это, как только сможем), это выполнимо (или я тоже что-то упустил).

P.S. Может ли кто-нибудь сказать, как Whatsapp и другие популярные приложения справляются с этим?

Большое спасибо за вашу помощь.

4b9b3361

Ответ 1

XMPP требует постоянного соединения сокета или "постоянного" соединения BOSH во время всего сеанса XMPP. Я считаю, что ваша задача заключается в том, что iOS не позволяет запускать приложение и сокет в фоновом режиме. Всякий раз, когда ваше приложение iOS выходит в фоновом режиме, iOS убивает ваше соединение сокета, а ваш сервер Openfire убивает ваш сеанс XMPP. Это означает, что пользователь переходит в автономном режиме. Это также причина, по которой входящие сообщения для этого пользователя переходят в автономное хранилище.

Извините за этот ответ, но все 3 предложенных вами решения - ужасные хаки;-). Если вы хотите найти хорошее решение, вам нужно очень глубоко проникнуть в XMPP и iOS. 1 неделя - очень короткий промежуток времени для этого.

Может ли кто-нибудь сказать, как Whatsapp и другие популярные приложения справляются с этим?

Они сохраняют сеанс XMPP. Это работает только с очень измененными серверами XMPP, некоторые "Прокси-сервер XMPP", между которыми поддерживается ваш сеанс, когда ваше приложение находится в фоновом режиме, или комбинация или и то, и другое.

Ответ 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];