I have created a MembersOnly, Persistant Room. In which I have invited multiple occupants.
Now I want to fetch detail of room for the user which was invited by creator.
I tried this code :
XMPP requirement :
<iq from='hag66#shakespeare.lit/pda'
id='ik3vs715'
to='coven#chat.shakespeare.lit'
type='get'>
<query xmlns='http://jabber.org/protocol/disco#info'/>
</iq>
iOS code to call the from iOS
NSXMLElement *query = [NSXMLElement elementWithName:#"query" xmlns:#"http://jabber.org/protocol/disco#info"];//
NSString *iqID = [[appDelegate xmppStream] generateUUID];
XMPPJID *jID = self.room.roomJID;
XMPPIQ *element = [XMPPIQ iqWithType:#"get" to:jID elementID:iqID child:query];
[element addAttributeWithName:#"from" stringValue:[[[appDelegate xmppStream] myJID] full]];
[[appDelegate xmppStream] fetchInformationForGivenIQ:element];
This should provide me this kinda result :
<iq from='coven#chat.shakespeare.lit'
id='ik3vs715'
to='hag66#shakespeare.lit/pda'
type='result'>
<query xmlns='http://jabber.org/protocol/disco#info'>
<identity
category='conference'
name='A Dark Cave'
type='text'/>
<feature var='http://jabber.org/protocol/muc'/>
<feature var='muc_passwordprotected'/>
<feature var='muc_hidden'/>
<feature var='muc_temporary'/>
<feature var='muc_open'/>
<feature var='muc_unmoderated'/>
<feature var='muc_nonanonymous'/>
</query>
</iq>
But I am getting this result :
<iq xmlns="jabber:client" type="result" id="some ID" from="Group-ID" to="My Full JabberID">
<query xmlns="http://jabber.org/protocol/disco#info">
<feature var="http://jabber.org/protocol/disco#info">
</feature>
</query>
</iq>
Can any one help me what I am doing wrong.
THanks in advance.
If you want to get the room info , you can call the mothod on XMPPRoom
- (void)fetchConfigurationForm;
Then , get the room info in the room's Delegate method
- (void)xmppRoom:(XMPPRoom *)sender didFetchConfigurationForm:(NSXMLElement *)configForm;
Related
I am trying to fetch the list of available chat groups in my Ejabbered server with the help of XMPPFramework. Following is my code to fetch the list of Chat Group.
- (void) getChatGroupList{
XMPPJID *servrJID = [XMPPJID jidWithString:#"conference.Server"];
XMPPIQ *iq = [XMPPIQ iqWithType:#"get" to:servrJID];
[iq addAttributeWithName:#"from" stringValue:[[self xmppStream] myJID].full];
NSXMLElement *query = [NSXMLElement elementWithName:#"query"];
[query addAttributeWithName:#"xmlns" stringValue:#"http://jabber.org/protocol/disco#items"];
[iq addChild:query];
[[self xmppStream] sendElement:iq];
}
In response I am getting following XML inside didReceiveIQ
<presence xmlns="jabber:client" from="username#Server/38489493512952747921478847202003609" to="username# Server/38489493512952747921478847202003609"><priority>24</priority><x xmlns="vcard-temp:x:update"><photo/></x><c xmlns="http://jabber.org/protocol/caps" hash="sha-1" node="https://github.com/robbiehanson/XMPPFramework" ver="VyOFcFX6+YNmKssVXSBKGFP0BS4="/></presence>
Exact name of the group I can't see in the response. Can anyone help what is missing here or How can I get list of Group name and list of users inside each group?
Have you figure what happened?
From what I see, your request looks OK, but the response should be for other request.
And not sure what version XMPPFramework you are using, in the latest, there is a XMPPMUC class in XEP-0045. You can call discoverRoomsForServiceNamed to do the same stuff. Just make sure to implement XMPPMUCDelegate when you use it.
I am trying to implement XEP-0055 which is supported by ejabbed as shown here in supported xeps
This is my request:
XMPPIQ *iq = [[XMPPIQ alloc] init];
[iq addAttributeWithName:#"type" stringValue:#"get"];
[iq addAttributeWithName:#"from" stringValue:#"testuser1#company.com"];
[iq addAttributeWithName:#"to" stringValue:#"company.com"];
[iq addAttributeWithName:#"id" stringValue:#"search1"];
XMPPElement *query = [XMPPElement elementWithName:#"query"];
[query setXmlns:#"jabber:iq:search"];
[iq addChild:query];
[self.xmppStream sendElement:iq];
I am getting this response:
<iq xmlns="jabber:client" from="company.com" to="testuser1#company.com/2834146151141475281662718" type="error" id="search1">
<query xmlns="jabber:iq:search"/>
<error code="501" type="cancel">
<feature-not-implemented xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/>
</error>
</iq>
Why am I receiving feature-not-implemented? Link to official XEP description.
In ejabberd, the search functionality is delegated to a subdomain, by default using the vjud prefix. Try sending the search request to vjud.company.com instead.
All one-one chat is send with Message Type as Chat.
Thus the Message Archiving technique (shown below) worked fine for me to save/retrieve chat history.
// Setup message archiving
xmppMessageArchivingStorage = [XMPPMessageArchivingCoreDataStorage sharedInstance];
xmppMessageArchiving = [[XMPPMessageArchiving alloc] initWithMessageArchivingStorage:xmppMessageArchivingStorage];
[xmppMessageArchiving setClientSideMessageArchivingOnly:YES];
// Activate xmpp modules
[xmppMessageArchiving activate:xmppStream];
// Add delegate
[xmppMessageArchiving addDelegate:self delegateQueue:dispatch_get_main_queue()];
However for Group Chat, the message type sent is "groupchat"
This will not be archived by the XMPPMessageArchivingCoreDataStorage
Can someone please guide me as to how I can achieve the Message Archiving for Group Chat Message.
This is the Series of Stanza that you will need to send to get Archived Messages. For more detail you can checkout http://xmpp.org/extensions/xep-0136.html
REQ
<iq type='get' id='mrug_sender#staging.openfire.com'>
<list xmlns='urn:xmpp:archive'
with='mrug_target_155#staging.openfire.com'>
<set xmlns='http://jabber.org/protocol/rsm'>
<max>6900</max>
</set>
</list>
</iq>
RES
<iq type="result" id="mrug_sender#staging.openfire.com" to="mrug_sender#staging.openfire.com/Psi">
<list xmlns="urn:xmpp:archive">
<chat with="mrug_target_155#staging.openfire.com" start="2014-06-07T06:52:26.041Z"/>
<chat with="mrug_target_155#staging.openfire.com" start="2014-06-07T07:06:53.372Z"/>
<set xmlns="http://jabber.org/protocol/rsm">
<first index="0">866</first>
<last>867</last>
<count>2</count>
</set>
</list>
</iq>
REQ
<iq type='get' id='mrug_sender#staging.openfire.com'>
<retrieve xmlns='urn:xmpp:archive' with='mrug_target_155#staging.openfire.com' start='2014-06-07T06:52:26.041Z'>
<set xmlns='http://jabber.org/protocol/rsm'>
<max>8000</max>
</set>
</retrieve>
</iq>
RES
<iq type="result" id="mrug_sender#staging.openfire.com" to="mrug_sender#staging.openfire.com/Psi">
<chat xmlns="urn:xmpp:archive" with="mrug_target_155#staging.openfire.com" start="2014-06-07T06:52:26.041Z">
<from secs="0" jid="mrug_target_155#staging.openfire.com">
<body>Wow !! This is Archived Message</body>
</from>
<set xmlns="http://jabber.org/protocol/rsm">
<first index="0">0</first>
<last>0</last>
<count>1</count>
</set>
</chat>
</iq>
To Fetch List of all Conversations
<iq type='get' id='mrug_sender#staging.openfire.com'>
<list xmlns='urn:xmpp:archive'>
<set xmlns='http://jabber.org/protocol/rsm'>
<max>6900</max>
</set>
</list>
</iq>
You can easily get archive messages from xmpp core database. Use Below code.
XMPPMessageArchivingCoreDataStorage *_xmppMsgStorage = [XMPPMessageArchivingCoreDataStorage sharedInstance];
NSManagedObjectContext *moc = [_xmppMsgStorage mainThreadManagedObjectContext];
NSEntityDescription *entityDescription = [NSEntityDescription entityForName:#"XMPPMessageArchiving_Message_CoreDataObject"
inManagedObjectContext:moc];
NSFetchRequest *request = [[NSFetchRequest alloc]init];
[request setEntity:entityDescription];
//[request setFetchLimit:20];
NSError *error;
NSString *predicateFrmt = #"bareJidStr == %#";
NSPredicate *predicate = [NSPredicate predicateWithFormat:predicateFrmt, [NSString stringWithFormat:#"%#%#",GroupName,GROUP_CHAT_DOMAIN]];
request.predicate = predicate;
NSArray *messages = [moc executeFetchRequest:request error:&error];
i have a lot of search regarding file transfer in IOS. I am using XEP-0065 and XEP-0096 for FileTransfer . Code which i am using :
- (void)sendToOtherDevice:(NSData *)fileData receiverJid:(NSString *)receiverJid
{
NSString *s = [NSString stringWithFormat:#"%#/Smack",receiverJid];
XMPPJID *jid = [XMPPJID jidWithString:s];
// XMPPSIFileTransfer * sifiletransfer = [[XMPPSIFileTransfer alloc] initiateFileTransferTo:jid withData:fileData];
XMPPSIFileTransfer *sifiletransfer = [[XMPPSIFileTransfer alloc] init];
[sifiletransfer initiateFileTransferTo:jid withData:fileData];
//XMPPJID *jid = [XMPPJID jidWithString:receiverJid];
NSString *jabbarID = [[[[self appDelegate] xmppStream] myJID] bare];
XMPPJID *senderjid = [XMPPJID jidWithString:jabbarID];
//[TURNSocket setProxyCandidates:[NSArray arrayWithObjects:s, nil]];
// [TURNSocket setProxyCandidates:[NSArray arrayWithObjects:s,jabbarID, nil]];
[TURNSocket setProxyCandidates:[NSArray arrayWithObjects:jid.domain,senderjid.domain, nil]];
// [TURNSocket setProxyCandidates:[NSArray arrayWithObjects:jid.domain, nil]];
//[TURNSocket setProxyCandidates:[NSArray arrayWithObjects:#"111.11.111.111", nil]];
TURNSocket *socket1 = [[TURNSocket alloc] initWithStream:[self xmppStream] toJID:jid];
// [turnSockets addObject:turnSocket];
[socket1 startWithDelegate:self delegateQueue:dispatch_get_main_queue()];
}
-(void)turnSocket:(TURNSocket *)sender didSucceed:(GCDAsyncSocket *)socket
{
[socket writeData:photoData withTimeout:60.0f tag:0];
[socket disconnectAfterWriting];
}
- (void)turnSocketDidFail:(TURNSocket *)sender
{
NSLog(#"Couldn't set up bytestream for file transfer!");
}
and i found following XML stanzas :
2013-11-22 14:23:08:990 iPhoneXMPP[1434:6417] SEND: <iq type="get" to="lava1" id="A5D91010-C182-4BCB-A989-5DFF2C0B6AE8"><query xmlns="http://jabber.org/protocol/disco#items"/></iq>
2013-11-22 14:23:09:290 iPhoneXMPP[1434:6a07] RECV: <iq xmlns="jabber:client" type="error" id="A5D91010-C182-4BCB-A989-5DFF2C0B6AE8" to="lava#example.com/368c5070" from="lava1"><query xmlns="http://jabber.org/protocol/disco#items"/><error code="404" type="cancel"><remote-server-not-found xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/></error></iq>
2013-11-22 14:23:09:291 iPhoneXMPP[1434:60b] iPhoneXMPPAppDelegate: xmppStream:didReceiveIQ:
2013-11-22 14:23:09:294 iPhoneXMPP[1434:6417] SEND: <iq type="get" to="example.com" id="7EB43464-63BC-4ADF-8B98-A1A15AB51DB3"><query xmlns="http://jabber.org/protocol/disco#items"/></iq>
2013-11-22 14:23:09:493 iPhoneXMPP[1434:400b] RECV: <iq xmlns="jabber:client" type="result" id="7EB43464-63BC-4ADF-8B98-A1A15AB51DB3" from="example.com" to="lava#example.com/368c5070"><query xmlns="http://jabber.org/protocol/disco#items"><item jid="search.example.com" name="User Search"/><item jid="conference.example.com" name="Public Chatrooms"/><item jid="proxy.example.com" name="Socks 5 Bytestreams Proxy"/><item jid="pubsub.example.com" name="Publish-Subscribe service"/></query></iq>
2013-11-22 14:23:09:494 iPhoneXMPP[1434:60b] iPhoneXMPPAppDelegate: xmppStream:didReceiveIQ:
2013-11-22 14:23:09:504 iPhoneXMPP[1434:6417] SEND: <iq type="get" to="proxy.example.com" id="0DFDF89F-29DE-4477-AF5E-B67387DD973C"><query xmlns="http://jabber.org/protocol/disco#info"/></iq>
2013-11-22 14:23:09:698 iPhoneXMPP[1434:400b] RECV: <iq xmlns="jabber:client" type="result" id="0DFDF89F-29DE-4477-AF5E-B67387DD973C" from="proxy.example.com" to="lava#example.com/368c5070"><query xmlns="http://jabber.org/protocol/disco#info"><identity category="proxy" name="SOCKS5 Bytestreams Service" type="bytestreams"/><feature var="http://jabber.org/protocol/bytestreams"/><feature var="http://jabber.org/protocol/disco#info"/></query></iq>
2013-11-22 14:23:09:699 iPhoneXMPP[1434:60b] iPhoneXMPPAppDelegate: xmppStream:didReceiveIQ:
2013-11-22 14:23:09:701 iPhoneXMPP[1434:6a07] SEND: <iq type="get" to="proxy.example.com" id="63C74776-93A4-4C97-8CFC-63C57494E4F6"><query xmlns="http://jabber.org/protocol/bytestreams"/></iq>
2013-11-22 14:23:09:903 iPhoneXMPP[1434:6417] RECV: <iq xmlns="jabber:client" type="result" id="63C74776-93A4-4C97-8CFC-63C57494E4F6" from="proxy.example.com" to="lava#example.com/368c5070"><query xmlns="http://jabber.org/protocol/bytestreams"><streamhost jid="proxy.example.com" host="10.128.63.123" port="7777"/></query></iq>
2013-11-22 14:23:09:904 iPhoneXMPP[1434:60b] iPhoneXMPPAppDelegate: xmppStream:didReceiveIQ:
2013-11-22 14:23:09:906 iPhoneXMPP[1434:6417] SEND: <iq type="set" to="lava1/Smack" id="BB87F255-51AF-49F1-B700-D009BFF8A057"><query xmlns="http://jabber.org/protocol/bytestreams" sid="BB87F255-51AF-49F1-B700-D009BFF8A057" mode="tcp"><streamhost xmlns="http://jabber.org/protocol/bytestreams" jid="proxy.example.com" host="10.128.63.123" port="7777"/></query></iq>
2013-11-22 14:23:10:210 iPhoneXMPP[1434:6a07] RECV: <iq xmlns="jabber:client" type="error" id="BB87F255-51AF-49F1-B700-D009BFF8A057" to="lava#example.com/368c5070" from="lava1/Smack"><query xmlns="http://jabber.org/protocol/bytestreams" sid="BB87F255-51AF-49F1-B700-D009BFF8A057" mode="tcp"><streamhost jid="proxy.example.com" host="10.128.63.123" port="7777"/></query><error code="404" type="cancel"><remote-server-not-found xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/></error></iq>
2013-11-22 14:23:10:212 iPhoneXMPP[1434:60b] iPhoneXMPPAppDelegate: xmppStream:didReceiveIQ:
2013-11-22 14:23:10.213 iPhoneXMPP[1434:60b] Couldn't set up bytestream for file transfer!
Please Let me know what i am doing wrong. How Can i use XEP-0096 for FileTransfer.
I am developing an application in that I want to update my avatar image. I am following XEP-0153 guidelines to update my avatar image and I constructed an NSXMLElement correspond to the following code in XEP-0153 and sent that element through XMPPStream.
<iq from='juliet#capulet.com'
type='set'
id='vc1'>
<vCard xmlns='vcard-temp'>
<PHOTO>
<TYPE>image/jpeg</TYPE>
<BINVAL>
Base64-encoded-avatar-file-here!
</BINVAL>
</PHOTO>
</vCard>
</iq>
The server responses the following error:
<iq xmlns="jabber:client" type="error" id="vc1" to="vvreddy50#gmail.com/83557F96">
<vCard xmlns="vcard-temp">
<photo>
<type>image/jpeg</type>
<binval>Base64-encoded-avatar-file-here</binval>
</photo>
</vCard>
<error code="500" type="wait">
<internal-server-error xmlns="urn:ietf:params:xml:ns:xmpp-stanzas">
</internal-server-error>
</error>
</iq>
Instead of <iq to='juliet#capulet.com' type='result' id='vc1'/>
Please can anyone post the code or the link related to update avatar image? Thanks in advance.
- (void)updateAvatar:(UIImage *)avatar
{
NSData *imageData = UIImagePNGRepresentation(avatar);
dispatch_queue_t queue = dispatch_queue_create("queue", DISPATCH_QUEUE_PRIORITY_DEFAULT);
dispatch_async(queue, ^{
XMPPvCardTempModule *vCardTempModule = [[XMPPHandler sharedInstance] xmppvCardTempModule];
XMPPvCardTemp *myVcardTemp = [vCardTempModule myvCardTemp];
[myVcardTemp setName:[NSString stringWithFormat:#"%#",name.text]];
[myVcardTemp setPhoto:imageData];
[vCardTempModule updateMyvCardTemp:myVcardTemp];
});
}
#import "XMPPvCardTemp.h"
- (void)updateAvatar:(UIImage *)avatar{
NSData *imageData1 = UIImageJPEGRepresentation(avatar,0.5);
NSXMLElement *vCardXML = [NSXMLElement elementWithName:#"vCard" xmlns:#"vcard-temp"];
NSXMLElement *photoXML = [NSXMLElement elementWithName:#"PHOTO"];
NSXMLElement *typeXML = [NSXMLElement elementWithName:#"TYPE"stringValue:#"image/jpeg"];
NSXMLElement *binvalXML = [NSXMLElement elementWithName:#"BINVAL" stringValue:[imageData1 base64Encoding]];
[photoXML addChild:typeXML];
[photoXML addChild:binvalXML];
[vCardXML addChild:photoXML];
XMPPvCardTemp *myvCardTemp = [[[self appDelegate] xmppvCardTempModule]myvCardTemp];
if (myvCardTemp) {
[myvCardTemp setPhoto:imageData1];
[[[self appDelegate] xmppvCardTempModule] updateMyvCardTemp
:myvCardTemp];
}
else{
XMPPvCardTemp *newvCardTemp = [XMPPvCardTemp vCardTempFromElement:vCardXML];
[[[self appDelegate] xmppvCardTempModule] updateMyvCardTemp:newvCardTemp];
}
}
From the XMPP Core RFC, <error type='wait'> means:
retry after waiting (the error is temporary)
so your code should wait a while and re-send the request.
(This is assuming that you are actually sending a base64-encoded JPEG image as the BINVAL of your vCard. The reply from the server doesn't correspond to the request you say you sent, so I'm assuming you've edited both. It would be better to include the exact request and reply in your question, but truncate the base64-encoded image to a few characters for concision.)