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"]) { // 请求删除好友
}
}
}
但是在这个方法中处理的话,还是会调用上一个方法,因此我觉得还是在前一个方法中处理更好些。