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

ios xmpp研究探索:删除好友

2015-03-24 22:32 204 查看
XMPP中删除好友,就是发送一个presence,其类型为:unsubscribe

- (void)removeBuddyWithJid:(NSString *)jidString completion:(HYBCompletionBlock)completion {
  if (![jidString hasSuffix:kServer]) {
    jidString = [NSString stringWithFormat:@"%@@%@", jidString, kServer];
  }
  
  self.completionBlock = completion;
  
  // 设置服务器
  [_xmppStream setHostName:kServer];

  // 发送移除好友请求
  [_xmppRoster removeUser:[XMPPJID jidWithString:jidString]];
  // 如果用下面的方法来移除,则需要在移除后,手动调用从数据库中移除,否则会有问题
 // [_xmppRoster unsubscribePresenceFromUser:[XMPPJID jidWithString:jidString]];
}


发出删除好友请求后,会先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,和其它可选的属性,例如昵称等。
 */
- (BOOL)xmppStream:(XMPPStream *)sender didReceiveIQ:(XMPPIQ *)iq {
  NSLog(@"xmpp stream 接收到查询消息:%@", [iq XMLString]);
  
  // 获取好友列表结果
  if ([iq.type isEqualToString:@"result"]) {
    NSXMLElement *query = [iq elementForName:@"query"];
    // 如果是注册,from和to都不为空,如果是删除,且待删除的用户在服务器中并没有,那么就没有from和to
    if ([iq attributeStringValueForName:@"from"] && [iq attributeStringValueForName:@"to"]) {
      return YES;
    }
    
    if (query == nil) { // 用户不存在,直接从数据库删除即可
      if (self.completionBlock && !_isLogining && !_isRegistering) {
        self.completionBlock(YES, nil);
      }
      return YES;
    }
    // 这种方式是通过手动发送IQ来查询好友列表的,不过这样操作不如使用XMPP自带的coredata操作方便
//    NSString *thdID = [NSString stringWithFormat:@"%@", [iq attributeStringValueForName:@"id"] ];
//    if ([thdID isEqualToString:kFetchBuddyListQueryID]) {
//      NSXMLElement *query = [iq elementForName:@"query"];
//      
//      NSMutableArray *result = [[NSMutableArray alloc] init];
//      for (NSXMLElement *item in query.children) {
//        NSString *jid = [item attributeStringValueForName:@"jid"];
//        NSString *name = [item attributeStringValueForName:@"name"];
//        
//        HYBBuddyModel *model = [[HYBBuddyModel alloc] init];
//        model.jid = jid;
//        model.name = name;
//        
//        [result addObject:model];
//      }
//      
//      if (self.buddyListBlock) {
//        self.buddyListBlock(result, nil);
//      }
//      
//      return YES;
//    }
  }
  // 删除好友需要先查询,所以会进入到此代理回调函数中,如果type=@"set",
  // 说明是更新操作,即删除好友或者添加好友查询
  else if ([iq.type isEqualToString:@"set"] && !_isRegistering && !_isLogining) {
    NSXMLElement *query = [iq elementForName:@"query"];
    for (NSXMLElement *item in query.children) {
      NSString *ask = [item attributeStringValueForName:@"ask"];
      NSString *subscription = [item attributeStringValueForName:@"subscription"];
      if ([ask isEqualToString:@"unsubscribe"] && ![subscription isEqualToString:@"none"]) { // 删除好友成功
        if (self.completionBlock) {
          self.completionBlock(YES, nil);
        }
        return YES;
      }
      // 请求添加好友,但是查询没有结果,表示用户不存在
      // none表示未确认
      else if ([ask isEqualToString:@"subscribe"] && [subscription isEqualToString:@"none"]) {
        if (self.completionBlock) {
          self.completionBlock(YES, @"发送添加好友请求成功");
        }
        return YES;
      } else if (![subscription isEqualToString:@"none"]) { // 添加好友请求,查询成功
        return YES;
      }
    }
  }
  
  return NO;
}


删除好友成功后:

// 添加好友同意后,会进入到此代理
- (void)xmppRoster:(XMPPRoster *)sender didReceiveRosterPush:(XMPPIQ *)iq {
  NSLog(@"添加成功!!!didReceiveRosterPush -> :%@",iq.description);
  
  DDXMLElement *query = [iq elementsForName:@"query"][0];
  DDXMLElement *item = [query elementsForName:@"item"][0];
  
  NSString *subscription = [[item attributeForName:@"subscription"] stringValue];
  // 对方请求添加我为好友且我已同意
  if ([subscription isEqualToString:@"from"]) {// 对方关注我
    NSLog(@"我已同意对方添加我为好友的请求");
  }
  // 我成功添加对方为好友
  else if ([subscription isEqualToString:@"to"]) {// 我关注对方
    NSLog(@"我成功添加对方为好友,即对方已经同意我添加好友的请求");
  } else if ([subscription isEqualToString:@"remove"]) {
    // 删除好友
    if (self.completionBlock) {
      self.completionBlock(YES, nil);
    }
  }
}


当然也可以在这里处理:
- (void)xmppRoster:(XMPPRoster *)sender didReceivePresenceSubscriptionRequest:(XMPPPresence *)presence {
  NSLog(@"接收到好友申请消息:%@", [presence fromStr]);
  // 好友在线状态
  NSString *type = [presence type];
  // 发送请求者
  NSString *fromUser = [[presence from] user];
  // 接收者id
  NSString *user = _xmppStream.myJID.user;
  
  NSLog(@"接收到好友请求状态:%@   发送者:%@  接收者:%@", type, fromUser, user);
  
  // 防止自己添加自己为好友
  if (![fromUser isEqualToString:user]) {
    if ([type isEqualToString:@"subscribe"]) { // 添加好友
      // 接受添加好友请求,发送type=@"subscribed"表示已经同意添加好友请求并添加到好友花名册中
      [_xmppRoster acceptPresenceSubscriptionRequestFrom:[XMPPJID jidWithString:fromUser]
                                          andAddToRoster:YES];
      NSLog(@"已经添加对方为好友,这里就没有弹出让用户选择是否同意,自动同意了");
    } else if ([type isEqualToString:@"unsubscribe"]) { // 请求删除好友
      
    }
  }
}


但是在这个方法中处理的话,还是会调用上一个方法,因此我觉得还是在前一个方法中处理更好些。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: