I am developing a XMPP based chat application for iOS. One of the features of the app is that i need to block some of the users from my rooster.Is there any method available to this in the XMPP framework ? If not, is there some work around to do this ?
Also can some one help me in sending images from one user to other using XMPP ?
There are a number of things you might want to consider:
Likely your user is subscribed to the contact's presence and vice-versa. He will unsubscribe from the contact's presence (so he will no longer receive presence notifications from him) by sending:
<presence to='contact#example.com' type='unsubscribe'/>
He will revoke subscription to his own presence from the contact by sending:
<presence to='contact#example.com' type='unsubscribed'/>
Finally you can remove the item from your roster.
<iq from='user#example.com/home' type='set' id='roster'>
<query xmlns='jabber:iq:roster'>
<item jid='contact#example.com' subscription='remove'/>
</query>
</iq>
In fact, if you send the stanza above, i.e. if you want to cancel both subscriptions, you do not need to send the presence stanzas, they will be handled by the servers.
Finally, you can now block further interaction with the user by means of the jabber:iq:privacy API. This is explained in detail here.
The general presence/roster management is explained in the same rfc, probably best here.
Please check this code to implement user blocking:
-(void)blockUser{
XMPPIQ *iq = [[XMPPIQ alloc]init];
NSString *from = [NSString stringWithFormat:#"from#mail.com/resources"];
[iq addAttributeWithName:#"from" stringValue: from];
[iq addAttributeWithName:#"type" stringValue:#"set"];
NSXMLElement *block =[NSXMLElement elementWithName:#"block" xmlns:#"urn:xmpp:blocking"];
NSXMLElement *item = [NSXMLElement elementWithName:#"item"];
[item addAttributeWithName:#"jid" stringValue:#"to#mail.com/resources"];
[block addChild:item];
[iq addChild:block];
[xmppStream sendElement:iq];
}
- (void)setupXMPPPrivacy
{
NSLog((#"%s [Line %d] "), __PRETTY_FUNCTION__, __LINE__);
//Init XMPPPrivacy List
//xmppPrivacy = [[XMPPPrivacy alloc] init];
xmppPrivacy = [[XMPPPrivacy alloc] initWithDispatchQueue:dispatch_get_main_queue()];
//Activate xmpp modules
[xmppPrivacy activate:[[self appDelegate] xmppStream]];
//Delegate XMPPPrivacy
[xmppPrivacy addDelegate:self delegateQueue:dispatch_get_main_queue()];
[xmppPrivacy retrieveListWithName :#"Block_List"];
}
-(void)privacyblock
{
[xmppPrivacy retrieveListWithName:#"Block_List"];
[xmppPrivacy setActiveListName:#"Block_List"];
NSXMLElement *privacyElement = [XMPPPrivacy privacyItemWithType:#"jid" value:xmpp_jid action:#"deny" order:1];
[XMPPPrivacy blockIQs:privacyElement];
[XMPPPrivacy blockMessages:privacyElement];
[XMPPPrivacy blockPresenceIn:privacyElement];
[XMPPPrivacy blockPresenceOut:privacyElement];
NSLog(#"-------> PRIVACY ELEMENT: %#", privacyElement);
[arrayPrivacy addObject:privacyElement];
[xmppPrivacy setListWithName:#"Block_List" items:arrayPrivacy];
}
Related
I am developing one group chat application in iPhone, in which I want to implement this feature: Admin can remove/kick any participant. And participant must get notification that an admin has removed him from this group.
I have tried below code but without success:
XMPPPresence *presence = [XMPPPresence presenceWithType:#"unavailable"];
[presence addAttributeWithName:#"from" stringValue:[[DatingUserDefaults sharedDefaults] getGroupName]];
[presence addAttributeWithName:#"to" stringValue:[[DatingUserDefaults sharedDefaults] getUsername]];
[xmppStream sendElement:presence];
I have searched on Google and got to know that I have to produce the below format in Objective-C:
<presence
from='harfleur#chat.shakespeare.lit/pistol'
to='pistol#shakespeare.lit/harfleur'
type='unavailable'>
<x xmlns='http://jabber.org/protocol/muc#user'>
<item affiliation='none' role='none'>
<actor nick='Fluellen'/>
<reason>Avaunt, you cullion!</reason>
</item>
<status code='307'/>
</x>
</presence>
Does anyone have any idea about how to do that?
This works for me.
<iq type="set" to="roomid" id="some random no"><query xmlns="http://jabber.org/protocol/muc#admin"><item affiliation="none" jid="jid you want to remove"></item></query></iq>
NSXMLElement *query = [NSXMLElement elementWithName:#"query" xmlns:#"http://jabber.org/protocol/muc#admin"];
NSXMLElement *item = [NSXMLElement elementWithName:#"item"];
[item addAttributeWithName:#"affiliation" stringValue:#"none"];
[item addAttributeWithName:#"jid" stringValue:"jid to remove"];
[query addChild:item]; XMPPIQ *RemoveUser = [[XMPPIQ alloc] initWithType:#"set" to:[XMPPJID jidWithString:roomid] elementID:#"some random id" child:query ];
[self.xmppStream sendElement:RemoveUser];
This work for me
[self.xmppRoom leaveRoom];
I am developing a chat application in iphone using XMPPFramework. Everything is working great but stuck at the point. I want to retrieve a list of all public rooms but there is no method found in XMPPFramework. So can someone help me out to solve this issue?
Here is the code to get list of all room
NSString* server = #"chat.shakespeare.lit"; //or whatever the server address for muc is
XMPPJID *servrJID = [XMPPJID jidWithString:server];
XMPPIQ *iq = [XMPPIQ iqWithType:#"get" to:servJID];
[iq addAttributeWithName:#"from" stringValue:[xmppStream myJID].full];
NSXMLElement *query = [NSXMLElement elementWithName:#"query"];
[query addAttributeWithName:#"xmlns" stringValue:#"http://jabber.org/protocol/disco#items"];
[iq addChild:query];
[xmppStream sendElement:iq];
If you have code to get the room of specific user please share it
I use this code to query server directly, but I'm not sure that is the best way.
XMPPIQ *iq = [[XMPPIQ alloc] initWithType:#"get"];
NSString* conferenceHost = [NSString stringWithFormat:#"conference.%#", _xmppStream.hostName];
[iq addAttributeWithName:#"from" stringValue:conferenceHost];
[iq addAttributeWithName:#"to" stringValue:_host];
DDXMLElement *query = [DDXMLElement elementWithName:#"query" xmlns:#"http://jabber.org/protocol/disco#items"];
[iq addChild:query];
[_xmppStream sendElement:iq];
Hope this help someone.
By the way, if you adopt this solution, then you have to do some parse in delegate method:
- (BOOL)xmppStream:(XMPPStream *)sender didReceiveIQ:(XMPPIQ *)iq {
}
I thing the best way is to parse method once the connection has started:
- (void)xmppStream:(XMPPStream *)sender didReceivePresence:(XMPPPresence *)presence {
/* parse */
}
Then you check
[[sender] from] domain]
if contains "conference." then you can think that sender is a room and finally you can add to NSMutableArray, for instance.
Also when a new room will be created, didReceivePresence will be called, so parser will add the new room.
So, you have:
NSMutableArray* rooms;
Your method will be:
-(NSMutableArray*)getRooms {
return _rooms;
}
I am developing chat application using xmpp client. I can send and receive message when I login with one account. My problem is when i login with two different account i cannot send message using First login account. For sending message i tried the fallowing code:
- (void)sendMessage:(id)sender
{
xmppStream=[[self appDelegate] xmppStream];
NSString *messageStr =messageField.text;
if([messageStr length] > 0)
{
NSXMLElement *body = [NSXMLElement elementWithName:#"body"];
[body setStringValue:messageStr];
NSXMLElement *message = [NSXMLElement elementWithName:#"message"];
[message addAttributeWithName:#"type" stringValue:#"chat"];
[message addAttributeWithName:#"to" stringValue:jidStr];
[message addChild:body];
NSLog(#"%#",message);
}
}
In this delegate method, i create stream object like fallowing
-(void)setUpStream
{
XMPPStream *xmppStream=[XMPPStream alloc] init]
}
when i second time login with another account then xmppStream object is associated with second account but not for First account.
so i can't send message using first account.can any one solve my problem plz and how to create two xmppStream objects for two accounts;
The easiest way to do this is to create to xmppStream objects in your AppDelegate.
Call one xmppStreamOne and xmppStreamTwo.
You could even create an NSMutableArray of xmppStreams if you intent to log into many different different servers.
When you retrieve the xmppStream from the AppDelegate make sure to grab the right one.
I receive messages from a Google Talk account, they are shown in the Table View in the Ios emulator, but when i send it, it is not shown in the Google Talk client (in another computer). This is the code:
-(IBAction)sendchat:(id)sender
{
General *general = [General sharedManager];//It is a singleton class used to store some values that need to be accesible in the whole application.
NSXMLElement *body = [NSXMLElement elementWithName:#"body"];
text=[mensaje text];
NSLog(#"Texto en el body: %#", text);
[body setStringValue:text];
NSArray *dest=[general.firstfrom componentsSeparatedByString:#"/"];//in firstfrom is stored the account from wich we receive the first message. This app cannot start a conversation itself, must only answer
NSLog(#"Destination trimmed: %#", [dest objectAtIndex:0]);//Here, the destination account shows correctly (without the /xxxx stuff, just name#gmail.com)
XMPPMessage *mens=[[XMPPMessage alloc]init];
[mens addAttributeWithName:#"body" stringValue:text];
[mens addAttributeWithName:#"sender" stringValue:general.userlogin];
NSLog(#"text vale: %#", text);
NSXMLElement *messagetosend = [NSXMLElement elementWithName:#"message"];
[messagetosend addAttributeWithName:#"type" stringValue:#"chat"];
[messagetosend addAttributeWithName:#"to" stringValue:[dest objectAtIndex:0]];
[messagetosend addChild:body];
NSLog(#"We are sending to: %#", [dest objectAtIndex:0]);
[self.xmppStream sendElement:messagetosend];
[self xmppStream:xmppStream didReceiveMessage:mens];//manage the sent message as it was received, to show it in the Table View
self.mensaje.text=#"";
}
As I say, messages are received perfectly, but I cannot send. Ive seen plenty of examples of how to send, and they are like my code. If i debug sender it is shown ok (namesender#gmail.com), and the "to" attribute is ok too (namereceiver#gmail.com). The xmppStrem is set correctly (as far as i know):
xmppStream = [[XMPPStream alloc] init];
[xmppStream addDelegate:self delegateQueue:dispatch_get_main_queue()];
In ViewDidLoad method.
Any help? Thank you.
---EDIT---
I forgot to say, both accounts know each others and in the Google Talk client, the presence is sent.
I found the answer. I had two classes receiving messages, because Class A must receive a message to trigger the pushing of the view of the class B (this app is unable to start a chat conversation by itself). So, i set two xmppStream, one for every class. I put an xmppStream in my General class, make both classes take that xmppStream, and it now sends messages.
I am developing a chat project using Openfire.
I have done with group chatting.
But confusion is in 1 to 1 chat.
I am using:
<message from='user2#server/user2' to='user1#server/user1' type='chat'>
<body>TEST< /body>
</message>
but it does not send it.
Thanks in advance.
Assuming that the spaces after the < characters shouldn't be there, it looks correct.
You can even do without the from attribute, since it'll be added by the server.
- (AppDelegate *)appDelegate
{
return (AppDelegate *)[[UIApplication sharedApplication] delegate];
}
- (XMPPStream *)xmppStream
{
return [[self appDelegate] xmppStream];
}
- (void)sendMessage:(id)sender
{
NSString *messageStr =messageField.text;
if([messageStr length] > 0)
{
NSXMLElement *body = [NSXMLElement elementWithName:#"body"];
[body setStringValue:messageStr];
NSXMLElement *message = [NSXMLElement elementWithName:#"message"];
[message addAttributeWithName:#"type" stringValue:#"chat"];
[message addAttributeWithName:#"to" stringValue:#"destination email address"];
[message addChild:body];
NSLog(#"%#",message);
[[self xmppStream] sendElement:message];
}
}
when you click on send button this method will be called and it shows log message as
<message type="chat" to="destination email address"><body>messageStr</body></message>
After fixing the syntax issues, removing the from address, and removing the doubtfully-correct resource from the to address, you're left with:
<message to='user1#server' type='chat'>
<body>TEST</body>
</message>
The resource on the to address is like the issue. Read XEP-0296 for how to deal with resources correctly when doing XMPP IM.