4
votes

Scenario:


Issue:

  • Messages that I sent to an offline user is lost.
  • The user, when he comes online is not receiving the offline messages.
  • In group Chat, it is fine, cuz if the user is Joined to ChatRoom again, he by default receives all messages.
  • But in one-to-one chat, the messages are lost.

Saving all Chat History and retrieving them has already been implemented. I am using XMPPMessageArchiving & XMPPMessageArchivingCoreDataStorage to achieve the same.

It will be very helpful, if someone can point me to the right direction to solve this issue.

3
what xmpp server you are using? Make sure offline storage is enabledvitalyster
Can you pls share how you saved Chat History and retrieve ...LittleRider

3 Answers

7
votes

Off-line messages are the responsibility of the server. How to handle off-line messages is explained in XEP- 160

On the client side, you'll want to make sure you are sending message stanzas with types of "normal" or "chat".

You'll also want to make sure you have off-line message storage enabled in eJabberd.

After you coming online you can get all offline messages one by one in

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

XMPPMessage will be like the following, with a delay and timestamp tag.

<message xmlns="jabber:client" from="demo@demoHost/demoResource" to="you@demoHost" type="chat" id="234E5B61-C450-4F15-B2E6-5AF68AA8D376"><body>offline message test body</body><html xmlns="http://jabber.org/protocol/xhtml-im"><body xmlns="http://www.w3.org/1999/xhtml" style="background-color:#e9e9e9;color:#000000;"><span style="font-family: 'Helvetica';font-size: 12px;">offline message test body</span></body></html><x xmlns="jabber:x:event"><composing></composing></x><active xmlns="http://jabber.org/protocol/chatstates"></active><delay xmlns="urn:xmpp:delay" from="suhailk-imac.local" stamp="2014-09-19T10:41:50Z">Offline Storage</delay><x xmlns="jabber:x:delay" stamp="20140919T10:41:50"></x></message>
2
votes

Whenever user comes online, send presence of user using XMPPPresence. As soon as ejabberd gets to know user is present, it will send all the offline messages back to the user

1
votes

I am also try to get all message from server but unable to get. So I retrieve message using in XMPPMessageArchivingCoreDataStorage and XMPPMessageArchiving

First declare the variables

 private var xmppMessageStorage: XMPPMessageArchivingCoreDataStorage?
 private var stream = XMPPStream()
 private var xmppMessageArchiving: XMPPMessageArchiving?

When start connection

// for retrive old chat messages
xmppMessageStorage = XMPPMessageArchivingCoreDataStorage.sharedInstance()
xmppMessageArchiving = XMPPMessageArchiving(messageArchivingStorage: xmppMessageStorage)
xmppMessageArchiving?.clientSideMessageArchivingOnly = true
xmppMessageArchiving?.activate(stream) //By this line all your messages are stored in CoreData
xmppMessageArchiving?.addDelegate(self, delegateQueue: DispatchQueue.main)

This method used get offline messages in CoreData for particular user

func getArchieveMessages(forUser user:String){
    
    let fetchRequest = NSFetchRequest<NSFetchRequestResult>()
    fetchRequest.predicate = NSPredicate(format: "bareJidStr = %@", user)
    let context = xmppMessageStorage?.mainThreadManagedObjectContext
    var messageEntity: NSEntityDescription? = nil
    if let context = context {
      messageEntity = NSEntityDescription.entity(forEntityName: "XMPPMessageArchiving_Message_CoreDataObject", in: context)
    }
    
    fetchRequest.entity = messageEntity
    
    let sortDescriptor = NSSortDescriptor(key: "timestamp", ascending: false)
    fetchRequest.sortDescriptors = [sortDescriptor]
    var results: [Any]? = []
    do {
      results = try context?.fetch(fetchRequest)
      self.modelController.delegate?.localHistoryMessages(results ?? [])
    } catch let error {
      debugPrint(error.localizedDescription)
    }
    debugPrint(results as Any)
}