My code to create a room:
XMPPRoomCoreDataStorage *rosterstorage = [[XMPPRoomCoreDataStorage alloc] init];
XMPPRoom *xmppRoom = [[XMPPRoom alloc] initWithRoo
First, take look here XEP-0045: Multi-User Chat.
As you can see, first you have to discover which capabilities your user (XMPPJID) has on the Jabber server.
To do this, send next command to your Jabber Server:
or writen in objective-c using XMPP library functions:
NSError *error = nil;
NSXMLElement *query = [[NSXMLElement alloc] initWithXMLString:@" "
error:&error];
XMPPIQ *iq = [XMPPIQ iqWithType:@"get"
to:[XMPPJID jidWithString:@"jabber.server.com"]
elementID:[xmppStream generateUUID] child:query];
[xmppStream sendElement:iq];
Now listen response from server in XMPPStream delegate - (BOOL)xmppStream:(XMPPStream *)sender didReceiveIQ:(XMPPIQ *)iq
and server response should be something like this:
or objective c:
- (BOOL)xmppStream:(XMPPStream *)sender didReceiveIQ:(XMPPIQ *)iq
{
if([iq isResultIQ])
{
if([iq elementForName:@"query" xmlns:@"http://jabber.org/protocol/disco#items"])
{
NSLog(@"Jabber Server's Capabilities: %@", [iq XMLString]);
}
}
}
Now for every item returned send IQ to your server for it's properties and figure out which one is type of conference, something like this:
or in objective c:
- (BOOL)xmppStream:(XMPPStream *)sender didReceiveIQ:(XMPPIQ *)iq
{
if([iq isResultIQ])
{
if([iq elementForName:@"query" xmlns:@"http://jabber.org/protocol/disco#items"])
{
NSXMLElement *query = [iq childElement];
NSArray *items = [query children];
for(NSXMLElement *item in items)
{
NSError *error = nil;
NSXMLElement *sendQuery = [[NSXMLElement alloc] initWithXMLString:@" "
error:&error];
XMPPIQ *sendIQ = [XMPPIQ iqWithType:@"get"
to:[XMPPJID jidWithString:[item attributeStringValueForName:@"jid"]]
elementID:[xmppStream generateUUID]
child:sendQuery];
[xmppStream sendElement:sendIQ];
}
}
}
}
Listen for responses from server:
and take group chat domain from identity with category:conference
- (BOOL)xmppStream:(XMPPStream *)sender didReceiveIQ:(XMPPIQ *)iq
{
if([iq isResultIQ])
{
if([iq elementForName:@"query" xmlns:@"http://jabber.org/protocol/disco#items"])
{
...
}
else if([iq elementForName:@"query" xmlns:@"http://jabber.org/protocol/disco#info"])
{
NSXMLElement *query = [iq childElement];
NSXMLElement *identity = [query elementForName:@"identity"];
if([[identity attributeStringValueForName:@"category"] isEqualToString:@"conference"])
{
groupChatDomain = [iq fromStr];
}
}
}
}
Finally, when we got group chat domain we can create chat room something like this:
XMPPJID *chatRoomJID = [XMPPJID jidWithUser:@"chat_room"
domain:groupChatDomain
resource:@"user"];
XMPPRoomMemoryStorage *roomMemoryStorage = [[XMPPRoomMemoryStorage alloc] init];
XMPPRoom *xmppRoom = [[XMPPRoom alloc] initWithRoomStorage:roomMemoryStorage
jid:roomChatJID
dispatchQueue:dispatch_get_main_queue()];
[xmppRoom activate:xmppStream];
[xmppRoom addDelegate:self delegateQueue:dispatch_get_main_queue()];
[xmppRoom joinRoomUsingNickname:user history:nil];
and add
protocol in your view controller and its delegates:
- (void)xmppRoomDidCreate:(XMPPRoom *)sender
- (void)xmppRoomDidDestroy:(XMPPRoom *)sender
- (void)xmppRoom:(XMPPRoom *)sender didConfigure:(XMPPIQ *)iqResult
- (void)xmppRoom:(XMPPRoom *)sender didNotConfigure:(XMPPIQ *)iqResult
- (void)xmppRoomDidJoin:(XMPPRoom *)sender
- (void)xmppRoomDidLeave:(XMPPRoom *)sender
- (void)xmppRoom:(XMPPRoom *)sender occupantDidJoin:(XMPPJID *)occupantJID withPresence:(XMPPPresence *)presence
- (void)xmppRoom:(XMPPRoom *)sender occupantDidLeave:(XMPPJID *)occupantJID withPresence:(XMPPPresence *)presence
- (void)xmppRoom:(XMPPRoom *)sender didReceiveMessage:(XMPPMessage *)message fromOccupant:(XMPPJID *)occupantJID
Note: Before inviting other users to Chat Room, you have to send and confirm room configurations (other users can be invited but messages can not be sent).
So you can do this after Room is created (delegate - (void)xmppRoomDidCreate:(XMPPRoom *)sender
is called) or your user has joined (delegate - (void)xmppRoomDidJoin:(XMPPRoom *)sender
is called) to Chat Room.
To send and confirm room configuration do one of the following:
- (void)xmppRoomDidCreate:(XMPPRoom *)sender
{
[sender configureRoomUsingOptions:nil];
}
or
- (void)xmppRoomDidJoin:(XMPPRoom *)sender
{
[sender configureRoomUsingOptions:nil];
}
Send nil
to accept default options or you can send IQ with syntax as below to your server:
http://jabber.org/protocol/muc#roomconfig
My Chat Room
.
.
.
or objective c code:
NSError *error = nil;
NSXMLElement *query = [[NSXMLElement alloc] initWithXMLString:@" "
error:&error];
NSXMLElement *x = [NSXMLElement elementWithName:@"x"
xmlns:@"jabber:x:data"];
[x addAttributeWithName:@"type" stringValue:@"submit"];
NSXMLElement *field1 = [NSXMLElement elementWithName:@"field"];
[field1 addAttributeWithName:@"var" stringValue:@"FORM_TYPE"];
NSXMLElement *value1 = [NSXMLElement elementWithName:@"value"
stringValue:@"http://jabber.org/protocol/muc#roomconfig"];
[field1 addChild:value1];
NSXMLElement *field2 = [NSXMLElement elementWithName:@"field"];
[field2 addAttributeWithName:@"var" stringValue:@"muc#roomconfig_roomname"];
NSXMLElement *value2 = [NSXMLElement elementWithName:@"value"
stringValue:@"My Chat Room"];
[field2 addChild:value2];
//Add other fields you need, just like field1 and field2
[x addChild:field1];
[x addChild:field2];
[query addChild:x];
NSXMLElement *roomOptions = [NSXMLElement elementWithName:@"iq"];
[roomOptions addAttributeWithName:@"type" stringValue:@"set"];
[roomOptions addAttributeWithName:@"id" stringValue:[xmppStream generateUUID];
[roomOptions addAttributeWithName:@"to" stringValue:@"chat_room@conference.jabber.server.com"];
[roomOptions addChild:query];
[sender configureRoomUsingOptions:roomOptions];
and list of all possible Configuration Form fields is here