您的位置:首页 > 移动开发 > IOS开发

IOS XMPP 聊天客户端

2014-09-18 09:10 169 查看
原文地址

其实,网上基于XMPP的iOS聊天客户端例子已经很多了,大多数是基于XMPPFramework进行二次开发的,小弟的也不例外,那为啥要有这篇教程呢?

因为目前网上的教程,大多数只有一个主体功能的实现,一些细节方面不完善,或者没说到。小弟在制作的过程中吃了不少苦头,为了以后的兄弟少走弯路,希望在这里可以跟大家多多交流。PS:小弟iOS开发时间不长,如有错误请大家不吝指教。

声明一下,此教程主要是针对原生Openfire提供的XMPP支持来做的,暂不考虑在服务器端增加任何自编写插件实现扩展功能。当然,在这个系列的完结后,我会开一个系列粗述关于插件的开发,这是后话。我在这里要做的,是手把手跟大家一起做一个达到上线标准的聊天程序客户端,也就是各种细节功能都实现(包括表情、语音、图片等收发)!

入正题,安装Openfire,配置等等的,小弟就不再详述了。一些基本的知识,请大家参考一下这些大大的系列文章
http://blog.csdn.net/acorld/article/category/1584273 http://www.cnblogs.com/dyingbleed/category/467219.html
当把XMPPFramework引入到自己新建的项目时,它原本已经实现了登录和查看好友列表的功能。好,我们可以加上在列表中查看该好友的详细信息。XMPP保存好友的详细信息是使用vCard的,所以,假设点击好友列表中的cell就进入好友详细信息页,我们可以在加入以下代码

[objc] view
plaincopy





- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath

{

XMPPUserCoreDataStorageObject *user = [[self fetchedResultsController] objectAtIndexPath:indexPath];

ChatViewController *controller=[[ChatViewController alloc] init];

controller.jidStr=user.jidStr;

[self.navigationController pushViewController:controller animated:YES];

}

我们暂时用ChatViewController来存放好友信息。

在这里,我们把vCard的信息读出来

[objc] view
plaincopy





XMPPvCardCoreDataStorage *xmppvCardStorage = [XMPPvCardCoreDataStorage sharedInstance];

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

XMPPvCardTemp *xmppvCardTemp =[xmppvCardTempModule vCardTempForJID:jid shouldFetch:YES];

然后xmppvcardTemp.nickname就是昵称,如此类推。

等等,为何性别、email、生日等的无法获取呢?

XMPPFramework不知道为什么少了这部分内容的解析,在XMPPvCardTemp.h加上

[objc] view
plaincopy





@property (nonatomic, strong) NSString *sex;

@property (nonatomic, strong) NSString *email;

@property (nonatomic, strong) NSString *birthDay;

在.m文件加上

[objc] view
plaincopy





- (NSString *)sex {

return [[self elementForName:@"SEX"] stringValue];

}

- (void)setSex:(NSString *)sex {

XMPP_VCARD_SET_STRING_CHILD(sex, @"SEX");

}

- (NSString *)email {

return [[self elementForName:@"EMAIL"] stringValue];

}

- (void)setEmail:(NSString *)email {

XMPP_VCARD_SET_STRING_CHILD(email, @"EMAIL");

}

- (NSString *)birthDay {

return [[self elementForName:@"BDAY"] stringValue];

}

- (void)setBirthDay:(NSString *)birthDay {

XMPP_VCARD_SET_STRING_CHILD(birthDay, @"BDAY");

}

嘿,看看xmppvcardTemp.sex,是不是出来了?

至于其他的节点可能还有漏的,可以参照这个完整节点

[html] view
plaincopy





<iq from='juliet@capulet.com'

to='romeo@montague.net/orchard'

type='result'

id='vc2'>

<vCard xmlns='vcard-temp'>

<BDAY>1476-06-09</BDAY>

<ADR>

<CTRY>Italy</CTRY>

<LOCALITY>Verona</LOCALITY>

<HOME/>

</ADR>

<NICKNAME/>

<N><GIVEN>Juliet</GIVEN><FAMILY>Capulet</FAMILY></N>

<EMAIL>jcapulet@shakespeare.lit</EMAIL>

<PHOTO>

<TYPE>image/jpeg</TYPE>

<BINVAL>

Base64-encoded-avatar-file-here!

</BINVAL>

</PHOTO>

</vCard>

</iq>

看看你想要用哪个节点,如此类推加上就可。

好了,如何进行资料修改?这个很简单,例如我要修改url,可以这样

[objc] view
plaincopy





xmppvCardTemp.url=@"csdn.net";

[self updatePhoto];

[xmppvCardTempModule updateMyvCardTemp:xmppvCardTemp];

嗯,当然还有头像修改啦,模拟一个IQ发过去就可以了

[objc] view
plaincopy





NSXMLElement *vCardXML = [NSXMLElement elementWithName:@"vCard" xmlns:

@"vcard-temp"];

NSXMLElement *photoXML = [NSXMLElement elementWithName:@"PHOTO"];

NSXMLElement *typeXML = [NSXMLElement elementWithName:@"TYPE"

stringValue:@"image/jpeg"];

UIImage *image=[UIImage imageNamed:@"DefaultPerson.png"];

NSData *dataFromImage =UIImagePNGRepresentation(image);

//UIImageJPEGRepresentation(image, 0.7f);

NSXMLElement *binvalXML = [NSXMLElement elementWithName:@"BINVAL"

stringValue:[dataFromImage base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength]];

[photoXML addChild:typeXML];

[photoXML addChild:binvalXML];

[vCardXML addChild:photoXML];

XMPPvCardTemp *myvCardTemp = [[[self appDelegate] xmppvCardTempModule]

myvCardTemp];

if (myvCardTemp) {

[myvCardTemp setPhoto:dataFromImage];

[[[self appDelegate] xmppvCardTempModule] updateMyvCardTemp

:myvCardTemp];

}

else{

XMPPvCardTemp *newvCardTemp = [XMPPvCardTemp vCardTempFromElement

:vCardXML];

[[[self appDelegate] xmppvCardTempModule] updateMyvCardTemp

:newvCardTemp];

}

好吧,夜深了,今天先讲到这,下回继续。如有问题,欢迎大家留言!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: