robbiehanson / XMPPFramework

An XMPP Framework in Objective-C for Mac and iOS
Other
5.91k stars 2.09k forks source link

Issue with retrieving the vCard for a user #503

Open daisoreanu opened 9 years ago

daisoreanu commented 9 years ago

I just started using the library, and working with XMPP, I also bough the book "Mastering The XMPP Framework", and there are a few thinks that I didn't quite managed to understand, and implicitly implement one of those things is:

http://stackoverflow.com/questions/28878849/how-to-create-update-retrieve-user-vcard-using-xmppframework-and-opefire-on-io

Also in order to update an existent vCard I need to upload the entire vCard or is it possible to only update the field in witch I am interested to change.

Thank you in advance, and I want to mention that I know that this is not an actual issue but more of a misunderstanding of myself.

ObjColumnist commented 9 years ago

XMPPvCardTempModule has the following delegate methods that get called if the sever updated or rejected you vCard:

vCards properties cannot be updated individual so if you make a change you have to update the whole vCard.

The vCard specifications states that you have to fetch your vCard before you are allowed to advertise it, so your vCard is cleared automatically upon authentication and automatically downloaded. This is why your vCard is nil upon authentication. If you have anyone else's vCard, they will still be cached locally upon authentication.

daisoreanu commented 9 years ago

I have tried to use this code in the xmppStreamDidAuthenticate: method but the NsLog prints out "Stored card: (null)"

dispatch_queue_t queue = dispatch_queue_create("queue", DISPATCH_QUEUE_PRIORITY_DEFAULT);

dispatch_async(queue, ^{

    XMPPvCardCoreDataStorage * xmppvCardStorage = [[XMPPvCardCoreDataStorage alloc] initWithInMemoryStore];

    XMPPvCardTempModule * xmppvCardTempModule = [[XMPPvCardTempModule alloc] initWithvCardStorage:xmppvCardStorage];

//also tried : //XMPPvCardTempModule * xmppvCardTempModule = [[XMPPvCardTempModule alloc] initWithvCardStorage:xmppvCardStorage dispatchQueue:dispatch_get_main_queue()];

    [xmppvCardTempModule  activate:[self xmppStream]];

    [xmppvCardTempModule fetchvCardTempForJID:[XMPPJID jidWithString:@"test11@administrator"] ignoreStorage:YES];

    XMPPvCardTemp *test = [xmppvCardStorage vCardTempForJID:[XMPPJID jidWithString:@"test11@administrator"] xmppStream:sender];

    NSLog(@"Stored card: %@",test.description);
});

Is it ok the way I am trying to implement the fetch request?

ObjColumnist commented 9 years ago

fetchvCardTempForJID is asynchronous, meaning that it sends the iq to the server requesting the vCard without blocking, so when you call vCardTempForJID the response hasn't yet been received.

In short, your vCard will never be available in xmppStreamDidAuthenticate: and you should implement xmppvCardTempModuleDidUpdateMyvCard: and xmppvCardTempModule:didReceivevCardTemp:forJID:

daisoreanu commented 9 years ago

Thank you very much, I will implement them and see if I get a good result

daisoreanu commented 9 years ago

So I have split the code as you suggested and also implemented the xmppvCardTempModule:didReceivevCardTemp:forJID: , so in my .h file I added the delegate XMPPvCardTempModuleDelegate, and in my .m in the xmppStreamDidAuthenticate: I have implemented the only the first part of the code, and removed the block, so now it looks like this:

and in the xmppvCardTempModule:didReceivevCardTemp:forJID: delegate method I simply added an NSLog to see if it works

}

The problem is that the delegate is not called. Any suggestions, or code corrections? Thank you very much for support until now ObjColumnist.

ObjColumnist commented 9 years ago

You still need to add yourself as a delegate to the vCard module using the addDelegate method.

daisoreanu commented 9 years ago

I just did that before I read the post and now it calls the method :D, I wanted to answer my question so I don't bother anymore

daisoreanu commented 9 years ago

But it still returns: Stored card: (null), when I NSLog. These is the code I used in the didReceivevCardTemp delegate method:

}

ObjColumnist commented 9 years ago

Im not sure but you shouldn't be doing this in xmppStreamDidAuthenticate:

xmppvCardStorage = [[XMPPvCardCoreDataStorage alloc] initWithInMemoryStore];
xmppvCardTempModule = [[XMPPvCardTempModule alloc] initWithvCardStorage:xmppvCardStorage];
[xmppvCardTempModule activate:[self xmppStream]];

1) It is too late as XMPPvCardTempModule also listens for xmppStreamDidAuthenticate: 2) You are creating this every time you authenticate, so you could end up with a lots of redundant modules in memory.

You should set up these modules at the same time as the XMPPStream and before you connect.

I have also never used memory storage as you could run out of RAM as vCards with images can quickly use up a lot of memory, but in theory it should work.

daisoreanu commented 9 years ago

Yes, But shouldn't I try to fetch the vCard after I am authenticated? So that I am sure that the login is successful(user name and password are correct) before I request for the vCard

ObjColumnist commented 9 years ago

The XMPPvCardTempModule automatically does this for you, assuming you have activated it on the XMPPStream before connecting.

daisoreanu commented 9 years ago

Could you please have a look on the Stackoverflow code and tell where should I implement it(I have constantly updates the post as a result of our discussion)? and how? because I just tried what you suggested and it doesn't seem to work(the delegate is no longer called), There should be something that I am skipping. Thank you in advance ObjColumnist and also thank you for all the support and explanations!

ObjColumnist commented 9 years ago

Something along the lines of:

- (void)signInButtonFunction{

    xmppStream = [[XMPPStream alloc] init];
    xmppStream.myJID = [XMPPJID jidWithString:@"test@administrator"];
    xmppStream.hostName = @"www.domainName.com";
    xmppStream.hostPort = 5222;
    [xmppStream addDelegate:self delegateQueue:dispatch_get_main_queue()];

    xmppvCardStorage = [XMPPvCardCoreDataStorage sharedInstance];
    xmppvCardTempModule = [[XMPPvCardTempModule alloc] initWithvCardStorage:xmppvCardStorage];
   [xmppvCardTempModule activate:xmppStream];
   [xmppvCardTempModule addDelegate:self delegateQueue:dispatch_get_main_queue()];

    reconnect = [[XMPPReconnect alloc] init];
    [reconnect activate:xmppStream];

    NSError *error = nil;
    if (![xmppStream connectWithTimeout:XMPPStreamTimeoutNone error:&error]) {
        NSLog(@"error: %@", error);
    }
    NSLog(@"error: %@", error);
}

Check out the iPhone sample project in the XMPPFramework, it doesn't do much but it allows you to authenticate and view your roster.

daisoreanu commented 9 years ago

Yes , I tried the same thing earlier and it doesn't enter the delegate method, it enters it only if I put my code in the xmppStreamDidAuthenticate delegate method...

I had a look over the sample project, some of my code is toked from there.

I just noticed you omitted to specify where to call: [xmppvCardTempModule fetchvCardTempForJID:[XMPPJID jidWithString:@"test11@administrator"] ignoreStorage:YES];

daisoreanu commented 9 years ago

also how can I log the vCardTempModule, from inside the xmppvCardTempModule:didReceivevCardTemp:forJID, because using the debug property returns the pointer address.

Used: NSLog(@"%@",vCardTempModule.myvCardTemp); and it printed nil description the same for vCardTemp the only one that returned data was the jid

daisoreanu commented 9 years ago

Would it help if I post a link to the project?

ObjColumnist commented 9 years ago

Sure, can't promise I will spot whats wrong though :smile:

daisoreanu commented 9 years ago

here you can find the source code, please let me know when you download it so that I can remove it -link have been removed-

ObjColumnist commented 9 years ago

Ive download the code, I will take a look when I get a moment.

daisoreanu commented 9 years ago

OK, Thank you ObjColumnist! I much appreciate your help :)

ObjColumnist commented 9 years ago

I would change signIn to:

- (void)signIn{

    //I have hardcoded the user and later the password for testing purpose
    xmppStream = [[XMPPStream alloc] init];
    xmppStream.myJID = [XMPPJID jidWithString:@"test@administrator"];
    xmppStream.hostName = @"www.b-0.info";
    xmppStream.hostPort = 5222;

    xmppvCardStorage = [XMPPvCardCoreDataStorage sharedInstance];
    xmppvCardTempModule = [[XMPPvCardTempModule alloc] initWithvCardStorage:xmppvCardStorage];
    xmppvCardAvatarModule = [[XMPPvCardAvatarModule alloc] initWithvCardTempModule:xmppvCardTempModule];

    reconnect = [[XMPPReconnect alloc] init];

    [xmppvCardAvatarModule activate:xmppStream];
    [xmppvCardTempModule activate:xmppStream];
    [reconnect activate:xmppStream];

    [xmppStream addDelegate:self delegateQueue:dispatch_get_main_queue()];
    [xmppvCardTempModule addDelegate:self delegateQueue:dispatch_get_main_queue()];
    [xmppvCardAvatarModule addDelegate:self delegateQueue:dispatch_get_main_queue()];

    NSError *error = nil;
    if (![xmppStream connectWithTimeout:XMPPStreamTimeoutNone error:&error]) {
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error" message:@"An error occurred while connecting to server!" delegate:self cancelButtonTitle:nil otherButtonTitles:@"OK", nil];
        [alert show];
    }
}

I don't think you need to fetch your vCard in xmppDidAuthenticate:, but (my mistake) I think it is xmppvCardTempModule that automatically fetches it, so I have added that to sign in.

I have changed xmppvCardTempModule:didReceivevCardTemp:forJID: as it is possible that the server is sending back an empty vCard.

- (void)xmppvCardTempModule:(XMPPvCardTempModule *)vCardTempModule
        didReceivevCardTemp:(XMPPvCardTemp *)vCardTemp
                     forJID:(XMPPJID *)jid{

    NSLog(@"Recieved card: %@",vCardTemp);
    XMPPvCardTemp *storedCard = [xmppvCardTempModule vCardTempForJID:jid shouldFetch:YES];
    NSLog(@"Stored card: %@",storedCard);
}
daisoreanu commented 9 years ago

and I let the: [xmppvCardTempModule fetchvCardTempForJID:[XMPPJID jidWithString:@"test11@administrator"] ignoreStorage:YES]; in the xmppStreamDidAuthenticate: delegate method?

because I am doing what you suggested and is not working It seems that it enters two times the delegate method xmppvCardTempModule:didReceivevCardTemp:forJID:

becauuse it prints out this: Recieved card: nil description Stored card: nil description xmlns: URI vcard-temp is not absolute Test40....//it returns the cached vCard not the one from server Stored card: nil description

Any clue why it is not working? is there something that I should try different, should I add a new plugin to the openFire server?

ObjColumnist commented 9 years ago

In the console do you see the iq stanzas getting logged?

daisoreanu commented 9 years ago

I just tested on device and these is what it logs after it authenticates: 2015-03-11 17:11:56.994 ChannelApp[2354:627432] Received card: nil description 2015-03-11 17:11:56.997 ChannelApp[2354:627432] Stored card: nil description 2015-03-11 17:11:57.211 ChannelApp[2354:627432] Received card: nil description 2015-03-11 17:11:57.214 ChannelApp[2354:627432] Stored card: nil description As i was saying, it seams that it enter twice in the delegate method

ObjColumnist commented 9 years ago

Sure, try setting the log levels to XMPP_LOG_FLAG_SEND_RECV to see the XMPP Stanzas

[DDLog addLogger:[DDTTYLogger sharedInstance] withLogLevel:XMPP_LOG_FLAG_SEND_RECV];
daisoreanu commented 9 years ago

I just implemented the DDLog, what should I look for now?

ObjColumnist commented 9 years ago

You should see the XMPP Stanzas in the console, so your looking to see if a vCard is sent across the network or an error.

http://xmpp.org/extensions/xep-0054.html

daisoreanu commented 9 years ago

Apparently, the call happens two times because I was asking for the vCard of another user, because I was logging in with user: "test" and was fetching the vCard or user: "test11", but I still retrieve the cached vCard, and here is what it is logged to the console:

2015-03-11 17:38:07.957 ChannerApp[2378:630889] authenticated 2015-03-11 17:38:07:963 ChannerApp[2378:1a07] SEND: 2015-03-11 17:38:08:176 ChannerApp[2378:200b] RECV: Test40( IT, PC ) 2015-03-11 17:38:08.179 ChannerApp[2378:630889] Recieved card: nil description 2015-03-11 17:38:08.185 ChannerApp[2378:630889] Stored card: nil description

ObjColumnist commented 9 years ago

that is strange because that isn't valid XML being received and send shouldn't be empty.

Does any XML get logged?

daisoreanu commented 9 years ago

Complete log:

2015-03-11 18:02:29.723 ChannerApp[2387:633421] xmppStreamWillConnect
2015-03-11 18:02:31:248 ChannerApp[2387:2203] SEND: <?xml version='1.0'?>
2015-03-11 18:02:31:249 ChannerApp[2387:2203] SEND: <stream:stream xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' version='1.0' to='administrator'>
2015-03-11 18:02:31:668 ChannerApp[2387:617] RECV: <stream:stream xmlns:stream="http://etherx.jabber.org/streams" xmlns="jabber:client" from="administrator" id="b50afa63" stream1:lang="en" version="1.0"/>
2015-03-11 18:02:31:879 ChannerApp[2387:1907] RECV: <stream:features xmlns:stream="http://etherx.jabber.org/streams"><starttls xmlns="urn:ietf:params:xml:ns:xmpp-tls"/><mechanisms xmlns="urn:ietf:params:xml:ns:xmpp-sasl"><mechanism>DIGEST-MD5</mechanism><mechanism>PLAIN</mechanism><mechanism>CRAM-MD5</mechanism></mechanisms><compression xmlns="http://jabber.org/features/compress"><method>zlib</method></compression><auth xmlns="http://jabber.org/features/iq-auth"/><register xmlns="http://jabber.org/features/iq-register"/></stream:features>
2015-03-11 18:02:31.880 ChannerApp[2387:633421] xmppStreamDidConnect
2015-03-11 18:02:31:881 ChannerApp[2387:807] SEND: <auth xmlns="urn:ietf:params:xml:ns:xmpp-sasl" mechanism="DIGEST-MD5"/>
2015-03-11 18:02:31.882 ChannerApp[2387:633421] Presence: <presence type="available"/>
namespace warning : xmlns: URI vcard-temp is not absolute
<vCard xmlns="vcard-temp"><nickname>Test40</nickname><interests>(
                         ^
2015-03-11 18:02:32:095 ChannerApp[2387:2203] RECV: <challenge xmlns="urn:ietf:params:xml:ns:xmpp-sasl">cmVhbG09ImFkbWluaXN0cmF0b3IiLG5vbmNlPSJvTktWcVJsSHl0SEhaMFlMOUpRZmdUR3BzdVNkcGFZTzF1MDNiTEloIixxb3A9ImF1dGgiLGNoYXJzZXQ9dXRmLTgsYWxnb3JpdGhtPW1kNS1zZXNz</challenge>
2015-03-11 18:02:32:098 ChannerApp[2387:2203] SEND: <response xmlns="urn:ietf:params:xml:ns:xmpp-sasl">dXNlcm5hbWU9InRlc3QxMSIscmVhbG09ImFkbWluaXN0cmF0b3IiLG5vbmNlPSJvTktWcVJsSHl0SEhaMFlMOUpRZmdUR3BzdVNkcGFZTzF1MDNiTEloIixjbm9uY2U9Ijc1MDhERjM0LUYxMUItNDY5NS1BRjZCLTQyRjVGMEVCOTdEQSIsbmM9MDAwMDAwMDEscW9wPWF1dGgsZGlnZXN0LXVyaT0ieG1wcC9hZG1pbmlzdHJhdG9yIixyZXNwb25zZT0xNGI4NGM1ODc1ZTY2MzI5NWVkOWI4MDNkNTBhMTc0OCxjaGFyc2V0PXV0Zi04</response>
2015-03-11 18:02:32:330 ChannerApp[2387:1907] RECV: <success xmlns="urn:ietf:params:xml:ns:xmpp-sasl">cnNwYXV0aD05YzFhNjE4YzY5NmIyYWMwYzYyMTM4MTFhOGZlZDEwYw==</success>
2015-03-11 18:02:32:331 ChannerApp[2387:1907] SEND: <stream:stream xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' version='1.0' to='administrator'>
2015-03-11 18:02:32:551 ChannerApp[2387:617] RECV: <stream:stream xmlns:stream="http://etherx.jabber.org/streams" xmlns="jabber:client" from="administrator" id="b50afa63" stream1:lang="en" version="1.0"/>
2015-03-11 18:02:32:551 ChannerApp[2387:617] RECV: <stream:features xmlns:stream="http://etherx.jabber.org/streams"><compression xmlns="http://jabber.org/features/compress"><method>zlib</method></compression><bind xmlns="urn:ietf:params:xml:ns:xmpp-bind"/><session xmlns="urn:ietf:params:xml:ns:xmpp-session"/></stream:features>
2015-03-11 18:02:32:553 ChannerApp[2387:617] SEND: <iq type="set" id="A4F8BE14-A907-4E87-BF81-4E55653B7F3D"><bind xmlns="urn:ietf:params:xml:ns:xmpp-bind"/></iq>
2015-03-11 18:02:32:764 ChannerApp[2387:617] RECV: <iq xmlns="jabber:client" type="result" id="A4F8BE14-A907-4E87-BF81-4E55653B7F3D" to="administrator/b50afa63"><bind xmlns="urn:ietf:params:xml:ns:xmpp-bind"><jid>test11@administrator/b50afa63</jid></bind></iq>
2015-03-11 18:02:32:767 ChannerApp[2387:617] SEND: <iq type="set" id="3959C7CA-6974-4229-B178-7B637CB19B18"><session xmlns="urn:ietf:params:xml:ns:xmpp-session"/></iq>
2015-03-11 18:02:32:980 ChannerApp[2387:617] RECV: <iq xmlns="jabber:client" type="result" id="3959C7CA-6974-4229-B178-7B637CB19B18" to="test11@administrator/b50afa63"/>
2015-03-11 18:02:32.980 ChannerApp[2387:633421] authenticated
2015-03-11 18:02:32:985 ChannerApp[2387:617] SEND: <iq type="get" to="test11@administrator"><vCard xmlns="vcard-temp"/></iq>
2015-03-11 18:02:33:197 ChannerApp[2387:2203] RECV: <iq xmlns="jabber:client" type="result" from="test11@administrator" to="test11@administrator/b50afa63"><vCard xmlns="vcard-temp"><nickname>Test40</nickname><interests>(
    IT,
    PC
)</interests></vCard></iq>
2015-03-11 18:02:33.201 ChannerApp[2387:633421] Recieved card: *nil description*
2015-03-11 18:02:33.208 ChannerApp[2387:633421] Stored card: *nil description*
ObjColumnist commented 9 years ago

Something is broken somewhere as those logs aren't correct, it is as if description has been overwritten on NSXMLNode/NSXMLElement.

Update: ah code github escaped it.

daisoreanu commented 9 years ago

Please ObjColumnist, can you take a look over the project that I send?

ObjColumnist commented 9 years ago

This isn't valid so Im guessing that is breaking it:

<interests>(
    IT,
    PC
)</interests>
daisoreanu commented 9 years ago

I added that part to the server using this code:

NSXMLElement *vCardXML = [NSXMLElement elementWithName:@"vCard" xmlns:@"vcard-temp"];
NSXMLElement *nicknameElement = [NSXMLElement elementWithName:@"nickname" stringValue:@"A0Test1"];
NSArray *myTestArray = [NSArray arrayWithObjects:@"IT",@"PC", nil];
NSXMLElement *nicknameElement2 = [NSXMLElement elementWithName:@"interests" stringValue:[NSString stringWithFormat:@"%@", myTestArray]];
[vCardXML addChild:nicknameElement];
[vCardXML addChild:nicknameElement2];
XMPPvCardTemp *newvCardTemp = [XMPPvCardTemp vCardTempFromElement:vCardXML];
[xmppvCardTempModule updateMyvCardTemp:newvCardTemp];

so if I was able to send it I should also be able to retrive it, right?

adozenlines commented 9 years ago

That would explain the broken XML stanzas.

You need create individual elements and add them as children of the root node.

On Mar 11, 2015, at 1:08 PM, daisoreanu notifications@github.com wrote:

I added that part to the server using this code: NSXMLElement vCardXML = [NSXMLElement elementWithName:@"vCard" xmlns:@"vcard-temp"]; NSXMLElement nicknameElement = [NSXMLElement elementWithName:@"nickname" stringValue:@"A0Test1"]; NSArray myTestArray = [NSArray arrayWithObjects:@"IT",@"PC", nil]; NSXMLElement nicknameElement2 = [NSXMLElement elementWithName:@"interests" stringValue:[NSString stringWithFormat:@"%@", myTestArray]]; [vCardXML addChild:nicknameElement]; [vCardXML addChild:nicknameElement2]; XMPPvCardTemp *newvCardTemp = [XMPPvCardTemp vCardTempFromElement:vCardXML]; [xmppvCardTempModule updateMyvCardTemp:newvCardTemp];

— Reply to this email directly or view it on GitHub https://github.com/robbiehanson/XMPPFramework/issues/503#issuecomment-78308255.

adozenlines commented 9 years ago
 <interests>
 <interest>IT</interest>
 <interest>WEB</interest>
 </interests>
NSXMLElement *interestElement = [NSXMLElement elementWithName:@"interests"];

NSArray *listOfInterest = @[@"IT",@"WEB"];

for (NSString *interest in listOfInterest) {

    NSXMLElement *interestNode = [NSXMLElement elementWithName:@"interest" stringValue:interest];

    [interestElement addChild:interestNode];

}
adozenlines commented 9 years ago

But according to the spec interests is not a defined element of the vCard format.

http://xmpp.org/extensions/xep-0292.html http://xmpp.org/extensions/xep-0292.html http://xmpp.org/extensions/xep-0054.html http://xmpp.org/extensions/xep-0054.html

On Mar 11, 2015, at 1:42 PM, Sean Batson sean.batson@gmail.com wrote:

        /**
         <interests>
         <interest>IT</interest>
         <interest>WEB</interest>
         </interests>
         */

        NSXMLElement *interestElement = [NSXMLElement elementWithName:@"interests"];

        NSArray *listOfInterest = @[@"IT",@"WEB"];

        for (NSString *interest in listOfInterest) {

            NSXMLElement *interestNode = [NSXMLElement elementWithName:@"interest" stringValue:interest];

            [interestElement addChild:interestNode];

        }

On Mar 11, 2015, at 1:35 PM, Sean Batson <sean.batson@gmail.com mailto:sean.batson@gmail.com> wrote:

That would explain the broken XML stanzas.

You need create individual elements and add them as children of the root node.

On Mar 11, 2015, at 1:08 PM, daisoreanu <notifications@github.com mailto:notifications@github.com> wrote:

I added that part to the server using this code: NSXMLElement vCardXML = [NSXMLElement elementWithName:@"vCard" xmlns:@"vcard-temp"]; NSXMLElement nicknameElement = [NSXMLElement elementWithName:@"nickname" stringValue:@"A0Test1"]; NSArray myTestArray = [NSArray arrayWithObjects:@"IT",@"PC", nil]; NSXMLElement nicknameElement2 = [NSXMLElement elementWithName:@"interests" stringValue:[NSString stringWithFormat:@"%@", myTestArray]]; [vCardXML addChild:nicknameElement]; [vCardXML addChild:nicknameElement2]; XMPPvCardTemp *newvCardTemp = [XMPPvCardTemp vCardTempFromElement:vCardXML]; [xmppvCardTempModule updateMyvCardTemp:newvCardTemp];

— Reply to this email directly or view it on GitHub https://github.com/robbiehanson/XMPPFramework/issues/503#issuecomment-78308255.

adozenlines commented 9 years ago

Sorry but I cannot help you with that.

On Mar 11, 2015, at 2:43 PM, daisoreanu notifications@github.com wrote:

So what should be my approach if I want to add a custom element in the XML?

— Reply to this email directly or view it on GitHub https://github.com/robbiehanson/XMPPFramework/issues/503#issuecomment-78343008.

ObjColumnist commented 9 years ago

The vCard standard says you can start custom elements with an X- but it's possible that XMPP/Openfire might reject it.

NSArray *interests = @[@"IT",@"WEB"];

for (NSString interest in interests) { NSXMLElement interestNode = [NSXMLElement elementWithName:@"X-INTEREST" stringValue:interest]; [vCardXML addChild:interestNode]; }

daisoreanu commented 9 years ago

On the server the vCard looks like this:

  <vCard xmlns="vcard-temp"><nickname>Test007</nickname><interests>(IT,PC)</interests></vCard>

So how should the vCard look like on the server? Because I am thinking about changing the XML on the server and then check the fetch in the app.

ObjColumnist commented 9 years ago
<vCard xmlns="vcard-temp"><nickname>Test007</nickname><x-interest>IT</x-interest><x-interest>PC</x-interest></vCard>
daisoreanu commented 9 years ago

I ha tested using the suggested XML, the change I made directly on the server, and then I test it, for the first time I tested it , it returned the XML in the logger like so:

2015-03-12 17:23:07.810 ChannerApp[2822:768322] xmppStreamWillConnect
2015-03-12 17:23:07:884 ChannerApp[2822:2103] SEND: <?xml version='1.0'?>
2015-03-12 17:23:07:886 ChannerApp[2822:2103] SEND: <stream:stream xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' version='1.0' to='administrator'>
2015-03-12 17:23:07:919 ChannerApp[2822:5d07] RECV: <stream:stream xmlns:stream="http://etherx.jabber.org/streams" xmlns="jabber:client" from="administrator" id="4db7bd5d" stream1:lang="en" version="1.0"/>
2015-03-12 17:23:07:929 ChannerApp[2822:5d07] RECV: <stream:features xmlns:stream="http://etherx.jabber.org/streams"><starttls xmlns="urn:ietf:params:xml:ns:xmpp-tls"/><mechanisms xmlns="urn:ietf:params:xml:ns:xmpp-sasl"><mechanism>DIGEST-MD5</mechanism><mechanism>PLAIN</mechanism><mechanism>CRAM-MD5</mechanism></mechanisms><compression xmlns="http://jabber.org/features/compress"><method>zlib</method></compression><auth xmlns="http://jabber.org/features/iq-auth"/><register xmlns="http://jabber.org/features/iq-register"/></stream:features>
2015-03-12 17:23:07.930 ChannerApp[2822:768322] xmppStreamDidConnect
2015-03-12 17:23:07:930 ChannerApp[2822:807] SEND: <auth xmlns="urn:ietf:params:xml:ns:xmpp-sasl" mechanism="DIGEST-MD5"/>
2015-03-12 17:23:07.931 ChannerApp[2822:768322] Presence: <presence type="available"/>
namespace warning : xmlns: URI vcard-temp is not absolute
<vCard xmlns="vcard-temp"><nickname>Test007</nickname><x-interest>IT</x-interest
                         ^
2015-03-12 17:23:07:946 ChannerApp[2822:5d07] RECV: <challenge xmlns="urn:ietf:params:xml:ns:xmpp-sasl">cmVhbG09ImFkbWluaXN0cmF0b3IiLG5vbmNlPSJLb3IyZ1ZxdXM3a2xabTNDVWpCdlF4MGh6b1czaUFTQjNSYzJFQVAvIixxb3A9ImF1dGgiLGNoYXJzZXQ9dXRmLTgsYWxnb3JpdGhtPW1kNS1zZXNz</challenge>
2015-03-12 17:23:07:947 ChannerApp[2822:5d07] SEND: <response xmlns="urn:ietf:params:xml:ns:xmpp-sasl">dXNlcm5hbWU9InRlc3QxMSIscmVhbG09ImFkbWluaXN0cmF0b3IiLG5vbmNlPSJLb3IyZ1ZxdXM3a2xabTNDVWpCdlF4MGh6b1czaUFTQjNSYzJFQVAvIixjbm9uY2U9IjA1NjZGREY3LURGNEItNDU5Mi04NkNELTU4REI0RkZFOTY1MSIsbmM9MDAwMDAwMDEscW9wPWF1dGgsZGlnZXN0LXVyaT0ieG1wcC9hZG1pbmlzdHJhdG9yIixyZXNwb25zZT0yNmQyYjBmZGYxMDA4NmY0OTYwNjM5MjE1MWQ0MDgxYixjaGFyc2V0PXV0Zi04</response>
2015-03-12 17:23:07:983 ChannerApp[2822:5d07] RECV: <success xmlns="urn:ietf:params:xml:ns:xmpp-sasl">cnNwYXV0aD1kMjc4NzgzNDBhNWM5OWVkZDQ0ZjRiNWY5MTBjODZiNg==</success>
2015-03-12 17:23:07:983 ChannerApp[2822:5d07] SEND: <stream:stream xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' version='1.0' to='administrator'>
2015-03-12 17:23:07:992 ChannerApp[2822:3303] RECV: <stream:stream xmlns:stream="http://etherx.jabber.org/streams" xmlns="jabber:client" from="administrator" id="4db7bd5d" stream1:lang="en" version="1.0"/>
2015-03-12 17:23:07:992 ChannerApp[2822:3303] RECV: <stream:features xmlns:stream="http://etherx.jabber.org/streams"><compression xmlns="http://jabber.org/features/compress"><method>zlib</method></compression><bind xmlns="urn:ietf:params:xml:ns:xmpp-bind"/><session xmlns="urn:ietf:params:xml:ns:xmpp-session"/></stream:features>
2015-03-12 17:23:07:993 ChannerApp[2822:3303] SEND: <iq type="set" id="A2AB299C-7C7A-4D80-9CA1-B74D1C345C20"><bind xmlns="urn:ietf:params:xml:ns:xmpp-bind"/></iq>
2015-03-12 17:23:08:009 ChannerApp[2822:3303] RECV: <iq xmlns="jabber:client" type="result" id="A2AB299C-7C7A-4D80-9CA1-B74D1C345C20" to="administrator/4db7bd5d"><bind xmlns="urn:ietf:params:xml:ns:xmpp-bind"><jid>test11@administrator/4db7bd5d</jid></bind></iq>
2015-03-12 17:23:08:010 ChannerApp[2822:3303] SEND: <iq type="set" id="28C791CB-B48B-45AE-8264-2CA7DBA1FD5C"><session xmlns="urn:ietf:params:xml:ns:xmpp-session"/></iq>
2015-03-12 17:23:08:035 ChannerApp[2822:2103] RECV: <iq xmlns="jabber:client" type="result" id="28C791CB-B48B-45AE-8264-2CA7DBA1FD5C" to="test11@administrator/4db7bd5d"/>
2015-03-12 17:23:08.036 ChannerApp[2822:768322] authenticated
2015-03-12 17:23:08:037 ChannerApp[2822:3303] SEND: <iq type="get" to="test11@administrator"><vCard xmlns="vcard-temp"/></iq>
2015-03-12 17:23:08:056 ChannerApp[2822:3303] RECV: <iq xmlns="jabber:client" type="result" from="test11@administrator" to="test11@administrator/4db7bd5d"><vCard xmlns="vcard-temp"><nickname>Test007</nickname><x-interest>IT</x-interest><x-interest>PC</x-interest></vCard></iq>
2015-03-12 17:23:08.057 ChannerApp[2822:768322] Recieved card: *nil description*
2015-03-12 17:23:08.059 ChannerApp[2822:768322] Stored card: *nil description*

As you can see it still says:

Presence: 24 namespace warning : xmlns: URI vcard-temp is not absolute

Test007IT
daisoreanu commented 9 years ago

I also tried by removing the interests like: <vCard xmlns="vcard-temp"><nickname>Test11</nickname></vCard> and it also didn't work

daisoreanu commented 9 years ago

Regarding namespace warning I have found the answer in one of your previous posts and the answer was: This is a message from libxml (the underlying XML Parser), the XEP Spec specifies an "invalid" xmlns so unfortunately its a bug in the specification not the XMPPFramework.

daisoreanu commented 9 years ago

so I tested the error with namespace on another device and first time when I launch the app it doesn't appear

daisoreanu commented 9 years ago

also the problem seems to be related to the fact that I made a previous request for that user, so when I make a second request for a users vCard even if the vCard was updated, it doesn't seem to fetch it, it only shows in the console the previous fetched vCard

ObjColumnist commented 9 years ago

There is code to prevent apps rerequesting vCard continuously:

  1. They don't change that often
  2. They can be quite large
  3. A vCard Hash can be advertised in a users presence, if the Hash has changed the vCard is downloaded.

But that doesn't explain why nil is being logged after the vCard has been downloaded.

daisoreanu commented 9 years ago

Will the code help? And regarding point 3, if I logout/ login, then should the vCard be downloaded again? because if I do so, then the vCard is not downloaded

ObjColumnist commented 9 years ago

The code might help but there are so many variables (including the sever) it's hard to find unless it is obvious.

You might just have to step through the code using the debugger to see where it is going wrong. The vCard appears to be recieved by the client and the correct delegate method is being called, so it is all very strange.

daisoreanu commented 9 years ago

Yes, the problem sees to be that the vCard that is received is the one that have somehow been cached, on the server I change the vCard in the ofVCard section for the user.