Come determinare lo stato del messaggio (letto/non letto). La chat è realizzata con il protocollo XMPP.Come determinare lo stato del messaggio (letto/non letto) nella chat?
risposta
XEP-0184: I messaggi di recapito della consegna supportano i mittenti di notifica quando il loro messaggio è stato recapitato. Potresti essere in grado di usarlo come elemento di base, a patto che non ti aspetti che i client esistenti inviino queste ricevute: oggi il XEP non è ampiamente implementato.
Ho implementato questa funzione e sto lavorando con successo. Sono confuso su come decidere che il messaggio viene consegnato o letto? Perché non esiste alcuna disposizione per memorizzare la consegna dello stato dei messaggi. Potete per favore suggerirmi cosa devo fare? –
È difficile capire se un messaggio è stato effettivamente letto. Questo è uno dei motivi principali per cui i client esistenti non implementano XEP. Direi che riuscire a capire se il messaggio è stato visualizzato è il meglio che si possa fare. Se il client è l'applicazione in cima mentre la scheda con il messaggio è la scheda che viene visualizzata e il messaggio è stato all'interno della finestra di scorrimento mentre si trova in quello stato, probabilmente è stato visualizzato. –
Penso che avete bisogno di utilizzare la chat marcatore visualizzato, per http://xmpp.org/extensions/xep-0333.html
XMPP non ha una lettura/ricevuta non letti. Mentre ricevuto è qualcosa che è stato implementato in XEP-0184.
Se si desidera ottenere le conferme di lettura, invece di inviare ricevute di consegna di messaggi automatici, inviarlo ogni volta che l'utente legge quel messaggio. Ogni messaggio ha il suo message_id corrispondente. Utilizzare tale message_id per inviare la ricevuta di consegna per il messaggio specifico che è stato letto. Aggiungere seguente codice mentre si effettua il collegamento
//message delivery
XMPPMessageDeliveryReceipts* xmppMessageDeliveryRecipts = [[XMPPMessageDeliveryReceipts alloc] initWithDispatchQueue:dispatch_get_main_queue()];
//don't write this line as it will send auto receipts whenever message will be delivered
//xmppMessageDeliveryRecipts.autoSendMessageDeliveryReceipts = YES;
xmppMessageDeliveryRecipts.autoSendMessageDeliveryRequests = YES;
[xmppMessageDeliveryRecipts activate:self.xmppStream];
Ho risolto questo problema con l'aggiunta di attributo 'chatStatus' nella mia entità messaggio. Per il mittente ho mantenuto il valore di chatStatus come inviato, non inviato o ricevuto (ricevuto dall'altra parte o meno). Per il lato ricevitore, ho mantenuto i valori letti o non letti (ho letto o meno il messaggio, in modo che per i messaggi non letti potessi inviare le conferme di lettura).
al click del pulsante di invio:
//Save to your Message Entity
NSMutableDictionary *m = [[NSMutableDictionary alloc] init];
[m setObject: message_body forKey:@"message_body"];
[m setObject:messageID forKey:@"message_id"];
[m setObject:@"yes" forKey:@"isOutgoing"];
[m setObject:dateString forKey:@"date"];
[m setObject:timeString forKey:@"time"];
[m setObject:[NSDate date] forKey:@"timeStamp"];
[m setObject:yourId forKey:@"from"];
[m setObject:toId forKey:@"to"];
if (!Is_InternetAvailable]) {
[m setObject:unsent forKey:@"chatStatus"];
}
else{
[m setObject:sent forKey:@"chatStatus"];
}
[[CoreDataMethods sharedCoreDataMethods] saveUserMessage:m];
}
In cellForRowAtIndexPath:
if ([message isoutGoing]) {//If I have sent the message
// Mine bubble
if ([[messageDict valueForKey:@"chatStatus"] isEqualToString:unsent]) {
//set unsent image
}
else if ([[messageDict valueForKey:@"chatStatus"] isEqualToString:sent]){
//set sent image
}
else if ([[messageDict valueForKey:@"chatStatus"] isEqualToString:received]){
//set Received Image
}
}
else{
// Other Bubble , Notify them that you have read the message if it is unread/new message
if ([[messageDict valueForKey:@"chatStatus"] isEqualToString:unread]) {
//send read receipt
NSXMLElement *receivedelement = [NSXMLElement elementWithName:@"received" xmlns:@"urn:xmpp:receipts"];
NSXMLElement *message = [NSXMLElement elementWithName:@"message" xmlns:@"jabber:client"];
[message addAttributeWithName:@"to" stringValue:toId];
[message addAttributeWithName:@"from" stringValue:fromID];
[receivedelement addAttributeWithName:@"id" stringValue:[messageDict valueForKey:@"message_id"]];
[message addChild:receivedelement];
//XMPPMessage *generatedReceiptResponse = [[messageDict valueForKey:@"xmppMessage"] generateReceiptResponse];
[[[kAppDelegate xmppHandler] xmppStream] sendElement:message];
// update message entity
[self updateChatStatus:read withMessageID:[messageDict valueForKey:@"message_id"]];
}
}
E infine quando si riceve la conferma di recapito in didReceiveMessage, aggiornare il chatStatus al ricevuto
- (void)xmppStream:(XMPPStream *)sender didReceiveMessage:(XMPPMessage *)message{
if ([message hasReceiptResponse]) {//message read
//Update database message entity
[self updateChatStatus:@"received" withMessageID:[message receiptResponseID]];
}
}
È possibile impostare i valori di chatStatus secondo le proprie esigenze. Per quanto riguarda i messaggi non inviati, l'ho impostato come inviato nel delegato didSendMessage.
Nota: Nella mia app dovevo solo mostrare lo stato di lettura, invio e disinserimento, non lo stato di consegna. Se vuoi anche mostrare lo stato di consegna, non commentare autoSendMessageDeliveryReceipts e ogni volta che i messaggi vengono letti, invia la stanza IQ al mittente invece della ricevuta di consegna e cambia di conseguenza il chatStatus.
Questa è solo l'idea di base, è possibile utilizzarlo secondo le vostre esigenze.
Spero che aiuti!
Sei riuscito a questo problema? Sono curioso di sapere come farlo –
Sono anche curioso di sapere come farlo ... – Sirius
Se qualcuno ha successo in questo, per favore condividi alcune informazioni @danipralea – juned