仿微信/QQ 开发基于XMPP的iPhone/iOS聊天客户端(一)好友资料

来源:互联网 发布:悟道红包软件 编辑:程序博客网 时间:2024/05/18 02:17

其实,网上基于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就进入好友详细信息页,我们可以在加入以下代码


- (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的信息读出来


    XMPPvCardCoreDataStorage *xmppvCardStorage = [XMPPvCardCoreDataStorage sharedInstance];    XMPPvCardTempModule *xmppvCardTempModule = [[XMPPvCardTempModule alloc] initWithvCardStorage:xmppvCardStorage];    XMPPvCardTemp *xmppvCardTemp =[xmppvCardTempModule vCardTempForJID:jid  shouldFetch:YES];

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


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


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

@property (nonatomic, strong) NSString *sex;@property (nonatomic, strong) NSString *email;@property (nonatomic, strong) NSString *birthDay;

在.m文件加上

- (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,是不是出来了?


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

<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,可以这样

    xmppvCardTemp.url=@"csdn.net";    [self updatePhoto];    [xmppvCardTempModule updateMyvCardTemp:xmppvCardTemp];

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

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

好吧,夜深了,今天先讲到这,下回继续。如有问题,欢迎大家留言!


0 0