iOS(五)基于XMPP协议的聊天App:二

上一篇讲到成功登陆,然后跳转到RosterController好友列表,所以这次主要围绕获取好友列表,以及添加好友!

iOS(五)基于XMPP协议的聊天App:二_第1张图片

之前讲过消息通知机制,当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="[email protected]"

  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="[email protected]">

  <query xmlns="jabber:iq:roster">

    <item jid="[email protected]" name="小燕" />

    <item jid="[email protected]" 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>


添加好友是需要点击了添加的按钮才能跳转的,所以在ViewLoad

 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控制器比较简单两个输入框,两个按钮,分别是返回和添加

iOS(五)基于XMPP协议的聊天App:二_第2张图片


在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>












你可能感兴趣的:(iOS(五)基于XMPP协议的聊天App:二)