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

其实,网上基于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
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值