上一篇讲到成功登陆,然后跳转到RosterController好友列表,所以这次主要围绕获取好友列表,以及添加好友!
之前讲过消息通知机制,当RosterConrtroller被通知时,判断是否登陆成功并在线,如果成功,则寻找帐号好友
<span style="font-size:14px;">-(void)onlineNotification:(NSNotification*)notification{
BOOL signin=[notification.object boolValue];
if (signin){
NSLog(@"Roster_queryRosterList");
[[AbilityRoster sharedRoster] queryRosterList];</span><span style="font-size:18px;">//寻找此账号的好友!!
</span><span style="font-size:14px;"> }
else{
NSLog(@"LoginViewController");
LoginViewController* loginVC=[[LoginViewController alloc]init];
[self presentViewController:loginVC animated:YES completion:^{
}];
}
}</span>
在AbilityRoster类queryRosterList方法
<span style="font-size:14px;">-(void)queryRosterList{
NSLog(@"queryRosterList");
XMPPIQ* iq=[XMPPIQ iqWithType:@"get"];
NSLog(@"%@",[AbilityManage sharedManager].jid);
[iq addAttributeWithName:@"from" stringValue:[AbilityManage sharedManager].jid];
[iq addAttributeWithName:@"id" stringValue:@"roster-1"];
NSXMLElement* element_query=[NSXMLElement elementWithName:@"query" xmlns:@"jabber:iq:roster"];
[iq addChild:element_query];
[[AbilityManage sharedManager].xmppStream sendElement:iq];
}</span>
好友列表,在 XMPP 中被称为 roster,花名册
获取 roster 需要客户端发送 <iq /> 标签向 XMPP 服务器端查询
一个 IQ 请求:
<iq type="get"
from="xiaoming@example.com"
to="example.com"
id="1234567">
<query xmlns="jabber:iq:roster"/>
<iq />
type 属性,说明了该 iq 的类型为 get,与 HTTP 类似,向服务器端请求信息
from 属性,消息来源,这里是你的 JID
to 属性,消息目标,这里是服务器域名
id 属性,标记该请求 ID,当服务器处理完毕请求 get 类型的 iq 后,响应的 result 类型 iq 的 ID 与 请求 iq 的 ID 相同
<query xmlns="jabber:iq:roster"/> 子标签,说明了客户端需要查询 roster
发送请求后,服务器会传来数据,这个时候会调用XMPP代理-(BOOL)xmppStream:(XMPPStream *)sender didReceiveIQ:(XMPPIQ *)iq
一个 IQ 响应:
<iq type="result"
id="1234567"
to="xiaoming@example.com">
<query xmlns="jabber:iq:roster">
<item jid="xiaoyan@example.com" name="小燕" />
<item jid="xiaoqiang@example.com" name="小强"/>
<query />
<iq />
type 属性,说明了该 iq 的类型为 result,查询的结果
<query xmlns="jabber:iq:roster"/> 标签的子标签 <item />,为查询的子项,即为 roster
item 标签的属性,包含好友的 JID,和其它可选的属性,例如昵称等。我们还需要把获取到的好友存储到可变数组memberList
<span style="font-size:14px;">-(BOOL)xmppStream:(XMPPStream *)sender didReceiveIQ:(XMPPIQ *)iq{
NSLog(@"didReceiveIQ");
if ([@"result" isEqualToString:iq.type]) {
NSXMLElement *query = iq.childElement;
if ([@"query" isEqualToString:query.name]) {
NSArray *items = [query children];
for (NSXMLElement *item in items) {
friend_class *member=[[friend_class alloc]initWithRosterElement:item];
NSLog(@"%@",member.name);
[self updateMember:member];//更新成员
}
}
[[NSNotificationCenter defaultCenter] postNotificationName:update_noti object:nil];
}
return YES;
}</span>
-(friend_class*)updateMember:(friend_class*)member{
//已经存在
if (!self.memberList[member.jid]){
self.memberList[member.jid]=member;
[[NSNotificationCenter defaultCenter] postNotificationName:update_noti object:member];
return member;
}
//还没有存在
else{
friend_class* updateMember=self.memberList[member.jid];
if (member.name){
updateMember.name=member.name;
}
[[NSNotificationCenter defaultCenter] postNotificationName:update_noti object:updateMember];
return updateMember;
}
}
方法的最后都会使用通知
<span style="font-size:14px;">-(void)updateRosterNotification:(NSNotification*)notification{
if(notification.object){
NSLog(@"updateRoster");
[self.tableView reloadData];}
}</span>
UIBarButtonItem *addfriend=[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(AddFriends)];
self.navigationItem.rightBarButtonItem=addfriend;
-(void)AddFriends{//跳转到添加好友的界面
AddFriendController *AFC=[[AddFriendController alloc] init];
UINavigationController* naVC=[[UINavigationController alloc]initWithRootViewController:AFC];
[self presentViewController:naVC animated:YES completion:^{}];
}
AddFriendController控制器比较简单两个输入框,两个按钮,分别是返回和添加
在AddFriendController的ViewLoad
添加了一个取消按钮,确定添加按钮,一个jid的输入框,一个用户名的输入框,
//left right button
self.navigationItem.leftBarButtonItem=[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:@selector(buttonCancel:)];
self.navigationItem.rightBarButtonItem=[[UIBarButtonItem alloc] initWithTitle:@"添加" style:UIBarButtonItemStyleDone target:self action:@selector(buttonAdd:)];
self.navigationItem.title=@"添加好友";
UIColor* textBackgroundColor=[UIColor colorWithRed:0.0f green:0.0f blue:0.0f alpha:0.05f];
if (!_JIDtext) {
_JIDtext=[[UITextField alloc] initWithFrame:CGRectMake(UIwidth/2-75,100, 150, 20)];
_JIDtext.backgroundColor=textBackgroundColor;
_JIDtext.placeholder=@"输入对方ID";
_JIDtext.keyboardType=UIKeyboardTypeEmailAddress;
[self.view addSubview:_JIDtext];
}
if (!_Nametext) {
_Nametext=[[UITextField alloc]initWithFrame:CGRectMake(UIwidth/2-75,130 ,150 ,20 )];
_Nametext.backgroundColor=textBackgroundColor;
_Nametext.placeholder=@"请给对方起个昵称";
_Nametext.keyboardType=UIKeyboardTypeDefault;
[self.view addSubview:_Nametext];
}
if (!_notice) {
_notice=[[UILabel alloc]initWithFrame:CGRectMake(UIwidth/2-100, 160, 200, 20)];
[self.view addSubview:_notice];
}
取消按钮
-(void)buttonCancel:(UIButton *)sender{
[self dismissViewControllerAnimated:YES completion:^{}];
}
确定添加
<span style="font-size:14px;">-(void)buttonAdd:(UIButton *)sender{
NSString *jid=_JIDtext.text;
NSString *name=_Nametext.text;
if (jid&&name) {
_notice.text=@"success";
[[AbilityRoster sharedRoster] addfriendToJid:jid name:name];
[self dismissViewControllerAnimated:YES completion:^{}];
}
else{
_notice.text=@"不能为空!!";
}
}</span>
<span style="font-size:14px;">#pragma mark subscribe
-(void)addfriendToJid:(NSString *)jid name:(NSString *)name{
if ([jid rangeOfString:@"@"].location==NSNotFound){
//判断没有@
jid=[NSString stringWithFormat:@"%@@%@",jid,[AbilityManage sharedManager].host];
}
///add member
XMPPIQ* iq=[XMPPIQ iqWithType:@"set"];
[iq addAttributeWithName:@"id" stringValue:@"abc-1"];
NSXMLElement* elemnt_query=[NSXMLElement elementWithName:@"query" xmlns:@"jabber:iq:roster"];
[iq addChild:elemnt_query];
NSXMLElement* element_item=[NSXMLElement elementWithName:@"item"];
[element_item addAttributeWithName:@"jid" stringValue:jid];
[element_item addAttributeWithName:@"name" stringValue:name];
[elemnt_query addChild:element_item];
NSXMLElement* element_group=[NSXMLElement elementWithName:@"group" stringValue:@"Friends"];
[element_item addChild:element_group];
[[AbilityManage sharedManager].xmppStream sendElement:iq];
///Presence
XMPPPresence* presence=[[XMPPPresence alloc]initWithType:@"subscribe" to:[XMPPJID jidWithString:jid]];
[presence addAttributeWithName:@"id" stringValue:@"abc-2"];
[[AbilityManage sharedManager].xmppStream sendElement:presence];
}</span>