How to determine the message status (read/unread). Chat is realized with the XMPP protocol.
-
3Have you succeeded in this matter? I'm curious myself on how to do it – Dani Pralea Mar 12 '12 at 15:16
-
I am also curious on how to do it... – Sirius Apr 04 '12 at 05:21
-
If anyone is success in this please share some information @danipralea – Juned Nov 06 '12 at 11:41
4 Answers
XEP-0184: Message Delivery Receipts supports notifying senders when their message has been delivered. You might be able to use that as a building block, as long as you don't expect existing clients to send these receipts -- the XEP is not widely-implemented today.

- 10,354
- 2
- 38
- 48
-
I have implemented this feature and working successfully. I am confused how to decide message is delivered or read? Because there is not any provision to store message status delivery. Can you please suggest me what do I need to do? – Jayeshkumar Sojitra Apr 22 '15 at 12:53
-
It is difficult to tell if a message has actually been read. This is one of the main reasons existing clients don't implement the XEP. I would say being able to tell if the message has been displayed is about the best you can do. If the client is the application on top while the tab with the message is the tab being displayed, and the message has been inside the scroll window while in that state, it's probably been displayed. – Joe Hildebrand Apr 22 '15 at 17:08
If you want to get the read receipts then instead of sending auto message delivery receipts, send it whenever user reads that message. Each message has it's corresponding message_id. Use that message_id to send the delivery receipt for the particular message that has been read. Add following code while making connection
//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];
I solved this problem by adding 'chatStatus' attribute in my message entity. For sender I have kept value of chatStatus as sent, unsent, or received(received by other side or not). For Receiver Side I have kept the Values as read or unread(Have I read message or not, So that for unread message I could send read Receipts).
On Click Of send Button:
//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"]];
}
}
And finally when you receive the delivery Receipt in didReceiveMessage, update the chatStatus to received
- (void)xmppStream:(XMPPStream *)sender didReceiveMessage:(XMPPMessage *)message{
if ([message hasReceiptResponse]) {//message read
//Update database message entity
[self updateChatStatus:@"received" withMessageID:[message receiptResponseID]];
}
}
You could set the values of chatStatus as per your requirement. As for unsent messages I have set it as sent in didSendMessage delegate.
Note: In my app I had to just show the read, sent and unset status, not the delivered status. If you also wanna show delivery status, then don't comment autoSendMessageDeliveryReceipts and whenever messages are read send the IQ stanza to sender instead of delivery receipt and change the chatStatus accordingly.
This is just the basic idea, you could use it as per your requirement.
Hope it Helps!!

- 354
- 1
- 9
I think you need to use the Displayed Chat Marker, per http://xmpp.org/extensions/xep-0333.html

- 316
- 3
- 8
Xmpp does not have a read/unread receipt. While received is something that was implemented in XEP-0184.

- 43
- 8