XMPPFramework - How to use Presence Priority? - ios

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.

Related

Xmpp MultiUserChat (MUC) Group Does not remain stable

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>

How to create a new group for chat using xmppframework?

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

MUC How-to with XMPPFramework

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()

XMPPFramework - Presence not changing

I'm trying to set the users presence to away (or anything at the moment). I'm using the following code but it doesn't seem to do anything.
XMPPPresence *presence = [XMPPPresence presence];
NSXMLElement *show = [NSXMLElement elementWithName:#"show" stringValue:#"away"];
NSXMLElement *status = [NSXMLElement elementWithName:#"status" stringValue:#"away"];
[presence addChild:show];
[presence addChild:status];
[[self xmppStream] sendElement:presence];
I've used iChat to make sure all the presence subscriptions on my Ejabberd server are correct and working. This is driving me crazy, am I missing something?
I figured it out, turns out the presence wasn't being sent out by the app as I'd missed this out:
- (MMApplication *)appDelegate {
return (MMApplication *)[[UIApplication sharedApplication] delegate];
}
- (XMPPStream *)xmppStream {
return [[self appDelegate] xmppStream];
}
Works perfectly now

XMPPFramework - Presence not received in iOS

I am trying to send message from simulator to device. On simulator there is one user while on device there is another user. But presence is not being received at any end.
I am using XMPPFramework for ios.
Here is the code I am using to send presence
NSXMLElement *presence = [NSXMLElement elementWithName:#"presence"];
[presence addAttributeWithName:#"to" stringValue:[NSString stringWithFormat:#"user1#server.com"]];
[presence addAttributeWithName:#"type" stringValue:#"available"];
[[self xmppStream] sendElement:presence];
But at the end where user1#server.com is logged in following method is NOT being invoked
- (void)xmppStream:(XMPPStream *)sender didReceivePresence:(XMPPPresence *)presence
{
NSLog(#"---------- xmppStream:didReceivePresence: ----------");
}
What might be the issue?
The reason presence was not being sent is that code was incorrect. I used following code to send presence
XMPPPresence *presence = [XMPPPresence presence];
[[self xmppStream] sendElement:presence];
after that it showed user online on openfire server and message was correctly being sent to other users.

Resources