2011-09-13 100 views

回答

6

XEP-0184:消息傳遞迴執支持在發送消息時通知發件人。只要您不希望現有客戶發送這些收據,您可以將其用作構建模塊 - XEP目前尚未廣泛實施。

+0

我已經實現了這個功能,併成功地工作。我很困惑如何決定郵件是傳遞還是閱讀?因爲沒有任何規定來存儲消息狀態傳遞。你能告訴我我需要做什麼? –

+0

很難判斷消息是否真的被讀取過。這是現有客戶不實施XEP的主要原因之一。我會說,能夠告訴消息是否已經顯示是你所能做的最好的。如果客戶端是頂部的應用程序,而帶有消息的選項卡是顯示的選項卡,並且該消息在該狀態下處於滾動窗口內部,則可能顯示該消息。 –

0

XMPP協議不具有讀/未讀回執。雖然收到的是在XEP-0184中實施的東西。

1

如果您希望獲取已讀回執,而不是發送自動消息傳遞收據,則只要用戶閱讀該消息就發送它。每條消息都有相應的message_id。使用該message_id發送已讀取的特定消息的傳遞收據。在建立連接時添加以下代碼

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

我通過在消息實體中添加「chatStatus」屬性來解決此問題。對於發件人,我已將chatStatus的值保存爲發送,未發送或接收(由其他方接收或不接收)。對於接收方我已經將值保持爲已讀或未讀(我是否閱讀過郵件,因此對於未讀郵件,我可以發送已讀收據)。

在點擊發送按鈕:

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

在的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"]]; 
     } 
    } 

最後,當您收到送達回執didReceiveMessage,更新chatStatus收到

- (void)xmppStream:(XMPPStream *)sender didReceiveMessage:(XMPPMessage *)message{ 

if ([message hasReceiptResponse]) {//message read 
//Update database message entity 
[self updateChatStatus:@"received" withMessageID:[message receiptResponseID]]; 
} 
} 

您可以根據您的要求設置chatStatus的值。至於未發送的消息,我已將它設置爲在didSendMessage委託中發送。

注意:在我的應用程序,我不得不只顯示讀取,發送和未設置狀態,而不是交付狀態。如果您還想要顯示送貨狀態,則不要評論autoSendMessageDeliveryReceipts,並且每次閱讀郵件時,都會將IQ節發送給發件人,而不是發送收據並相應地更改chatStatus。

這只是基本的想法,你可以根據你的要求使用它。

希望它有助於!

相關問題