前言
上一篇博客中我們說到如何通過XMPPFramework中的代理方法來獲取到好友節(jié)點(diǎn)數(shù)據(jù)信息,但是我們發(fā)現(xiàn)節(jié)點(diǎn)信息能展示的只有JID,所以今天我們就說一下在XMPPFramework如何設(shè)置名片信息以及如何獲取自己的和好友的名片信息.
XMPP中的電子名片簡介(來自網(wǎng)絡(luò)...)
在Extensions中有XEP-0054擴(kuò)展燃异,提供了一種可以通過XMPP發(fā)送電子名片的機(jī)制睬棚。
- vCard蛛砰,也叫Versitcard咙鞍,vCard的常用文件擴(kuò)展名是.vcf烤宙。在XMPPFramework中通過XMPPvCardTemp和XMPPvCardCoreDataStorage兩個(gè)類來實(shí)現(xiàn)。
- vCard是電子名片的文件格式標(biāo)準(zhǔn)联四,一般附加在電子郵件之后凯肋,但也可以用于其它場(chǎng)合,比如在因特網(wǎng)上相互交換蝙场。
這里我要說一下在XMPPFramework中電子名片的幾個(gè)相關(guān)的類.其中,XMPPv CardTempModule這個(gè)類使用做電子名片的讀取和存儲(chǔ),XMPPvCardCoreDataStorage用來做電子名片的本地存儲(chǔ),XMPPvCardAvatarModule是用來做頭像的存儲(chǔ)和讀取的,XMPPvCardTemp則是電子名片.
這里我要說一下關(guān)于XMPPvCardTemp相關(guān)的屬性,XMPPvCardTemp是電子名片類.用戶的電子名片就是XMPPvCardTemp對(duì)象.這里我就把幾個(gè)常用的屬性列舉出來.當(dāng)然了,我們可以自己對(duì)其中一些屬性進(jìn)行存儲(chǔ)修改,我們只要知道我們?cè)谀囊粋€(gè)屬性存儲(chǔ)了什么數(shù)據(jù)即可,比如我們讓nickname(標(biāo)準(zhǔn)化姓名)存儲(chǔ)一個(gè)地址字符串,然后取出來nickname的時(shí)候,我們知道是nickname存儲(chǔ)的是什么即可.靈活運(yùn)用XMPPvCardTemp的各種屬性.
//頭像圖片屬性
@property (nonatomic, strong) NSData *photo;
//標(biāo)準(zhǔn)化名稱
@property (nonatomic, strong) NSString *nickname;
//地址數(shù)組
@property (nonatomic, strong) NSArray *addresses;
//公司名稱
@property (nonatomic, strong) NSString *orgName;
//部門數(shù)組
@property (nonatomic, strong) NSArray *orgUnits;
//職位
@property (nonatomic, strong) NSString *title;
//郵件地址數(shù)組
@property (nonatomic, strong) NSArray *emailAddresses;
//備注
@property (nonatomic, strong) NSString *note;
</br>
XMPPFramework中電子名片相關(guān)的方法說明
下面是XMPPFramework中與電子名片相關(guān)的方法(下述的所有方法都在在X MPPvCardTempModule類中).
注意:??????最后一個(gè)是代理方法,我們調(diào)用前兩個(gè)方法在獲取到電子名片數(shù)據(jù)之后,會(huì)調(diào)起最后的那個(gè)代理方法.
//到服務(wù)器上請(qǐng)求聯(lián)系人名片信息
- (void)fetchvCardTempForJID:(XMPPJID *)jid;
//請(qǐng)求聯(lián)系人的名片凌停,如果數(shù)據(jù)庫有就不請(qǐng)求,沒有就發(fā)送名片請(qǐng)求
- (void)fetchvCardTempForJID:(XMPPJID *)jid ignoreStorage:(BOOL)ignoreStorage;
//獲取聯(lián)系人的名片售滤,如果數(shù)據(jù)庫有就返回罚拟,沒有返回空台诗,并到服務(wù)器上抓取
- (XMPPvCardTemp *)vCardTempForJID:(XMPPJID *)jid shouldFetch:(BOOL)shouldFetch;
//更新自己的名片信息
- (void)updateMyvCardTemp:(XMPPvCardTemp *)vCardTemp;
//獲取到聯(lián)系人的名片信息的回調(diào)
- (void)xmppvCardTempModule:(XMPPvCardTempModule *)vCardTempModule didReceivevCardTemp:(XMPPvCardTemp *)vCardTemp forJID:(XMPPJID *)jid
電子名片的業(yè)務(wù)流程
上面我們對(duì)電子名片進(jìn)行了簡單的介紹,那么接下來我們就SDChat這個(gè)Demo中的電子名片的獲取以及設(shè)置來進(jìn)行業(yè)務(wù)流程說明.流程分為三大部分.(PS:高清圖片過大,請(qǐng)下載再進(jìn)行查看.)
不管是做什么,我們都需要先在SDXmppManager激活對(duì)應(yīng)的模塊.在SDXmppManager我們要聲明三個(gè)屬性,分別是電子名片本地存儲(chǔ)類屬性XMPPvCardCoreDataStorage電子名片讀取存儲(chǔ)屬性XMPPvCardTempModule 以及電子名片的頭像模塊XMPPvCardAvatarModule.
@property(nonatomic,strong)XMPPvCardTempModule *vCardTempModule;
@property(nonatomic,strong)XMPPvCardCoreDataStorage *vCardCoreDataStorage;
@property(nonatomic,strong)XMPPvCardAvatarModule *vCardAvatarModule
然后在SDXmppManager的初始化過程中對(duì)三個(gè)屬性對(duì)象進(jìn)行初始化并且激活電子名片模塊以及頭像模塊.
self.vCardCoreDataStorage = [XMPPvCardCoreDataStorage sharedInstance];
self.vCardTempModule = [[XMPPvCardTempModule alloc]initWithvCardStorage:self.vCardCoreDataStorage];
[self.vCardTempModule activate:self.stream];
[self.vCardTempModule addDelegate:self delegateQueue:dispatch_get_main_queue()];
self.vCardAvatarModule = [[XMPPvCardAvatarModule alloc]initWithvCardTempModule:self.vCardTempModule];
[self.vCardAvatarModule activate:self.stream];
[self.vCardAvatarModule addDelegate:self delegateQueue:dispatch_get_main_queue()];
用戶注冊(cè)過程中的電子名片設(shè)置
用戶在注冊(cè)過程中就可能需要設(shè)置電子名片,我們?cè)赟DXmppManager單例的初始化過程中完成電子名片模塊激活之后,在SDRegisterVC這個(gè)類中,我們注冊(cè)完成之后,在注冊(cè)成功之后,我們?cè)谧?cè)成功的代理方法(-(void)xmppStreamDidRegister:(XMPPStream *)sender
)中登錄注冊(cè)的賬號(hào)密碼(我覺得應(yīng)該可以直接上傳的,但是我怕出現(xiàn)問題,就讓登錄之后在上傳電子名片數(shù)據(jù),大家可以自行測(cè)試).代碼如下所示.
-(void)xmppStreamDidRegister:(XMPPStream *)sender{
[[SDXmppManager defaulManager] loginWithUserName:self.loginName.text AndPassWord:self.passWord.text];
}
當(dāng)?shù)卿洺晒χ?我們?cè)诘卿洺晒Φ拇矸椒?- (void)xmppStreamDidAuthenticate:(XMPPStream *)sender
)中新建一個(gè)XMPPvCardTemp對(duì)象并上傳工作,代碼如下所示.
XMPPvCardTemp *myCard = [XMPPvCardTemp vCardTemp];
myCard.nickname = self.userName.text;
[[SDXmppManager defaulManager].vCardTempModule updateMyvCardTemp:myCard];
同時(shí)彈出頭像設(shè)置頁面跳轉(zhuǎn)的彈窗.
UIAlertController *alertView = [UIAlertController alertControllerWithTitle:@"設(shè)置頭像" message:@"設(shè)置屬于自己的頭像" preferredStyle:UIAlertControllerStyleAlert];
__weak typeof(self)temp = self;
UIAlertAction *action = [UIAlertAction actionWithTitle:@"好的,沒問題" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
[temp.navigationController pushViewController:[SDRegisterHeaderVC new] animated:YES];
}];
[alertView addAction:action];
[self presentViewController:alertView animated:YES completion:nil];
進(jìn)入頭像設(shè)置頁面之后,我們可以默認(rèn)給用戶一張圖片,當(dāng)用戶不進(jìn)行設(shè)置的時(shí)候,默認(rèn)上傳的頭像圖片就是默認(rèn)圖片,這里我就隨意找了一張圖片,然后我們給UIImageView對(duì)象添加一個(gè)輕點(diǎn)手勢(shì).讓用戶點(diǎn)擊圖片的時(shí)候可以切換圖像.
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(clickHeaderView)];
[self.headerView addGestureRecognizer:tap];
self.headerView.userInteractionEnabled = YES;
我們?cè)邳c(diǎn)擊事件中添加打開系統(tǒng)的圖庫以及系統(tǒng)的相機(jī)的方法并且添加代理方法,如果不知道如何打開系統(tǒng)相機(jī)或者相冊(cè),可以查看華山論劍之淺談iOS調(diào)用大亂斗(電話,短信,瀏覽器,相機(jī),相冊(cè)).那么我們就可以通過代理方法來獲取到我們的圖片,代理方法如下所示.
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info;
在代理方法中,我們需要注意一個(gè)問題,如果我們依照華山論劍之淺談iOS調(diào)用大亂斗(電話,短信,瀏覽器,相機(jī),相冊(cè))來獲取圖片的話可能獲取圖片是變形的,我們需要把從info字典中獲取圖片的key值UIImagePickerControllerOriginalImage
換成UIImagePickerControllerEditedImage
;
UIImage* image = [info objectForKey:@"UIImagePickerControllerEditedImage"];
我們把圖片保存在SDRegisterHeaderVC的屬性對(duì)象headerImg當(dāng)中,然后在用戶點(diǎn)擊"完成"時(shí)候,我們就會(huì)調(diào)用SDXmppManager獲取到當(dāng)前登錄賬號(hào)的d電子名片對(duì)象.
XMPPvCardTemp *vCard = [SDXmppManager defaulManager].vCardTempModule.myvCardTemp;
然后我們把進(jìn)行壓縮,修改圖片的尺寸,(注意:??????圖片過大的時(shí)候,可能會(huì)出現(xiàn)圖片上傳失敗的情況,所以我們把它進(jìn)行圖片的修改),這里我提供了一個(gè)圖片修改的方法并且用它對(duì)我們的頭像圖片進(jìn)行了尺寸修改.
- (UIImage *)reSizeImage:(UIImage *)image toSize:(CGSize)reSize{
UIGraphicsBeginImageContext(CGSizeMake(reSize.width, reSize.height));
[image drawInRect:CGRectMake(0, 0, reSize.width, reSize.height)];
UIImage *reSizeImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return reSizeImage;
}
UIImage *headerimage = [self reSizeImage:self.headerImg toSize:CGSizeMake(100, 100)];
修改完圖片的尺寸之后,我們就對(duì)頭像圖片進(jìn)行二級(jí)制文件的文件轉(zhuǎn)換(這里只拿PNG格式圖片作說明,具體還有JPEG格式的,請(qǐng)查看Demo源碼),然后把頭像文件更新到Openfire服務(wù)器中.代碼如下所示.
data = UIImagePNGRepresentation(headerimage);
vCard.photo = data;
[[SDXmppManager defaulManager].vCardTempModule updateMyvCardTemp:vCard];
最后,我們關(guān)閉與服務(wù)器之間的連接,跳轉(zhuǎn)到登錄界面.
[self dismissViewControllerAnimated:YES completion:nil];
[[SDXmppManager defaulManager] disconnectWithServer];
用戶登錄之后電子名片的獲取(過程在SDContactsVC中實(shí)現(xiàn))
上面我們說到如何在用戶的注冊(cè)過程中對(duì)用戶的電子名片進(jìn)行設(shè)置,那么我們?cè)诘卿浲瓿芍笕绾潍@取用戶的頭像,名稱以及好友的用戶頭像,名稱呢?我們先用代理方法來實(shí)現(xiàn)獲取電子名片的方法.
首先,我們需要在聯(lián)系人界面初始化方法中添加電子名片的相關(guān)代理.如下所示.
[[SDXmppManager defaulManager].vCardAvatarModule addDelegate:self delegateQueue:dispatch_get_main_queue()];
[[SDXmppManager defaulManager].vCardTempModule addDelegate:self delegateQueue:dispatch_get_main_queue()];
緊接著,我們?cè)讷@取每一個(gè)好友節(jié)點(diǎn)的代理方法中獲取到好友節(jié)點(diǎn)所對(duì)應(yīng)的JID信息,然后我們使用SDXmppManager中的vCardTempModule調(diào)起- (void)fetchvCardTempForJID:(XMPPJID *)jid ignoreStorage:(BOOL)ignoreStorage
方法就可以調(diào)起代理方法來.代碼如下所示.
[[SDXmppManager defaulManager].vCardTempModule fetchvCardTempForJID:jid ignoreStorage:YES];
然后,我們通過下述代理方法的回調(diào),我們可以獲取到JID以及對(duì)應(yīng)的電子名片信息.
- (void)xmppvCardTempModule:(XMPPvCardTempModule *)vCardTempModule
didReceivevCardTemp:(XMPPvCardTemp *)vCardTemp
forJID:(XMPPJID *)jid
不過,這里不但能獲取到好友的數(shù)據(jù),而且登錄者的電子名片也可以通過這個(gè)代理方法進(jìn)行獲取,所以我們要判斷區(qū)分.如果是登錄者的JID,那么我們把獲取到電子信息名片存儲(chǔ)到SDUser這個(gè)單例當(dāng)中方便其他位置獲取,如果是好友的JID,那么我們就遍歷我們的好友節(jié)點(diǎn)數(shù)組,然后通過比對(duì)JID信息,把對(duì)應(yīng)的電子名片添加到Model中去,然后刷新當(dāng)前的好友列表頁面 .整體的代碼如下所示.
if ([jid.user isEqual:[SDUser defaulUser].jid.user]) {
[SDUser defaulUser].vCard = vCardTemp;
[self.userInformationView reloadAllData];
}else{
for (NSString * key in self.contactsPinyinDic) {
NSMutableArray *array = [NSMutableArray arrayWithArray:self.contactsPinyinDic[key]];
for (SDContactModel *model in array) {
if ([model.jid isEqual:jid]) {
model.vCard =vCardTemp;
}
}
}
//刷新頁面
[self networkingWithContactsArray];
}
上述的是通過代理方法來實(shí)現(xiàn)好友以及登陸者本身的電子名片獲取.下面我們看一下如何通過XMPPvCardTempModule這個(gè)類來進(jìn)行電子名片的獲取.
首先,我們還是在獲取每一個(gè)好友節(jié)點(diǎn)的代理方法中獲取到好友節(jié)點(diǎn)所對(duì)應(yīng)的JID信息,然后我們使用SDXmppManager中的vCardTempModule調(diào)起- (XMPPvCardTemp *)vCardTempForJID:(XMPPJID *)jid shouldFetch:(BOOL)shouldFetch;
這個(gè)方法來.直接獲取到好友本身的電子名片信息,代碼如下所示/
XMPPvCardTemp *vCard = [[SDXmppManager defaulManager].vCardTempModule vCardTempForJID:jid shouldFetch:YES];
那么,我們?nèi)绾沃苯荧@取登陸者本身的電子名片數(shù)據(jù)呢?我們直接使用SDXmppManager就可以直接獲取到登陸者本身電子名片本身.
XMPPvCardTemp *myCard = [SDXmppManager defaulManager].vCardTempModule.myvCardTemp;
NSString *userName = [NSString stringWithFormat:@" 昵稱: %@",myCard.nickname];
NSData *imgData = myCard.photo;
騷棟前期也是直接獲取電子名片數(shù)據(jù)的,不過這樣直接獲取電子名片數(shù)據(jù)是有一定弊端的,那就是獲取服務(wù)器中電子名片數(shù)據(jù)是有一定時(shí)間的,如果在頁面刷新之前還沒有獲取到數(shù)據(jù)的話,那么在頁面上數(shù)據(jù)像是就為空了,所以建議使用代理回調(diào)方法來進(jìn)行好友數(shù)據(jù)的獲取.(SDChat中兩種方法都是有所保留的.)
登錄之后設(shè)置電子名片流程
用戶在登錄之后,跟注冊(cè)過程類似,也是可以設(shè)置對(duì)應(yīng)的電子名片數(shù)據(jù)的.首先我們獲取到登錄者的電子名片,如下所示.
XMPPvCardTemp *myCard = [SDXmppManager defaulManager].vCardTempModule.myvCardTemp;
然后,我們修改電子名片中的屬性.這里拿名稱來舉例說明.
myCard.nickname = textField.text;
最后,我們上傳到服務(wù)器上進(jìn)行更新.
[[SDXmppManager defaulManager].vCardTempModule updateMyvCardTemp:myCard];
不過這里需要注意的是代理方法的回調(diào)問題,我們?nèi)绾沃牢覀兊暮糜岩呀?jīng)進(jìn)行了頭像的更改或者說是電子名片的修改呢?這就需要實(shí)現(xiàn)兩個(gè)代理方法,一個(gè)是我們上面說到獲取到好友節(jié)點(diǎn)的電子名片回調(diào)方法,另外一個(gè)就是獲得好友節(jié)點(diǎn)的頭像更改的代理回調(diào)方法,兩個(gè)方法如下所示.(前提,我們先要在初始化過程中設(shè)置代理)
//獲取到好友節(jié)點(diǎn)的電子名片回調(diào)方法
- (void)xmppvCardTempModule:(XMPPvCardTempModule *)vCardTempModule
didReceivevCardTemp:(XMPPvCardTemp *)vCardTemp
forJID:(XMPPJID *)jid
//獲得好友節(jié)點(diǎn)的頭像更改的代理回調(diào)方法
- (void)xmppvCardAvatarModule:(XMPPvCardAvatarModule *)vCardTempModule
didReceivePhoto:(UIImage *)photo
forJID:(XMPPJID *)jid
在方法中,我們需要區(qū)別處理,我們當(dāng)獲取到登錄者本身的電子名片的修改該怎么辦,我們收到聯(lián)系人中電子名片又該如何操作,需要我們根據(jù)實(shí)際情況來進(jìn)行處理.
好了上述就是電子名片的相關(guān)這是獲取和設(shè)置,當(dāng)我們完成之后,我們就可以等到下面的界面了,相比于只展示JID確實(shí)是美觀了許多呢~~
結(jié)束
上面基本就是XMPPFramework中電子名片的相關(guān)技術(shù)點(diǎn)了,如果任何童鞋有疑問,歡迎提出,騷棟非常歡迎各位童鞋前來交流.下一篇我準(zhǔn)備寫寫XMPPFramework中邏輯最多的好友添加和刪除模塊,希望大家持續(xù)關(guān)注騷棟,謝謝.最后把SDChat的傳送門送給大家.大家可以對(duì)照著Demo來看本篇博客.