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.
Related
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. Here my problem is, I want to send chat notifications .I tried the fallowing way but not getting correctly.
- (void)sendMessage:(id)sender
{
NSString *messageStr =messageField.text;
if([messageStr length] > 0)
{
NSXMLElement *body = [NSXMLElement elementWithName:#"body"];
NSXMLElement *chatStatus=[NSXMLElement elementWithName:#"composing" xmlns:xmlns_chatstates];
[body setStringValue:messageStr];
NSXMLElement *message = [NSXMLElement elementWithName:#"message"];
[message addAttributeWithName:#"type" stringValue:#"chat"];
[message addAttributeWithName:#"to" stringValue:jidString];
[message addChild:chatStatus];
[message addChild:body];
[[self xmppStream] sendElement:message];
}
}
I am using above method for sending a message.But it always shows typing notification even i am not typing .can any one help to me.
thanks in advance
According to XEP-0085: Chat State Notifications, you should send another notification saying you've stopped typing, for example <active/> or <paused/>.
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 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];
}
I want to send automatically an email to sender (hard coded email id) from iphone on particular timeInterval. How i send an email automatically without using UI of MFMailComposeViewController class?
Thanks.
There is nothing in the built in frameworks that will allow it. You could of course use the unix sockets api to conect to a mail server and send a message using SMTP, however there are some third party ibraries to make your life easier.
I have used the Pantomine messaging library. It works well on iOS and can be found at http://www.collaboration-world.com/pantomime/
Once you have the library in your project you can do something like this:
CWMessage *message = [[CWMessage alloc] init];
CWInternetAddress *from = [[CWInternetAddress alloc] initWithString:#"from#gmail.com"];
[message setFrom:from];
[from release];
CWInternetAddress *to = [[CWInternetAddress alloc] initWithString:#"to#somewhere.com"];
[address setType:PantomimeToRecipient];
[message addRecipient:to];
[to release];
[message setSubject:#"This is my subject"];
[message setContentType: #"text/plain"];
[message setContentTransferEncoding: PantomimeEncodingNone];
[message setCharset: #"us-ascii"];
[message setContent: [#"This is my message" dataUsingEncoding: NSASCIIStringEncoding]];
smtp = [[CWSMTP alloc] initWithName:#"smtp.gmail.com" port:465];
[smtp setDelegate: self];
[smtp setMessage: message];
[message release];
ssl = YES;
mechanism = #"PLAIN";
[smtp connectInBackgroundAndNotify];