Hi I'm developing a chat application in IOS and completed one to one chat, after searching a lot about groupChat, unable to got how to create a normal group in xmppframework.
What I already tried here is a link
iOS XMPP group chat implementation
Accepting chatroom invitation
How to create MultiUserChatRoom using XMPPFramework in iPhone
XMPPFramework - How to Create a MultiUserChat Rooms?
But didnt get any positive response from these above links,
In coding I tried
XMPPRoomCoreDataStorage *rosterstorage = [[XMPPRoomCoreDataStorage alloc] init];
XMPPRoom *xmppRoom = [[XMPPRoom alloc] initWithRoomStorage:rosterstorage jid:[XMPPJID jidWithString:#"test#conference.domainName.com/rohit"] dispatchQueue:dispatch_get_main_queue()];
[xmppRoom configureRoomUsingOptions:nil];
[xmppRoom activate:[self xmppStream]];
[xmppRoom addDelegate:self
delegateQueue:dispatch_get_main_queue()];
[xmppRoom inviteUser:[XMPPJID jidWithString:#"abc#domainName.com"] withMessage:#"Hi join room"];
Also this
- (void)createOrEnterRoom:(NSString *)roomName
{
//here we enter a room, or if the room does not yet exist, this method creates it
//per XMPP documentation: "If the room does not yet exist, the service SHOULD create the room"
//this method accepts an argument which is what you would baptize the room you wish created
XMPPPresence *presence = [XMPPPresence presence];
NSString *room = [roomName stringByAppendingString:#"#conference.domain.com"];
[presence addAttributeWithName:#"to" stringValue:room];
NSXMLElement *x = [NSXMLElement elementWithName:#"x" xmlns:#"http://jabber.org/protocol/muc"];
NSXMLElement *history = [NSXMLElement elementWithName:#"history"];
[history addAttributeWithName:#"maxstanzas" stringValue:#"50"];
[x addChild:history];
[presence addChild:x];
[[self xmppStream] sendElement:presence];
}
Last one is
-(void)createGroup
{
#try {
NSString *username=#"user_3";//[self.userDefault valueForKey:#"userid"];
NSXMLElement *presenceElement=[NSXMLElement elementWithName:#"presence"];
[presenceElement addAttributeWithName:#"type" stringValue:#"groupchat"];
[presenceElement addAttributeWithName:#"from" stringValue:[NSString stringWithFormat:#"%#%#",username,HostName]];
[presenceElement addAttributeWithName:#"to" stringValue:[NSString stringWithFormat:#"testGroup#conference.%#/%#",HostName,username]];
NSXMLElement *xElement=[NSXMLElement elementWithName:#"x" xmlns:#"http://jabber.org/protocol/muc"];
NSXMLElement *historyElement=[NSXMLElement elementWithName:#"history"];
[xElement addChild:historyElement];
[presenceElement addChild:xElement];
[self.xmppStream sendElement:presenceElement];
}
#catch (NSException *exception) {
}
}
Anyone please show me a way to solve out this. Please also let me know if we need to configure something extra in ejjabered configuration.
Please find go through this i found best and detailed answer here .
Trouble creating xmpp muc room: Code 503 (service unavailable)
Infact group chat is not provided by XMPP, its a chat room that you have created with XMPPRoom,
or you can say conversation.
You cant send offline group messages with this.
I have implement Group chat in my http://www.catchbuddies.com/ project with the help of other custom server.
You can make and configue group chat with the help of some webservces for Groups.
You should check your muc settings of ejabberd server configuration.
make sure muc host is set correctly.
in my case, I changed host to {host, "pub.#HOST#"}, then I tried to join room "test#conference.#HOST#" always got service unavailable error, it took me a whole night to fix.
also, you can use imessage login to your jabber server with admin user, and create chat room before you run ios client.
Change ejabberd log level to debug may help a lot.
For group creation change setting for muc_room. Also prefer this url will suggest the way for setting https://serverfault.com/questions/185770/configuring-ejabberd-for-multi-user-chat
Related
I created an Xmpp Chat App where I have implemented the one-to-one and group chat.
The Chat itself is working fine.
The issue is in Group chat. I created a group with 2-3 members, again the chat is working fine, but when I kill the application and restart it, I'm not getting the group messsages from any of the groups I have created.
while I am connected to the XMPP Server and re-join any group then I get the messages.
My problem is that I have to join into groups again every time after I kill the app completly.
Please let me know How I can get the messages or join automatically in group when i open the application from killed state.
You need to send presence to XMPP server once your application launched or come out from background. so the XMPP server understand that respective group is ready to handle event.
Edit : you can send presence using following code.
- (void)goOnline {
NSXMLElement *presence = [NSXMLElement elementWithName:#"presence"];
NSXMLElement *show = [NSXMLElement elementWithName:#"show"
stringValue:#"dnd"];
NSXMLElement *status = [NSXMLElement elementWithName:#"status" stringValue:#"available"];
NSXMLElement *priority = [NSXMLElement elementWithName:#"priority" stringValue:#"24"];
[presence addChild:show];
[presence addChild:status];
[presence addChild:priority];
[_xmppStream sendElement:presence];
[self createOrJoinRoom];
}
- (void)createOrJoinRoom {
if ([appDelegate.xmppStream isConnected]) {
NSString *myJID = [[NSUserDefaults standardUserDefaults] stringForKey:#"XMPPUserId"];
NSXMLElement *presence = [NSXMLElement elementWithName:#"presence"];
[presence addAttributeWithName:#"from" stringValue:[[appDelegate.xmppStream myJID]full]];
[presence addAttributeWithName:#"to" stringValue:[NSString stringWithFormat:#"%##%#/%#", #"newone", GroupChatRoomName,myJID]];
NSXMLElement *xelement = [NSXMLElement elementWithName:#"x" xmlns:XMPPMUCNamespace];
[presence addChild:xelement];
[appDelegate.xmppStream sendElement:presence];
}
}
May this help you.
You have to join all your previous join/connected groups. Because in iOS if you kill your app then you left from your created or joined groups.
So every time in this section of the code
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
you have to join your group again.
Below is demo code for it :
XMPPRoomHybridStorage *xmppRoomStorage1 = [XMPPRoomHybridStorage sharedInstance];
xmppRoom = [[XMPPRoom alloc] initWithRoomStorage:xmppRoomStorage1 jid:RoomName];
[xmppRoom addDelegate:self delegateQueue:dispatch_get_main_queue()];
[xmppRoom activate:appDelegate.Obj_xmppManager.xmppStream];
NSXMLElement *history = [NSXMLElement elementWithName:#"history"];
[history addAttributeWithName:#"maxstanzas" stringValue:#"1"];
[xmppRoom joinRoomUsingNickname:self.xmppStream.myJID.user history:nil];
Adding to the Presence answer, I would also check more basic things -
Are the rooms (group chat) you create persistant?
or do you have to create the room again every time you connect?
(notice the difference between 'openning' and 'creating').
On some servers, rooms are temporary by default - you can check this by connecting with 2 seperate clients, send some messages, disconnect only one of them, and reconnect - if you do see the messages that were sent in your reconnected client - this might be your issue, can you show the parameters you pass to the server when you create the room?.
Is the server you are using configured to send history messages by default, and if so how many, again, server implementations may vary, could you share some information on the server you are using (openfire, ejabbered, prosody)? or a snippet from you configuration file?
Is it possible you are getting the messages, but not showing them correctly, maybe not refreshing the screen\view when first entering a room? any log messages?
I am also facing this issue since a week and looking for solution and after a lot of search on google and stack overflow i got a clue which solve this issue.
In my case group created successfully and chat is working good with members and members can send me chat too but when any member of group logout or kill the app and then login again he is unable to send message is this group and group says in response Only occupants are allowed to send messages to the conference.
In my case when user tap on group to go into group and start chat i call this method to join group.
NSString *roomJID = [NSString stringWithFormat:#"%##conference.yourHostName", roomJid];
XMPPJID *jid = [XMPPJID jidWithString:roomJID];
_xmppRoom = [[XMPPRoom alloc] initWithRoomStorage:xmppRoomCoreDataStorage jid:jid dispatchQueue:dispatch_get_main_queue()];
[_xmppRoom activate:stream];
[_xmppRoom addDelegate:self delegateQueue:dispatch_get_main_queue()];
[_xmppRoom joinRoomUsingNickname:stream.myJID.bare history:nil];
Hope this will work for you too
By default a MUCRoom will send some history to newly joined user, the number is determined by config, under mod_muc: history_size:.
Or you need to explicitly request for some amount of history while sending the Presence, doc:
<presence
from='hag66#shakespeare.lit/pda'
id='n13mt3l'
to='coven#chat.shakespeare.lit/thirdwitch'>
<x xmlns='http://jabber.org/protocol/muc'>
<history maxstanzas='20'/>
</x>
</presence>
I am able to send messages to users which means i have a working and authenticated xmppStream.
But i am unable to send and receive acknowledgement from server. I want to know which message was received successfully by the server. I googled and found that XEP-0198 should be implemented for this. I am using ejabberd as XMPP server and it supports XEP-0198.
I tried that but i don't know if i am doing it right or not.
First of all i included the header file and added XMPPStreamManagementDelegate.
#import "XMPPStreamManagement.h"
#interface AppDelegate : UIResponder <UIApplicationDelegate,XMPPStreamManagementDelegate>
In the implementation file, here's how i have defined the stream.
XMPPStream *xmppS = [[XMPPStream alloc] init];
[xmppS addDelegate:self delegateQueue:dispatch_get_main_queue()];
XMPPStreamManagement *xsm = [[XMPPStreamManagement alloc] init];
[xsm addDelegate:self delegateQueue:dispatch_get_main_queue()];
[xsm activate:xmppS];
After that i connect with the server. After the connection is successful, i send an enable stanza.
NSXMLElement *enable = [NSXMLElement elementWithName:#"enable" xmlns:#"urn:xmpp:sm:3"];
[xsm.xmppStream sendElement:enable];
Then i send a message
NSXMLElement *a = [NSXMLElement elementWithName:#"request" xmlns:#"urn:xmpp:receipts"];
XMPPElement *e = [[XMPPElement alloc] initWithName:#"message"];
[e addAttributeWithName:#"id" stringValue:#"123456"];
[e addAttributeWithName:#"type" stringValue:#"chat"];
[e addAttributeWithName:#"to" stringValue:#"testuser#myxmppserver.com"];
[e addAttributeWithName:#"from" stringValue:#"testuser2#myxmppserver.com"];
[e addChild:a];
[xsm.xmppStream sendElement:e];
Test User receives the message and Test User 2 gets the received stanza.
<received xmlns="urn:xmpp:receipts" id="123456"/>
My problem is if i send the following stanza, i receive no message.
NSXMLElement *r = [NSXMLElement elementWithName:#"r"];
[xsm.xmppStream sendElement:r];
I have implemented the following function
-(void)xmppStreamManagementDidRequestAck:(XMPPStreamManagement *)sender
{
NSLog(#"ACK");
}
But still nothing gets printed.
Please help. Also, how can i know when the server has received the sent message.
Let me know if anyone wants to know any other part of code from my side.
You can use the functions in xmppStreamManagement for sending the request and get received id:
[xmppStreamManagement requestAck];
and
- (void)xmppStreamManagement:(XMPPStreamManagement *)sender wasEnabled:(NSXMLElement *)enabled
- (void)xmppStreamManagement:(XMPPStreamManagement *)sender didReceiveAckForStanzaIds:(NSArray *)stanzaIds
make sure the stream management is enabled by:
[self.xmppStreamManagement enableStreamManagementWithResumption:YES maxTimeout:0];
I'm working on an iOS app with XMPPFramework and Openfire Server. I work with a book to implement it, but there are some parts I don't understand because the book makes references to Google Talk and I can't figure out what to do in those methods:
The first one is about presence, here is the code that is implemented in the book:
-(void)goOnline
{
XMPPPresence *presence = [XMPPPresence presence];
NSString *domain = [self.xmppStream.myJID domain];
// Google set their presence priority to 24, so we do the same to be compatible.
if ([domain isEqualToString:#"gmail.com"] || [domain isEqualToString:#"gtalk.com"])
{
NSXMLElement *priority = [NSXMLElement elementWithName:#"priority" stringValue:#"24"];
[presence addChild:priority];
}
[[self xmppStream] sendElement:presence];
[self.rootViewController updateStatus:#"online"];
}
As I'm working on localhost with my own server name, I don't know exactly what to do with presence or if Openfire have a value for the presence priority.
I am developing an iOS XMPP chat app that utilizes Robbie Hanson's XMPPFramework.
The most important functionalities have been implemented - sending and receiving messages. Basically, I've built a basic functional chat app already, with a little eye candy of course.
Now, the problem I have is regarding MUC. The codes I saw from other websites show that there is a method initWithRoomName in XMPPRoom. However, this method is absent in the git repo I cloned. So, what is the alternative to this? Or, if there is none, how do I go about creating rooms using XMPPFramework?
Thanks.
Below is how I got my own problem solved. Note that this solution does not involve XMPPRoom at all. First, I created a method that, depending on the situation, either creates or enters a room. (Per XMPP documentation, the XML request for creating is the same is the same as the one you would send to enter a room; that is, if the room has does not exist yet when you enter it, the service will create it for you.)
Here we go. This is the method that creates/enters a room. What this method does is send a presence to the room which you intend to create/enter. If you are the first to enter a room and the room has not been created yet, you automatically become its owner and moderator.
- (void)createOrEnterRoom:(NSString *)roomName
{
//here we enter a room, or if the room does not yet exist, this method creates it
//per XMPP documentation: "If the room does not yet exist, the service SHOULD create the room"
//this method accepts an argument which is what you would baptize the room you wish created
NSXMLElement *presence = [NSXMLElement elementWithName:#"presence"];
NSString *room = [roomName stringByAppendingString:#"#conference.jabber.com/iMac"];
[presence addAttributeWithName:#"to" stringValue:room];
NSXMLElement *x = [NSXMLElement elementWithName:#"x" xmlns:#"http://jabber.org/protocol/muc"];
NSXMLElement *history = [NSXMLElement elementWithName:#"history"];
[history addAttributeWithName:#"maxstanzas" stringValue:#"50"];
[x addChild:history];
[presence addChild:x];
[[self xmppStream] sendElement:presence];
}
Next, in the AppDelegate where XMPPStream methods are declared we filter the XML response we receive in the didReceivePresence method by checking the status code sent by the server. If the status code is 201, bingo! The room creation went just fine. Status codes other than 201 mean different things, but let's focus on 201 for our purpose.
- (void)xmppStream:(XMPPStream *)sender didReceivePresence:(XMPPPresence *)presence
{
NSXMLElement *x = [presence elementForName:#"x" xmlns:#"http://jabber.org/protocol/muc#user"];
for (NSXMLElement *status in [x elementsForName:#"status"])
{
switch ([status attributeIntValueForName:#"code"])
{
case 201: [self notifyRoomCreationOk:room];
}
}
}
Then, we tell the server that what we are creating a room of the type "instant," which means that we will send an IQ element telling it room defaults. notifyRoomCreationOk is a delegate method called in a different view when the room creation succeeds, after all I have to record the room in a text file to make it persistent so that the next time I open the app the room I created before will be visible. In my notifyRoomCreationOk method, I have sendDefaultRoomConfig which, basically, describes what is stated in the first sentence of this paragraph.
-(void)sendDefaultRoomConfig:(NSString *)room
{
NSXMLElement *x = [NSXMLElement elementWithName:#"x" xmlns:#"jabber:x:data"];
[x addAttributeWithName:#"type" stringValue:#"submit"];
NSXMLElement *query = [NSXMLElement elementWithName:#"query" xmlns:#"http://jabber.org/protocol/muc#owner"];
[query addChild:x];
XMPPIQ *iq = [XMPPIQ iq];
[iq addAttributeWithName:#"id" stringValue:[NSString stringWithFormat:#"inroom-cr%#", room]];
[iq addAttributeWithName:#"to" stringValue:room];
[iq addAttributeWithName:#"type" stringValue:#"set"];
[iq addChild:query];
[[self xmppStream ] sendElement:iq];
}
Make sure that you have XMPPStream enabled on the views that call the above methods, otherwise, these won't work. That's all there is to it. Have fun XMPP-ing!
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
Your post is old, however now I would do it like this:
- (void)createRoomWithJid:(XMPPJID*)roomJID
{
XMPPRoom *xmppRoom = [[XMPPRoom alloc] initWithRoomStorage:self.xmppRoomHybridStorage
jid:roomJID
dispatchQueue:dispatch_get_main_queue()];
[xmppRoom addDelegate:self delegateQueue:dispatch_get_main_queue()];
[xmppRoom activate:self.xmppStream];
[xmppRoom joinRoomUsingNickname:self.xmppStream.myJID.user
history:nil
password:nil];
}
Create chat room by given below code using XMPPFRAMWORK.
let roomStorage: XMPPRoomMemoryStorage = XMPPRoomMemoryStorage()
/**
* Remember to add 'conference' in your JID like this:
* e.g. uniqueRoomJID#conference.yourserverdomain
*/
let roomJID: XMPPJID = XMPPJID.jidWithString("chatRoom_name#conference.myhostname")
let xmppRoom: XMPPRoom = XMPPRoom(roomStorage: roomStorage,
jid: roomJID,
dispatchQueue: dispatch_get_main_queue())
xmppRoom.activate(SKxmpp.manager().xmppStream)
xmppRoom.addDelegate(self, delegateQueue: dispatch_get_main_queue())
xmppRoom.joinRoomUsingNickname(SKxmpp.manager().xmppStream.myJID.user, history: nil, password: nil)
xmppRoom.fetchConfigurationForm()
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");
}
}