how to check received message is read or unread in xmpp framework in ios

后端 未结 2 1542
北海茫月
北海茫月 2021-02-01 11:03

i am developing chat application using xmppframework and i am successfully completed the send and receive message , but

1) if i am chat with user A and user B send me

相关标签:
2条回答
  • 2021-02-01 11:48

    For users who are facing the same problem.

    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 line 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, but we want to send delivery receipts when user has read the message.
        //xmppMessageDeliveryRecipts.autoSendMessageDeliveryReceipts = YES;
        xmppMessageDeliveryRecipts.autoSendMessageDeliveryRequests = YES;
        [xmppMessageDeliveryRecipts activate:self.xmppStream];
    

    I have used '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.On sender side you have to take one one value for chatStatus sent, unsent, received, delivered.

    Hope it Helps!!

    0 讨论(0)
  • 2021-02-01 12:04

    You can have look to XEP-0184

    This should be the message stanza format

    <message
        from='sender@domain/resource'
        id='messageId-1010'
        to='receiver@domain/resource'>
      <body>your message </body>
      <request xmlns='urn:xmpp:receipts'/>
    </message>
    

    And This is received response message

    <message
        from='receiver@domain/resource'
        id='packetId'
        to='sender@domain/resource'>
      <received xmlns='urn:xmpp:receipts' id='messageId-1010'/>
    </message>
    

    Here messageId-1010 will be unique to get you know which message response it is.

    0 讨论(0)
提交回复
热议问题