Saving XMPP Multi User chat messages through XMPP MessageArchiving in iOS - ios

I am developing a chat application in iOS using XMPP. I have so far successfully implemented and tested a single user chat scenario, i.e. sending, receiving, saving and retrieving messages.
The problem now em facing is that now when handling Multi User Chat scenarios em receiving it but not able to save them using XMPP MessageArchiving hence cant retrieve them either.
Anyone who has gone through this process/problem?
Thank you in advance

Messages with groupchat type may be saved within XMPPRoom.xcdatamodel, you need to initialize the XMPPRoomCoreDataStorage in your xmpp setup like:
XMPPRoomCoreDataStorage *xmppRoomStorage = [[XMPPRoomCoreDataStorage alloc] init];
So, this class implements a method to insert all the messages ROOM within the correct data model (in our case, all the outgoing and incoming messages are saved in XMPPRoom.xcdatamodel).
- (void)insertMessage:(XMPPMessage *)message
outgoing:(BOOL)isOutgoing
forRoom:(XMPPRoom *)room
stream:(XMPPStream *)xmppStream
More XEP-0045 info http://xmpp.org/extensions/xep-0045.html

You can use this code for a saving room messages
NSString *xmppRoomJIDString = [NSString stringWithFormat:#"%##conference.your_host", #"your_room_name"];
XMPPJID *roomJID = [XMPPJID jidWithString:xmppRoomJIDString];
XMPPRoomCoreDataStorage *roomCoreDataStorage = [XMPPRoomCoreDataStorage sharedInstance];
XMPPRoom *xmppRoom = [[XMPPRoom alloc]
initWithRoomStorage:roomCoreDataStorage
jid:roomJID
dispatchQueue:dispatch_get_main_queue()];
[xmppRoom activate:xmppStream];
[xmppRoom addDelegate:self delegateQueue:dispatch_get_main_queue()];
[xmppRoom joinRoomUsingNickname:#"your_nicke_name" history:nil];
[xmppRoom fetchConfigurationForm];

Related

Getting duplicate message while retrieving messages from History

I'm created group chat in Openfire & XMPP.
I'm getting history from Openfire server using "since" while joining room.
Here is my code :
XMPPRoomMemoryStorage *roomStorage = [[XMPPRoomMemoryStorage alloc] init];
XMPPJID *roomJID = [XMPPJID jidWithString:chatWithUser];
xmppRoom = [[XMPPRoom alloc] initWithRoomStorage:roomStorage
jid:roomJID
dispatchQueue:dispatch_get_main_queue()];
[xmppRoom activate:self.xmppStream];
[xmppRoom addDelegate:self
delegateQueue:dispatch_get_main_queue()];
NSXMLElement *history = [NSXMLElement elementWithName:#"history"];
[history addAttributeWithName:#"since" stringValue:finalDate];
[xmppRoom joinRoomUsingNickname:self.xmppStream.myJID.user
history:history
password:nil];
I store message in local so next time user when login it fetch last message date from local and send it to server to fetch all message after that date.
finalDate is date from that i fetch from local and send it to server.
But what happern is that when i send finalDate to server it fetch last message also that i already stored in local database.
If my last message from localDB is 'Hi' and date '2016-08-08T04:52:42.347Z' than it fetch 'Hi' from server.
Why this happen ? I want message from server after date.
The problem of XMPP MUC specification is - history messages are stamped with server time, while you ask since your local time. There is an XMPPAutoTime module in XMPPFramework, which trying to track time difference and you should add that difference for any timestamp-based queries. Check the detailed description here

How to retrieve offline message openfire XMPP?

I Successfully implemented group chat using Openfire with XMPP.
Now when User A send message to User B who is offline, So when User B is online how can I retrieve all unread/offline messages from server.
I'm doing this stuff to join the room but it getting all messages from server :
- (void) getJoinRoom
{
XMPPRoomMemoryStorage *roomStorage = [[XMPPRoomMemoryStorage alloc] init];
XMPPJID *roomJID = [XMPPJID jidWithString:chatWithUser];
xmppRoom = [[XMPPRoom alloc] initWithRoomStorage:roomStorage
jid:roomJID
dispatchQueue:dispatch_get_main_queue()];
[xmppRoom activate:self.xmppStream];
[xmppRoom addDelegate:self
delegateQueue:dispatch_get_main_queue()];
[xmppRoom joinRoomUsingNickname:self.xmppStream.myJID.user
history:nil
password:nil];
}
How do I fetch those offline messages ?
As per XMPP standard, only one-one chat messages are eligible for offline storage, so messages of type="groupchat" are never stored in offline storage in XMPP Servers.
As per MUC XEP if a user goes offline, it doesn't count as a participant of the room any more. So when the user comes online, he will have to join the room by sending presence packet to the room.

Robbiehanson xmpp framework for iOS not receiving chat messages

Trying to create a very simple proof of concept iOS xmpp app with the robbiehanson xmpp frame work, just need to be able to send and receive messages and roster data. I can authenticate and send messages successfully, but when users attempt to respond to my messages I do not receive them. I have implemented the didReceiveMessage delegate method as follows:
-(void)xmppStream:(XMPPStream *)sender didReceiveMessage:(XMPPMessage *)message {
NSLog(#"incoming message: %#", message);
}
but I never receive this log. If I log in with the existing web app or android app that communicates with this xmpp server I receive these messages, so I'm inclined to believe they are formatted properly. Is there a module I need to add to the XMPPStream for receiving messages? I'm setting up the stream like this (some of the string values have been changed for security and what not):
stream = [[XMPPStream alloc] init];
stream.enableBackgroundingOnSocket = YES;
stream.hostName = #"hostname.com";
stream.hostPort = 5222;
XMPPRosterCoreDataStorage* xmppRosterStorage = [[XMPPRosterCoreDataStorage alloc] initWithInMemoryStore];
XMPPRoster* xmppRoster = [[XMPPRoster alloc] initWithRosterStorage:xmppRosterStorage];
xmppRoster.autoFetchRoster = YES;
xmppRoster.autoAcceptKnownPresenceSubscriptionRequests = YES;
[stream addDelegate:self delegateQueue:dispatch_get_main_queue()];
XMPPJID* jid = [XMPPJID jidWithUser:#"username" domain:#"domain.com" resource:#"iOS"];
[stream setMyJID:jid];
[xmppRoster activate:stream];
[stream connectWithTimeout:XMPPStreamTimeoutNone error:&error]
and then in the xmppStreamDidConnect method I do this to authenticate
NSString *myPassword = #"password";
NSError *error = nil;
[stream authenticateWithPassword:myPassword error:&error]
When I am sending a message out I use this snippet:
MPPJID* recipient = [XMPPJID jidWithString:#"user#domain.com"];
XMPPMessage* message = [[XMPPMessage alloc] initWithType:#"chat" to:recipient];
[message addBody:#"hello world"];
[stream sendElement: message];
I'm thinking there is something simple I am missing that someone who has used this before will be able to point out to me right away. I'm ready to supply other info if necessary for solving this issue.
I simply needed to broadcast my presence, then I was able to receive messages.
I added these lines to the streamDidAuthenticate method
XMPPPresence *presence = [XMPPPresence presence];
[sender sendElement:presence];

Add a user to xmpp group or in muc

I want to add 4 members (who are already users in oprefire) to a group.
I want to add them without user permission nor sending invitation
Right now i am inviting a user using this code:
[sender inviteUser:[XMPPJID jidWithString:#"keithoys"] withMessage:#"Greetings!"];
Is there some another way to achieve this?
When user send request to other user, the following delegate method is called:
-(void)xmppMUC:(XMPPMUC *)sender roomJID:(XMPPJID *)roomJID didReceiveInvitation:(XMPPMessage *)message{
roomMemoryStorage = [[XMPPRoomMemoryStorage alloc] init];
xmppRoom = [[XMPPRoom alloc]
initWithRoomStorage:roomMemoryStorage
jid:roomJID
dispatchQueue:dispatch_get_main_queue()];
[xmppRoom activate:[self xmppStream]];
[xmppRoom addDelegate:self delegateQueue:dispatch_get_main_queue()];
//Now add user to the group directly without prompting them
[xmppRoom joinRoomUsingNickname:[xmppStream myJID].user history:nil];
}
I've only written the code, if you need explanation, i'll.

Single chat and group chat at same time in xmpp

In my application my User to User single chat is working perfectly.
but if I send the invitation of Room to any User then single chat is not working.
and I didn't attach group chat code in app yet. just send invitation of Room to other user and then creating single chat.
is there anything logically I missed ?
My code for creating and inviting
XMPPRoomMemoryStorage * _roomMemory = [[XMPPRoomMemoryStorage alloc]init];
NSString* roomID = [NSString stringWithFormat:#"%##conference.room",strGlobalRoomNameForLogin];
XMPPJID * roomJID = [XMPPJID jidWithString:roomID];
xmppRoom = [[XMPPRoom alloc] initWithRoomStorage:_roomMemory jid:roomJID dispatchQueue:dispatch_get_main_queue()];
[xmppRoom activate:xmppStream];
[xmppRoom joinRoomUsingNickname:[NSString stringWithFormat:#"%#",strCureentUserName] history:nil];
//NSLog(#"strCureentUserName %#",strCureentUserName);
//.........inviting the Friend.......
for (int i=0; i<[arrUserName count];i++) {
NSString *strInviteUserEmalid = [[arrUserName objectAtIndex:i] stringByReplacingOccurrencesOfString:#"#" withString:#"$"];
// NSLog(#"strInviteUserEmalid %#",strInviteUserEmalid);
[xmppRoom inviteUser:[XMPPJID jidWithString:[NSString stringWithFormat:#"%##user",strInviteUserEmalid]] withMessage:#"Come Join me in this room"];
}
[xmppRoom fetchConfigurationForm];
[xmppRoom configureRoomUsingOptions:nil];
[xmppRoom addDelegate:_roomMemory delegateQueue:dispatch_get_main_queue()];
For large numbers of invitees, you may be running into "karma" limits on your server. Try sending the invites slower by adding a timeout.

Resources