I am using Robbiehanson's iOS XMPPFramework. I am trying to create a MUC room and invite a user to the group chat room but it is not working.
I am using the following code:
XMPPRoom *room = [[XMPPRoom alloc] initWithRoomName:#"user101#conference.jabber.org/room" nickName:#"room"];
[room createOrJoinRoom];
[room sendInstantRoomConfig];
[room setInvitedUser:#"ABC#jabber.org"];
[room activate:[self xmppStream]];
[room inviteUser:jid1 withMessage:#"hello please join."];
[room sendMessage:#"HELLO"];
The user ABC#jabber.org should receive the invite message but nothing is happening.
Any help will be appreciated. :)
After exploring various solutions, I've decided to compile and share my implementation here:
Create an XMPP Room:
XMPPRoomMemoryStorage *roomStorage = [[XMPPRoomMemoryStorage alloc] init];
/**
* Remember to add 'conference' in your JID like this:
* e.g. uniqueRoomJID#conference.yourserverdomain
*/
XMPPJID *roomJID = [XMPPJID jidWithString:#"chat#conference.shakespeare"];
XMPPRoom *xmppRoom = [[XMPPRoom alloc] initWithRoomStorage:roomStorage
jid:roomJID
dispatchQueue:dispatch_get_main_queue()];
[xmppRoom activate:[self appDelegate].xmppStream];
[xmppRoom addDelegate:self
delegateQueue:dispatch_get_main_queue()];
[xmppRoom joinRoomUsingNickname:[self appDelegate].xmppStream.myJID.user
history:nil
password:nil];
Check if room is successfully created in this delegate:
- (void)xmppRoomDidCreate:(XMPPRoom *)sender
Check if you've joined the room in this delegate:
- (void)xmppRoomDidJoin:(XMPPRoom *)sender
After room is created, fetch room configuration form:
- (void)xmppRoomDidJoin:(XMPPRoom *)sender {
[sender fetchConfigurationForm];
}
Configure your room
/**
* Necessary to prevent this message:
* "This room is locked from entry until configuration is confirmed."
*/
- (void)xmppRoom:(XMPPRoom *)sender didFetchConfigurationForm:(NSXMLElement *)configForm
{
NSXMLElement *newConfig = [configForm copy];
NSArray *fields = [newConfig elementsForName:#"field"];
for (NSXMLElement *field in fields)
{
NSString *var = [field attributeStringValueForName:#"var"];
// Make Room Persistent
if ([var isEqualToString:#"muc#roomconfig_persistentroom"]) {
[field removeChildAtIndex:0];
[field addChild:[NSXMLElement elementWithName:#"value" stringValue:#"1"]];
}
}
[sender configureRoomUsingOptions:newConfig];
}
References: XEP-0045: Multi-User Chat, Implement Group Chat
Invite users
- (void)xmppRoomDidJoin:(XMPPRoom *)sender
{
/**
* You can read from an array containing participants in a for-loop
* and send multiple invites in the same way here
*/
[sender inviteUser:[XMPPJID jidWithString:#"keithoys"] withMessage:#"Greetings!"];
}
There, you've created a XMPP multi-user/group chat room, and invited a user. :)
I have the feeling that the first thing to do after alloc-init is to attach it to your xmppStream, so it can use xmppStream to send/receive messages.
More exactly:
XMPPRoom *room = [[XMPPRoom alloc] initWithRoomName:#"user101#conference.jabber.org/room" nickName:#"room"];
[room activate:[self xmppStream]];
//other things (create/config/...)
Check the latest XMPPMUCLight & XMPPRoomLight its similar to Whatsapp and other today's trends social app rooms that don't get destroyed or members kicked when offline or no one in room.
Refer this documentation & mod from MongooseIM
Related
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.
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.
In my application if i am sending invitation to other user then moderator and all user who got the request will join the room but if another user will send the request to all then moderator of previous room is not getting invitation.
For Example:
user 1 will send invitation for Room 1 to user 2 and user 3 then all three are in Room 1.
if User 2 will send invitation for Room 2 to User 1 and User 3 then User 1 will is not getting invitation.
And also if User 3 will send invitation for Room 3 then User 3 only be present in Room and all other two are not getting invitation too.
In my application i am inviting other user with this request
XMPPRoomMemoryStorage * _roomMemory = [[XMPPRoomMemoryStorage alloc]init];
NSString* roomID = [NSString stringWithFormat:#"RoomName#conference.openfire id"];
XMPPJID * roomJID = [XMPPJID jidWithString:roomID];
xmppRoom = [[XMPPRoom alloc] initWithRoomStorage:_roomMemory jid:roomJID dispatchQueue:dispatch_get_main_queue()];
[xmppRoom addDelegate:_roomMemory delegateQueue:dispatch_get_main_queue()];
[xmppRoom activate:xmppStream];
[xmppRoom joinRoomUsingNickname:[NSString stringWithFormat:#"%#",strCureentUserName] history:nil];
//.........inviting the Friend.......
for (int i=0; i<[arrUserName count];i++) {
[xmppRoom inviteUser:[XMPPJID jidWithString:[NSString stringWithFormat:#"Invite user's ID"]] withMessage:#"Come Join me in this room"];
}
[xmppRoom fetchConfigurationForm];
[xmppRoom configureRoomUsingOptions:nil];
and other user gets invitation here
- (void)xmppStream:(XMPPStream *)sender didReceiveMessage:(XMPPMessage *)message
{
NSXMLElement * x = [message elementForName:#"x" xmlns:XMPPMUCUserNamespace];
NSXMLElement * invite = [x elementForName:#"invite"];
NSXMLElement * decline = [x elementForName:#"decline"];
NSXMLElement * directInvite = [message elementForName:#"x" xmlns:#"jabber:x:conference"];
NSString *msg1 = [[message elementForName:#"body"]stringValue];
NSString *from1 = [[message attributeForName:#"from"]stringValue];
if (invite || directInvite)
{
NSLog(#"come in invite method of if condition");
[self createAndEnterRoom:from1 Message:msg1];
return;
}
How to get invitation from all user all the time.
Any kind of help is welcomed...
Thanks in Advance.
I'm actually working on it, I use XMPPMUC delegate (MUC stands for MultiUserChat)
Delegate has this method :
-(void)xmppMUC:(XMPPMUC *)sender roomJID:(XMPPJID *)roomJID didReceiveInvitation:(XMPPMessage *)message
{
}
I haven't done this yet, but I guess that you could search on this...
I think you made mistake while inviting users.You just use an array of user to invite other peoples that's fine but invitation must be sent when this XMPPRooms's delegate method call
- (void)xmppRoomDidJoin:(XMPPRoom *)sender
{
/**
* You can read from an array containing participants in a for-loop
* and send multiple invites in the same way here
*/
[sender inviteUser:[XMPPJID jidWithString:#"arpan"] withMessage:#"Greetings!"];
}
Just use XMPPRoomdelegates in proper way to invite user.Refer thins link for delegates..
XMPPFramework - How to create a MUC room and invite users?
I'm able to create a MUC using XMPPFramework and send user invitation requests to join that room by using the code below.
// Creating
AppDelegate *dele =(AppDelegate *) [[UIApplication sharedApplication]delegate];
xmppRoom = [[XMPPRoom alloc] initWithRoomStorage:dele jid:[XMPPJID jidWithString:self.roomName] dispatchQueue:dispatch_get_main_queue()];
[xmppRoom addDelegate:dele delegateQueue:dispatch_get_main_queue()];
[xmppRoom activate:dele.xmppStream];
[xmppRoom joinRoomUsingNickname:self.myNick history:nil];
// Inviting
[xmppRoom inviteUser:[XMPPJID jidWithString:#"abc#host"] withMessage:#"Come Join me"];
How does a user "abc" know that he has received an invitation and how can he react to it either by accepting or declining?
I could not find any class in XMPPFramework which directly deal with chat room invitation.
My research says that whenever a user receives an chatroom invitation, xmmppStream's delegate method is called:
- (void)xmppStream:(XMPPStream *)sender didReceiveMessage:(XMPPMessage *)message
In that message, I check whether the it contains NSXMLElement with name "invite", and if it contains then i send a callback to the user. Then i create chatroom with the same name as the name of the chatroom from which user received invitation and enter that newly created room. It works fine but quiet lengthy and not quiet efficient.
I want to know if there is a class in XMPPFramework available here which could handle chat room invitation separately. For instance, detecting, accepting, and declining of room invitations.
My code for extracting room name:
- (void)xmppStream:(XMPPStream *)sender didReceiveMessage:(XMPPMessage *)message
{
NSXMLElement * x = [message elementForName:#"x" xmlns:XMPPMUCUserNamespace];
NSXMLElement * invite = [x elementForName:#"invite"];
NSXMLElement * decline = [x elementForName:#"decline"];
NSXMLElement * directInvite = [message elementForName:#"x" xmlns:#"jabber:x:conference"];
NSString *msg = [[message elementForName:#"body"]stringValue];
NSString *from = [[[message attributeForName:#"from"]stringValue];
if (invite || directInvite)
{
[self createAndEnterRoom:from Message:msg];
return;
}
[self.delegate newMessageRecieved:msg];
}
For room invitations and declines, implement XMPPMUCDelegate and its methods -xmppMUC:didReceiveRoomInvitation: and -xmppMUC:didReceiveRoomInvitationDecline:.
To get the room JID, invoke [message from];
To join the room, instantiate an XMPPRoom and invoke -joinRoomUsingNickname:history:.
Then have your room delegate class implement XMPPRoomDelegate, and implement some of the delegate methods to handle receiving messages in the room.
It looks like there isn't at present a more automatic way to respond to invitations.
Update: The delegate callbacks now receive the room JID as a parameter, clarifying the semantics a bit.
- (void)xmppMUC:(XMPPMUC *)sender roomJID:(XMPPJID *) roomJID didReceiveInvitation:(XMPPMessage *)message;
- (void)xmppMUC:(XMPPMUC *)sender roomJID:(XMPPJID *) roomJID didReceiveInvitationDecline:(XMPPMessage *)message;
just add below code
if ([presenceType isEqualToString:#"subscribe"]) {
[_chatDelegate newBuddyOnline:[NSString stringWithFormat:#"%##%#", presenceFromUser, #"localhost"]];
NSLog(#"presence user wants to subscribe %#",presenceFromUser);
[xmppRoster acceptPresenceSubscriptionRequestFrom:[presence from] andAddToRoster:YES];
//For reject button
// [xmppRoster rejectPresenceSubscriptionRequestFrom:[tmpPresence from]];
}
inside the method
- (void)xmppStream:(XMPPStream *)sender didReceivePresence:(XMPPPresence *)presence ;
method
I have an application which I am using for one-to-one chat. Now I need to implement group chat. I know it is possible with XMPPFramework and there is a class called XMPPRoom which we can use to create a room or join a room. But I am unable to implement that in my project.
Can anyone please provide me some ideas, suggestions and if possible a sample application.
Thanks in advance :)
here you have a script that allows to connect to a room
[xmppRoom activate:[self xmppStream]];
[xmppRoom createOrJoinRoom];
In order to do this you should have access to the xmppStream.
- (void)createOrJoinRoomWithRoomName:(NSString *)roomName nickName:(NSString *)nickName
{
if(roomName && nickName)
{
_xmppRoomStorage = [XMPPRoomHybridStorage sharedInstance];
XMPPJID *roomJid = [XMPPJID jidWithString:[NSString stringWithFormat:#"%##%#.%#",roomName,#"conference",self.hostName]];
_xmppRoom = [[XMPPRoom alloc] initWithRoomStorage:_xmppRoomStorage jid:roomJid];
[_xmppRoom addDelegate:self delegateQueue:dispatch_get_main_queue()];
[_xmppRoom activate:_xmppStream];
NSXMLElement *history = [NSXMLElement elementWithName:#"history"];
[history addAttributeWithName:#"maxstanzas" stringValue:MAX_ROOM_HISTORY];
[_xmppRoom joinRoomUsingNickname:nickName history:history];
}
else
{
NSLog(#"room creation arguments missing");
}
}