iOS XMPP研究探索:添加好友

简介:

公开一个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];
    }
  }
}


目录
相关文章
|
iOS开发
iOS多线程的初步研究-- dispatch同步
GCD提供两种方式支持dispatch队列同步,即dispatch组和信号量。
183 0
|
C# iOS开发
iOS(iPho“.NET研究”ne/iPad)开发新手必读
上海闵行企业网站设计与制作="_blank">Objective-C 入门 一个简单的可以快速上手的 Objective-C 入门教程。 上海网站建设> iOS概述上海徐汇企业网站设计与制作trong> 本文对构成iOS的基础特性提供了高层的概述,帮上海企业网站制作助你了解这个上海徐汇企业网站制作平台。
1089 0
|
iOS开发 MacOS
iOS开发库的族“.NET研究”谱介绍
  Foundation/Core Foundation/Carbon/Cocoa/Cocoa Touch/Toll Free Bridging光看看这tm些名字就jb够晕了,你是不是也看着这些东西恶心?你是不是也发现在你开发同上海闵行企业网站制作样一个功能的时候,从a库也可以到达,从b库也可以到达?虽然都能抓住老鼠,可是到底哪只猫是串儿?哪只猫是纯种的波斯猫?   本文就是对这些库族谱的介绍。
913 0
|
iOS开发
iOS“.NET研究”平台应用开发的敏捷设计流程
  本文翻译自《Computer Arts》中对专注于iPhone和iPad应用开发的设计师Sarah Parmenter的访谈录,希望对iPhone应用开发的朋友能有所帮助。   以下为全部译文:   对设计师来说,iPhone和iPad是全新的平台。
1034 0
|
iOS开发 分布式计算 Spark
|
iOS开发
研究笔记:iOS中使用WebViewProxy拦截URL请求
本文为阿里iOS开发工程师阳翼所作。 先说明下iOS中加载url的正常流程: 1.客户端发送NSURLRequest给server 2.
|
iOS开发 Android开发 HTML5
OpenGL ES 在 iOS 平台纹理贴图倒置的问题研究
OpenGL ES 在 iOS 平台纹理贴图倒置的问题研究 太阳火神的美丽人生 (http://blog.csdn.net/opengl_es) 本文遵循“署名-非商业用途-保持一致”创作公用协议 转载请保留此句:太阳火神的美丽人生 -  本博客专注于 敏捷开发及移动和物联设备研究:iOS、Android、Html5、Arduino、pcDuino,否则,出自本博客的文章拒绝转载或再转载,谢谢合作。
1431 0
|
18天前
|
开发框架 前端开发 Android开发
安卓与iOS开发中的跨平台策略
在移动应用开发的战场上,安卓和iOS两大阵营各据一方。随着技术的演进,跨平台开发框架成为开发者的新宠,旨在实现一次编码、多平台部署的梦想。本文将探讨跨平台开发的优势与挑战,并分享实用的开发技巧,帮助开发者在安卓和iOS的世界中游刃有余。
|
9天前
|
Java 调度 Android开发
安卓与iOS开发中的线程管理差异解析
在移动应用开发的广阔天地中,安卓和iOS两大平台各自拥有独特的魅力。如同东西方文化的差异,它们在处理多线程任务时也展现出不同的哲学。本文将带你穿梭于这两个平台之间,比较它们在线程管理上的核心理念、实现方式及性能考量,助你成为跨平台的编程高手。