公开一个API,提供添加好友功能:
- (void)addBuddyWithJid:(NSString *)jidString completion:(HYBCompletionBlock)completion {
if (![jidString hasSuffix:kServer]) {
jidString = [NSString stringWithFormat:@"%@@%@", jidString, kServer];
}
// 先判断是否已经是我的好友,如果是,就不再添加
if ([_xmppRosterStorage userForJID:[XMPPJID jidWithString:jidString]
xmppStream:_xmppStream
managedObjectContext:[self rosterContext]]) {
if (completion) {
completion(NO, [NSString stringWithFormat:@"%@已经是您的好友!", jidString]);
}
return;
}
self.completionBlock = completion;
// 设置服务器
[_xmppStream setHostName:kServer];
// 发送添加好友请求
/*
presence.type有以下几种状态:
available: 表示处于在线状态(通知好友在线)
unavailable: 表示处于离线状态(通知好友下线)
subscribe: 表示发出添加好友的申请(添加好友请求)
unsubscribe: 表示发出删除好友的申请(删除好友请求)
unsubscribed: 表示拒绝添加对方为好友(拒绝添加对方为好友)
error: 表示presence信息报中包含了一个错误消息。(出错)
*/
[_xmppRoster subscribePresenceToUser:[XMPPJID jidWithString:jidString]];
}
注意:这里添加了是否已经是好友的判断,
[_xmppRosterStorage userForJID:[XMPPJID jidWithString:jidString]
xmppStream:_xmppStream
managedObjectContext:[self rosterContext]])
这个方法是判断用户jid是否已经存在,如果存在,表示已经是我的好友了,如果为nil,表示不存在我的好友列表中,
则可以发送好友添加请求。
节点presence的类型type可以有多种值:
available: 表示处于在线状态(通知好友在线)
unavailable: 表示处于离线状态(通知好友下线)
subscribe: 表示发出添加好友的申请(添加好友请求)
unsubscribe: 表示发出删除好友的申请(删除好友请求)
unsubscribed: 表示拒绝添加对方为好友(拒绝添加对方为好友)
error: 表示presence信息报中包含了一个错误消息。(出错)
// 加好友回调函数
/*
presence.type有以下几种状态:
available: 表示处于在线状态(通知好友在线)
unavailable: 表示处于离线状态(通知好友下线)
subscribe: 表示发出添加好友的申请(添加好友请求)
unsubscribe: 表示发出删除好友的申请(删除好友请求)
unsubscribed: 表示拒绝添加对方为好友(拒绝添加对方为好友)
error: 表示presence信息报中包含了一个错误消息。(出错)
*/
- (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"]) { // 请求删除好友
}
}
}
// 添加好友同意后,会进入到此代理
- (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);
}
}
}
/**
* Sent when the roster receives a roster item.
*
* Example:
*
* <item jid='romeo@example.net' name='Romeo' subscription='both'>
* <group>Friends</group>
* </item>
**/
// 已经互为好友以后,会回调此
- (void)xmppRoster:(XMPPRoster *)sender didReceiveRosterItem:(NSXMLElement *)item {
NSString *subscription = [item attributeStringValueForName:@"subscription"];
if ([subscription isEqualToString:@"both"]) {
NSLog(@"双方已经互为好友");
if (self.buddyListBlock) {
// 更新好友列表
[self fetchBuddyListWithCompletion:self.buddyListBlock];
}
}
}