How to create/ update/ retrieve user vCard using X

2020-06-23 09:01发布

As the title suggests,I am trying to create a vcard for my user and send it to the server, but it seems that it doesn't work, any ideas? i will much appreciate any help

Here is my code together with the stream connect and authentication, I included thses part bacause there may also be something wrong with them, as I am a noob in working with xmpp framework, the iOS client thaI use is: https://github.com/robbiehanson/XMPPFramework

the .h class code is:

#import <UIKit/UIKit.h>
#import "XMPPStream.h"
#import "XMPP.h"
#import "XMPPReconnect.h"
#import "XMPPPresence.h"
#import "XMPPRoster.h"
#import "ForgotPasswordViewController.h"
#import "XMPPReconnect.h"
#import "XMPPRosterCoreDataStorage.h"
#import "ConractsViewController.h"
#import "KeychainItemWrapper.h"
#import "SignUpViewController.h"
#import "XMPPvCardTemp.h"
#import "XMPPvCardTempModule.h"
#import "XMPPvCardCoreDataStorage.h"

@interface SignInViewController : UIViewController <UITextFieldDelegate, XMPPRosterDelegate, XMPPStreamDelegate>

@property (strong, nonatomic) XMPPRosterCoreDataStorage *xmppRosterStorage;
@property (strong, nonatomic) XMPPRoster *xmppRoster;
@property (strong, nonatomic) XMPPReconnect *reconnect;
@property (strong, nonatomic) XMPPStream *xmppStream;

@end

.m class implementation

@implementation SignInViewController
@synthesize xmppRosterStorage, xmppRoster, reconnect, xmppStream;

- (void)viewDidLoad {

    //add SignIn button
    int signInButtonXPossition = [[UIScreen mainScreen] bounds].size.width * 0.1f;
    int signInButtonYPossition = [[UIScreen mainScreen] bounds].size.height * 0.55f;
    int signInButtonWidth = [[UIScreen mainScreen] bounds].size.width * 0.8f;
    int signInButtonHeight = [[UIScreen mainScreen] bounds].size.height * 0.07;
    UIButton *signInButton = [[UIButton alloc] initWithFrame:CGRectMake(signInButtonXPossition, signInButtonYPossition, signInButtonWidth, signInButtonHeight)];
    [signInButton addTarget:self
                     action:@selector(signInButtonFunction)
           forControlEvents:UIControlEventTouchUpInside];
    signInButton.backgroundColor = [UIColor colorWithRed:(167/255.f) green:(224/255.f) blue:(250/255.f) alpha:1];
    signInButton.layer.cornerRadius=[[UIScreen mainScreen] bounds].size.width * 0.05f;
    signInButton.layer.borderWidth=1.0;
    signInButton.layer.masksToBounds = YES;
    signInButton.layer.borderColor=[[UIColor whiteColor] CGColor];
    [self.view addSubview:signInButton];
    [signInButton setTitle:@"Sign In" forState:UIControlStateNormal];

}

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

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

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

}

- (void)xmppStreamDidConnect:(XMPPStream *)sender {
    NSError *error = nil;

    if (![xmppStream authenticateWithPassword:@"test" error:&error]) {
        UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Error"
                                                            message:[NSString stringWithFormat:@"Can't authenticate %@", [error localizedDescription]]
                                                           delegate:nil
                                                  cancelButtonTitle:@"Ok"
                                                  otherButtonTitles:nil];
        [alertView show];
    }
    XMPPPresence *mypresence = [XMPPPresence presenceWithType:@"available"];
    [xmppStream sendElement:mypresence];
}

- (void)xmppStreamWillConnect:(XMPPStream *)sender{
    NSLog(@"Did connect");
}

- (void)xmppStreamDidAuthenticate:(XMPPStream *)sender{
    NSLog(@"e%d",[xmppStream isConnected]);//prints out 1
    NSLog(@"e%d",[xmppStream isAuthenticated]);//prints out 1

    if ([xmppStream isAuthenticated]) {
        NSLog(@"authenticated");

            XMPPvCardCoreDataStorage* xmppvCardStorage = [XMPPvCardCoreDataStorage sharedInstance];

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

            XMPPvCardTemp *xmppvCardTemp;
            NSXMLElement *vCardElement = [NSXMLElement elementWithName:@"vCard" xmlns:@"vcard-temp"];
            NSXMLElement *nicknameElement = [NSXMLElement elementWithName:@"nickname" stringValue:@"A0Test1"];
            [vCardElement addChild:nicknameElement];
            xmppvCardTemp = [XMPPvCardTemp vCardTempFromElement:vCardElement];
            [xmppvCardTempModule updateMyvCardTemp:xmppvCardTemp];
    }
}

It returns 1 when I connect and when I authenticate, but the card is not uploaded, is it correct what I do, at least partially?

Thank you for your support and vote up for all answers!

3条回答
放我归山
2楼-- · 2020-06-23 09:38

UPDATE 3 - Need help in uploading the vCard:

So after succeeding in uploading my vCard I tried to implement the fetch vCard, so I replaced the upload code with the fetch code in the xmppStreamDidAuthenticate:delegate method and also in my .h file added the delegate XMPPvCardTempModuleDelegate. And tested if the xmppvCardTempModule:didReceivevCardTemp:forJID: delegate method is called. The problem is that the delegate method is called but the NSLogs: Stored card: (null).

-(void)xmppStreamDidAuthenticate:(XMPPStream *)sender{

    if ([xmppStream isAuthenticated]) {
        NSLog(@"authenticated");
        xmppvCardStorage = [[XMPPvCardCoreDataStorage alloc] initWithInMemoryStore];
        xmppvCardTempModule = [[XMPPvCardTempModule alloc] initWithvCardStorage:xmppvCardStorage];
        [xmppvCardTempModule activate:[self xmppStream]];
        [xmppvCardTempModule addDelegate:self delegateQueue:dispatch_get_main_queue()];
        [xmppvCardTempModule fetchvCardTempForJID:[XMPPJID jidWithString:@"test11@administrator"] ignoreStorage:YES];
                                      }

}

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


    NSLog(@"Delegate is called");
    XMPPvCardTemp *test = [xmppvCardStorage vCardTempForJID:jid xmppStream:xmppStream];
    NSLog(@"Stored card: %@",test.description);

}
查看更多
啃猪蹄的小仙女
3楼-- · 2020-06-23 09:41

UPDATE 2

-> How to check that the vCard was successfully send or not?

-> Answer: This is done by implementing the next two delegate methods:

 - (void)xmppvCardTempModuleDidUpdateMyvCard:(XMPPvCardTempModule *)vCardTempModule;

 - (void)xmppvCardTempModule:(XMPPvCardTempModule *)vCardTempModule failedToUpdateMyvCard:(NSXMLElement *)error;
查看更多
【Aperson】
4楼-- · 2020-06-23 09:54

UPDATE 1 - UPLOAD VCARD SUCCEEDED:

I have managed to update/ create a vCard by using the next code but I have a problem when I try to send an NSArray, using the method setLabels, the array is not send to the server or the serve doesn't save it when it receives it.

Here is my update:

- (void)xmppStreamDidAuthenticate:(XMPPStream *)sender{

    if ([xmppStream isAuthenticated]) {
        NSLog(@"authenticated");
        dispatch_queue_t queue = dispatch_queue_create("queue", DISPATCH_QUEUE_PRIORITY_DEFAULT);
        dispatch_async(queue, ^{

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

            XMPPvCardTemp *myVcardTemp = [xmppvCardTempModule myvCardTemp];

            if (!myVcardTemp) {
                NSLog(@"TEST FOR VCARD");
                NSXMLElement *vCardXML = [NSXMLElement elementWithName:@"vCard" xmlns:@"vcard-temp"];
                XMPPvCardTemp *newvCardTemp = [XMPPvCardTemp vCardTempFromElement:vCardXML];
                [newvCardTemp setNickname:@"nick"];
                [xmppvCardTempModule updateMyvCardTemp:newvCardTemp];
            }else{
                //Set Values as normal
                NSLog(@"TEST FOR VCARD ELSE");

                        NSLog(@"TEST FOR VCARD");
                        NSXMLElement *vCardXML = [NSXMLElement elementWithName:@"vCard" xmlns:@"vcard-temp"];
                        XMPPvCardTemp *newvCardTemp = [XMPPvCardTemp vCardTempFromElement:vCardXML];
                        [newvCardTemp setNickname:@"aaaaaa"];
                        NSArray *interestsArray= [[NSArray alloc] initWithObjects:@"food", nil];
                        [newvCardTemp setLabels:interestsArray];
                        [newvCardTemp setMiddleName:@"Stt"];

                        [newvCardTemp setEmailAddresses:[NSMutableArray arrayWithObjects:@"email", nil]];

                        [xmppvCardTempModule updateMyvCardTemp:newvCardTemp];
            }
        });   
    }   
}

from my test I conclude that there should be an issue when the serve should handle NSArrays.

I also tried to send a custom XML, here is the example, I don't know how to send an array so I converted it to string:

        NSLog(@"TEST FOR VCARD");
        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];

My question remains now, how to check if it reached the server, is there any delegate method called by xmpp framework when the vCard transfer is completed like in stream case? and how can I receive the vCard from the server?

查看更多
登录 后发表回答