2013-04-19 19 views
17

Ho un'applicazione di chat ios che utilizza openfire, quello che devo fare è inviare notifica push quando il messaggio (1) non può essere consegnato per nessun motivo, (2) l'app è in stato sospeso, ovvero non può generare una notifica autonomamente.invia notifica push a ios per la chat all'utente offline, openfire xmpp

Ho letto la maggior parte delle domande/suggerimenti relativi su questo su StackOverflow e altrove e ho concluso poche soluzioni al mio problema. Non sono uno sviluppatore ios e non so nulla di openfire o xmpp prima di un paio di giorni, quindi temo che la mia comprensione delle cose potrebbe non essere completa e le mie soluzioni potrebbero essere imperfette.

Gentilmente confermare la mia comprensione e suggerire se mi manca qualcosa o se c'è un approccio migliore. Si prega inoltre di suggerire quanto sarà complesso implementare una particolare soluzione elencata di seguito.

sfida è quello di identificare quando è richiesta la spinta e dove viene avviato il processo, così

1) un modo è utilizzare l'implementazione XEP-0184 di xmpp per verificare se il messaggio viene consegnato. per fare questo dovremmo avere qualche contrassegno consegnato con messaggio nel database ios, che viene aggiornato quando la risposta consegnata viene ricevuta dall'altra parte. Quindi è necessario controllare questo flag dopo un po 'e se lo stato di consegna è falso, avviare il processo push con il messaggio. Sembra essere una soluzione complicata (attendere la risposta .. controllare la bandiera con un certo intervallo di tempo .. non molto impressionante)

2) Un approccio più diretto è quello di fare qualcosa in openfire, quando openfire non può consegnare un messaggio lo memorizza nella tabella offline, possiamo fare alcune intercettazioni su quella parte e avviare il processo push con il messaggio. Questo sembra essere l'approccio corretto, ma ho davvero paura di ottenere tutto questo all'interno di openfire e cambiare qualcosa (Potrebbe essere facile anche, qualcuno che ha lavorato un po 'con il fuoco aperto può dire?)

3) Questo è il mio ultimo resort, e questa non è una soluzione .. ma se non riesco a farlo correttamente entro i tempi previsti (che è una settimana da ora), abbiamo in programma di inviare una notifica push per tutti i messaggi. oppenfire prenderà in considerazione la normale chat mentre un push verrà inviato dal nostro server per ogni messaggio ma quando l'app è in primo piano, facciamo qualcosa per gestire i messaggi push extra che non devono essere mostrati, altrimenti viene ricevuto un push ogni volta che c'è un Messaggio. Cosa ne pensate voi di questo modo temporaneo (dovremo ovviamente cambiarlo il più presto possibile), è fattibile (o mi manca qualcosa anche qui).

P.S. Qualcuno può dire come Whatsapp e altre popolari app gestiscono questo?

Molte grazie per il vostro aiuto.

+0

grazie per la menzione del protocollo xep-0184! – VinceFR

+0

Segnala questo collegamento http://stackoverflow.com/questions/30253948/how-to-send-push-notification-to-offline-users-of-xmpp/30530294#30530294 – Parthpatel1105

risposta

6

XMPP richiede una connessione socket persistente o una connessione BOSH "persistente" durante l'intera sessione XMPP. Penso che la tua sfida sia che iOS non ti consente di eseguire l'app e il socket in background. Ogni volta che la tua app iOS passa in background, iOS uccide la tua connessione socket e il tuo server Openfire uccide la tua sessione XMPP. Ciò significa che l'utente va offline. Questo è anche il motivo per cui i messaggi in arrivo per questo utente passano alla memoria offline.

Ci scusiamo per questa risposta, ma tutte e 3 le soluzioni che hai suggerito sono terribili hack ;-). Se vuoi trovare una buona soluzione devi andare molto in profondità in XMPP e iOS. 1 settimana è un periodo molto breve per questo.

Qualcuno può dire come Whatsapp e altre app popolari gestiscono questo?

Mantengono in vita la sessione XMPP. Funziona solo con server XMPP altamente modificati, tra cui "XMPP Client Proxy" tra i quali mantiene la sessione in esecuzione mentre la tua app è in background, o una combinazione o entrambi.

+0

Grazie Alex. Come ho capito fino ad ora, quando l'app viene messa in sospensione da iOS (dopo 10 minuti di esecuzione in background), non può eseguire altri codici, ma quando è in background, dovrebbe essere in grado di ricevere messaggi e generare notifiche internamente (non push). Stai dicendo che non è possibile ?? io sono morta!! :(... quindi, per whatsapp anche ios deve uccidere la connessione socket, ma come hai detto, lo stanno gestendo dal proxy client xmpp? giusto? – shailesh

+0

Si prega di leggere qui l'applicazione iOS afferma: http: // developer .apple.com/library/ios/# documentazione/iphone/concettuale/iphoneosprogrammingguide/ManagingYourApplicationsFlow/ManagingYourApplicationsFlow.html – Alex

+5

@alex risposta è sbagliata, che cosa è l'uso di app server per il monitoraggio quando l'utente è in linea e utilizzare notifica push, non puoi mantenere ur app dal vivo sempre – DivineDesert

2

Ho una soluzione per te.

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

} 

E ovunque si invii messaggi ad altri utenti in chat. Fai questo

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