XMPPFramework iOS开发(五)电子名片

XMPPFramework iOS开发(五)电子名片

一、程序目标

XMPPFramework iOS开发(五)电子名片_第1张图片

这是项目4个TabBar下的其中一个,用于电子名片的显示和更改。其中个人信息界面下,头像所在的cell设置tag为0,微信号设置tag为2,其他点击后会跳转到编辑页面更改信息的设置tag为1。

二、电子名片

电子名片的文件格式标准是vCard,XMPP框架下的Extensions文件夹下面的XEP-0054提供了一种机制,可以通过XMPP发送电子名片。

使用电子名片的步骤分为以下4步:
1、在XMPPFramework.h中启用电子名片的扩展头文件

//电子名片模块
#import "XMPPvCardTempModule.h"
#import "XMPPvCardCoreDataStorage.h"

//电子名片头像模块
#import "XMPPvCardAvatarModule.h"

2、在XMPPTool中定义成员变量
3、为XMPPStream添加电子名片拓展
4、需要时使用

电子名片模块内部实现的功能有两个:
1. 发送请求从服务器获取“电子名片”数据
2. 把数据缓存到本地数据库

三、使用前准备

首先,在WCXMPPTool.h文件中定义成员变量

//电子名片模块
@property (nonatomic, strong, readonly) XMPPvCardTempModule *vCard;
//电子名片数据存储
@property (nonatomic, strong, readonly) XMPPvCardCoreDataStorage *vCardStorage;
//头像模块
@property (nonatomic, strong, readonly) XMPPvCardAvatarModule *avatar;

之后,为XMPPStream添加电子名片拓展,放在setupStream方法里面。

 // 1.添加电子名片模块
    _vCardStorage = [XMPPvCardCoreDataStorage sharedInstance];
    _vCard = [[XMPPvCardTempModule alloc] initWithvCardStorage:_vCardStorage];
    // 激活
    [_vCard activate:_xmppStream];

    // 2.添加头像模块
    _avatar = [[XMPPvCardAvatarModule alloc] initWithvCardTempModule:_vCard];
    [_avatar activate:_xmppStream];

四、WCMeViewController

在上一节中已经实现了注销的功能,这里不再重复贴代码,只贴上设置cell的数据的代码:

- (void)viewDidLoad
{
    [super viewDidLoad];

    //不能使用myvCard.jid.user获取,因为服务器返回的xml数据没有JABBERID节点
    NSString *str = @"微信号: ";
    self.wechatNumLabel.text = [str stringByAppendingString:[WCUser shareUser].loginAccount];

    //登录用户的电子名片信息, 它会自动查找本地数据库,不需要自己写数据库操作语句
    XMPPvCardTemp *myvCard = [WCXMPPTool sharedWCXMPPTool].vCard.myvCardTemp;

    //获取头像
    if (myvCard.photo) {
        self.avatarImageView.image = [UIImage imageWithData:myvCard.photo];
    }
}

五、WCProfileViewController

5.1 获取数据

@interface WCProfileViewController () <WCEditVCardViewControllerDelegate, UIImagePickerControllerDelegate, UIActionSheetDelegate, UINavigationControllerDelegate>

@property (weak, nonatomic) IBOutlet UIImageView *avatarImageView;   //头像
@property (weak, nonatomic) IBOutlet UILabel *nicknameLabel;    //昵称
@property (weak, nonatomic) IBOutlet UILabel *wechatNumLabel;   //微信号
@property (weak, nonatomic) IBOutlet UILabel *orgNameLabel;     //公司
@property (weak, nonatomic) IBOutlet UILabel *titleLabel;         //职位
@property (weak, nonatomic) IBOutlet UILabel *telLabel;       //电话
@property (weak, nonatomic) IBOutlet UILabel *emailLabel;        //邮件

@end

@implementation WCProfileViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

    //XMPP框架内电子名片xml数据解析的功能没有完善,有些节点没有解析,所以称为temp
    XMPPvCardTemp *myvCard = [WCXMPPTool sharedWCXMPPTool].vCard.myvCardTemp;

    //获取头像
    if (myvCard.photo) {
        self.avatarImageView.image = [UIImage imageWithData:myvCard.photo];
    }

    self.wechatNumLabel.text = [WCUser shareUser].loginAccount;

    self.nicknameLabel.text = myvCard.nickname;

    if (myvCard.orgUnits.count > 0) {
        self.orgNameLabel.text = myvCard.orgUnits[0];
    }

    self.titleLabel.text = myvCard.title;

    //XMPP框架内部没有解析电话节点,需要自己解析,这里使用 note 充当电话
    self.telLabel.text = myvCard.note;

    NSArray *emails = myvCard.emailAddresses;
    if (emails.count > 0) {
        self.emailLabel.text = emails[0];
    }

}

上面的一些协议之后会用到,其中WCEditVCardViewControllerDelegate是之后编写编辑页面的功能时自己定义的协议,UIImagePickerControllerDelegate是编写更新头像功能时需要用到的协议。

5.2 cell点击事件

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *selectedCell = [tableView cellForRowAtIndexPath:indexPath];
    switch (selectedCell.tag) {
        case 0:
            ZHLog(@"换头像");
            [self chooseImage];
            break;

        case 1:
            ZHLog(@"跳转到EditVCardViewController");
            [self performSegueWithIdentifier:@"toEditVCard" sender:selectedCell];
            break;

        case 2:
            ZHLog(@"不做任何操作");
            break;

        default:
            break;
    }
}

tag的设置在本文开头讲过了。

5.3 更改个人信息

跳转到个人信息编辑页面:

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    id destVc = segue.destinationViewController;

    if ([destVc isKindOfClass:[WCEditVCardViewController class]]) {
        WCEditVCardViewController *editVc = destVc;
        editVc.cell = sender;
        editVc.delegate = self;
    }
}

5.4 点击头像

#pragma mark 选择图片
- (void)chooseImage
{
    UIActionSheet *sheet = [[UIActionSheet alloc] initWithTitle:@"请选择" delegate:self cancelButtonTitle:@"取消" destructiveButtonTitle:@"拍照" otherButtonTitles:@"图库", nil];
    [sheet showInView:self.view];
}

- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
{
    ZHLog(@"%ld", (long)buttonIndex);

    if (buttonIndex == 2)   return;

    //图片选择器
    UIImagePickerController *imagePc = [[UIImagePickerController alloc] init];

    imagePc.delegate = self;

    //允许编辑图片
    imagePc.allowsEditing = YES;

    if (buttonIndex == 0) { //拍照
        imagePc.sourceType = UIImagePickerControllerSourceTypeCamera;
    }else{ //图库
        imagePc.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
    }

    //显示
    [self presentViewController:imagePc animated:YES completion:nil];
}

5.5 更新头像

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
    ZHLog(@"%@", info);

    //获取编辑后的图片
    UIImage *editImg = info[UIImagePickerControllerEditedImage];

    //更新头像
    self.avatarImageView.image = editImg;

    //退出图片选择控制器
    [self dismissViewControllerAnimated:YES completion:nil];

    //更新数据到服务器
    [self editVCardViewController:nil didClickSaveBtn:nil];
}

上面最后一句代码,编辑个人信息完成后、更新头像完成后都需要更新数据到服务器,因此不需要另外写一个方法,使用现成的即可。

5.6 更新数据到服务器

#pragma mark 电子名片编辑器的代理方法
- (void)editVCardViewController:(WCEditVCardViewController *)editVc didClickSaveBtn:(id)sender
{
    XMPPvCardTemp *myvCard = [WCXMPPTool sharedWCXMPPTool].vCard.myvCardTemp;

    //myvCard.photo是NSData类型,因此需要使用UIImageJPEGRepresentation方法把图片转换为NSData类型
    //第二个参数指图片压缩比例,比如10k*0.75=7.5k
    myvCard.photo = UIImageJPEGRepresentation(self.avatarImageView.image, 0.75);
    myvCard.nickname = self.nicknameLabel.text;
    myvCard.orgName = self.orgNameLabel.text;
    myvCard.title = self.titleLabel.text;
    myvCard.note = self.telLabel.text;

    if (self.emailLabel.text.length > 0) {
        myvCard.emailAddresses = @[self.emailLabel.text];
    }

    //数据更新到服务器
    [[WCXMPPTool sharedWCXMPPTool].vCard updateMyvCardTemp:myvCard];
}

这个代码有一个不好的地方就是每修改一个数据,就需要把个人信息全更新一遍,如果想优化这个代码,需要对openfire进行二次开发。

六、WCEditViewController

6.1 WCEditViewController.h

#import <UIKit/UIKit.h>

@class WCEditVCardViewController;

@protocol WCEditVCardViewControllerDelegate <NSObject>

@optional
- (void)editVCardViewController:(WCEditVCardViewController *)editVc didClickSaveBtn:(id)sender;

@end


@interface WCEditVCardViewController : UITableViewController

/** * 上一个控制器(Profile)传入的cell */
@property (nonatomic, strong) UITableViewCell *cell;

/** * 保存后通知Profile更新数据 */
@property (nonatomic, weak) id<WCEditVCardViewControllerDelegate> delegate;

@end

6.2 WCEditViewController.m

@implementation WCEditVCardViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

    //设置控制器标题
    self.title = self.cell.textLabel.text;

    //设置输入框默认值
    self.tectField.text = self.cell.detailTextLabel.text;
}

- (IBAction)saveBtnClick:(id)sender {

    // 1.更新cell的detailTextLabel
    self.cell.detailTextLabel.text = self.tectField.text;

    [self.cell layoutSubviews];

    // 2.退出当前控制器
    [self.navigationController popViewControllerAnimated:YES];

    // 3.通知代理
    if ([self.delegate respondsToSelector:@selector(editVCardViewController:didClickSaveBtn:)]) {
        [self.delegate editVCardViewController:self didClickSaveBtn:sender];
    }
}
@end

七、小结

XMPPFramework iOS开发(五)电子名片_第2张图片

以上。

你可能感兴趣的:(ios,XMPP,个人信息,电子名片)