【问题标题】:How to create/ update/ retrieve user vCard using XMPPFramework and OpeFire on iOS如何在 iOS 上使用 XMPPFramework 和 OpeFire 创建/更新/检索用户 vCard
【发布时间】:2015-05-06 21:08:58
【问题描述】:

正如标题所示,我正在尝试为我的用户创建一个 vcard 并将其发送到服务器,但它似乎不起作用,有什么想法吗?我将非常感谢任何帮助

这是我的代码以及流连接和身份验证,我包括这些部分是因为它们可能也有问题,因为我是使用 xmpp 框架的菜鸟,我使用的 iOS 客户端是:https://github.com/robbiehanson/XMPPFramework

.h 类代码为:

#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 类实现

@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];
    }
}

当我连接和身份验证时返回 1,但卡未上传,我所做的是否正确,至少部分正确?

感谢您的支持并为所有答案投票!

【问题讨论】:

    标签: ios objective-c xmpp openfire vcf-vcard


    【解决方案1】:

    更新 1 - 上传 VCARD 成功:

    我已经设法使用下一个代码更新/创建了一个 vCard,但是当我尝试使用 setLabels 方法发送一个 NSArray 时出现问题,该数组未发送到服务器或服务未保存当它收到它时。

    这是我的更新:

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

    从我的测试中我得出结论,当服务应该处理 NSArrays 时应该存在问题。

    我也尝试发送自定义 XML,这里是示例,我不知道如何发送数组,所以我将其转换为字符串:

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

    我的问题现在仍然存在,如何检查它是否到达服务器,当 vCard 传输完成时,xmpp 框架是否调用了任何委托方法,就像在流情况下一样?以及如何从服务器接收 vCard?

    【讨论】:

      【解决方案2】:

      更新 2

      -> 如何检查vCard是否发送成功?

      -> 答:这是通过实现接下来的两个委托方法来完成的:

       - (void)xmppvCardTempModuleDidUpdateMyvCard:(XMPPvCardTempModule *)vCardTempModule;
      
       - (void)xmppvCardTempModule:(XMPPvCardTempModule *)vCardTempModule failedToUpdateMyvCard:(NSXMLElement *)error;
      

      【讨论】:

        【解决方案3】:

        更新 3 - 在上传 vCard 时需要帮助:

        所以在成功上传我的 vCard 后,我尝试实现提取 vCard,因此我将上传代码替换为 xmppStreamDidAuthenticate:delegate 方法中的提取代码,并在我的 .h 文件中添加了委托 XMPPvCardTempModuleDelegate。 并测试是否调用了 xmppvCardTempModule:didReceivevCardTemp:forJID: 委托方法。 问题是调用了委托方法,但是 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);
        
        }
        

        【讨论】:

          猜你喜欢
          • 2014-02-19
          • 1970-01-01
          • 2013-09-24
          • 1970-01-01
          • 2014-07-15
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-05-08
          相关资源
          最近更新 更多