XMPPFramework开发(五):添加/删除好友

111396375-9db55c83806e2430

前言


前面几篇文章我们主要搞了搞关于好友列表的相关技术以及逻辑,还有用户上下线监控这个没说,我准备放到最后再说,比较简单,今天我们就说一下关于添加好友和删除好友的逻辑和技术.添加好友的逻辑比较多.

121396375-4a0c7c28bf8dfd44

添加好友

XMPP好友关系


在前面的好友列表中,我们也设定当两个JID相互订阅才认定两者是好友关系,那么为什么要这么设定呢?其实主要是因为添加好友的缘故,这文章的后面我会具体的说到,我们看一下两个JID账号都有什么订阅关系.总共有五种订阅关系.分别是NoneToFromBothRemove;五种定影状态楚翔的情况如下表所示.

订阅状态 情况出现情景
None 当A订阅了B之后,B并没有订阅A的时候,A中的B的订阅状态就为None
ToFrom 当A订阅了B之后,B上线之后同意之后,A中B的订阅状态就为To,B中A的订阅状态就为From
Both 当A订阅了B之后,B也在线同意了A的订阅请求,那么A中B的订阅状态就为Both
Remove 当A删除B之前,在B中的定义状态就为Remove

 

XMPPFramework中添加/删除好友相关的方法


XMPPFramework的好友管理类是XMPPRoster,下面我们就看一下我们所需要的方法以及代理回调方法.

 

XMPPFramework 中添加好友的流程


骚栋在SDChat中采用的是先发送订阅的消息,如果被拒绝再删除好友的整体逻辑.所以我们需要先看一下逻辑的流程图.流程图我把它分成两种情况区别对待,如下所示.

  • 第一种是用户A向用户B发送订阅请求,用户B同意A的订阅请求.

    131396375-9b195d75f6458047

  • 第二种是用户A向用户B发送订阅请求,用户B拒绝了A的订阅请求.

    141396375-6894f59af97ce5b7

上面我们看到了用户的好友添加的流程图,下面我们就对着SDChat中的代码来具体看一下我们的流程.当然了,这个过程是需要两个用户来完成的,所以,我们假设有用户A和用户B两个用户.

用户A: 在SDAddContactVC这个类中输入用户B的账号,我们通过组装,然后使用XMPPRoster类中的- (void)subscribePresenceToUser:(XMPPJID *)jid方法向用户B发送订阅请求.

用户B:当用户A发出好友请求的时候,如果用户B不在线,那么用户A中好友列表的用户B的订阅状态就为To,用户B上线之后仍然会受到订阅消息;如果用户B当前在线,那么用户B会通过AppDelegate中的- (void)xmppRoster:(XMPPRoster *)sender didReceivePresenceSubscription Request:(XMPPPresence *)presence这个代理方法获取到好友订阅的消息.由于一个好友请求可能发送多次,但是我们只需要提取其中一次就好,这样我们就需要判断从服务器来的好友订阅消息在SDUser中的addFriendArray数组中是否已经存在,如果不存在,那么我们将添加到数组中,并且发出一个通知,通知各个界面做出对应的改变.给用户一个直观的视觉体验.具体代码如下所示.

用户B:如果用户B当前在SDContactsVC联系人列表页面中,那么通过通知,我们刷新了页面.用户B可以直接通过页面来知道有新的好友请求消息.在这里为了防止内存的不必要的损耗,我们先判断一下当前的列表显示的cell是否在有”新的朋友”这一个Cell,如果有才进行刷新,没有的话,用户B在往上滑动到最顶端的时候回自动刷新.具体代码如下所示.

用户B:如果用户B在SDAddContactVC好友添加页面,那么通过App的好友通知,我们刷新了页面,用户B看到了当前的好友请求.如下图所示.

151396375-13049a3ed21e3a1e

那么接下来还是要分用户B同意好友添加和用户B拒绝好友添加两种情况了.

 

第一种是用户A向用户B发送订阅请求,用户B同意A的订阅请求.

用户B: 用户B点击了好友同意,那么通过调用- (void)acceptPresenceSubscriptionRequest From:(XMPPJID *)jid andAddToRoster:(BOOL)flag这个方法,用户B就添加了用户A,这时候用户A和B的关系为Both或者是To-From的关系,认定两者是好友关系,代码如下所示.

然后,我们需要把SDUser中addFriendArray的对应的JID删除掉,并且刷新页面通知用户,已经操作成功了.代码如下所示.

用户A: 如果用户B添加成功之后,那么用户A在好友列表中刷新页面就会获取到用户B了,至此,用户A成功的添加了用户B的好友.

 

第二种是用户A向用户B发送订阅请求,用户B拒绝了A的订阅请求.

用户B:用户B收到好友请求消息的时候,用户B点击”拒绝”,然后我们会调用- (void) rejectPresenceSubscriptionRequestFrom:(XMPPJID *)jid这个方法,我们想用户A发送拒绝的消息.同时要删除好友列表中用户A,有人会问用户A与B现在不是还没有好友关系吗?为什么用户B的好友列表中会有A?原因是这样的,当用户A发送好友请求的时候,用户B的列表就有了用户A,不过订阅状态却是None,这时候,我们需要删除好友A.代码如下所示.

用户B:于此同时,我们还要删除本地中的好友请求数组中对应的数据.然后刷新页面,如下所示.

用户A:当用户B拒绝了好友请求的时候,用户A通过AppDelegate中的- (void)xmppStream:(XMPPStream *)sender didReceivePresence:(XMPPPresence *)presence方法可以获取到用户B拒绝的消息,然后把用户A好友列表中的用户B删除掉.当然了,这个代理方法另外一个作用就是获取好友上下线状态,所以消息类型较多,我们需要判断一下消息类型,然后酌情处理.具体代码如下所示.

 

XMPPFramework 中删除好友的流程


在SDChat中,用户是可以删除好友的,那就是联系人列表左滑菜单会出现删除按钮,如图所示.

161396375-4a5ab4c30ab625b5

那么逻辑实现也是比较简单,但是还是需要两个用户,这里,我们仍然假设有用户A和用户B,现在两者互为好友关系.

用户A :用户A在用户B所对应的Cell上左滑,然后出现删除按钮,用户A点击删除,就会调用如下的方法,删除好友,这里需要注意的一点就是,这是说的是直接删除好友,而不是取消订阅.具体代码如下所示.

用户A :当上面这句代码执行完成之后,获取每一个好友节点的代理方法-(void)xmppRoster:(XMPPRoster *)sender didReceiveRosterItem:(DDXMLElement *)item就会重洗执行一遍,这时候,用户A好友列表中用户B的订阅状态为”Remove”;所以我们要做的是在代理方法中删除本地数据并且刷新页面,代码如下所示.

用户B :用户A虽然删除了用户B,但是用户B好友列表中含有用户A.所以,当用户A删除了用户B之后,用户B通过AppDelegate中的- (void)xmppStream:(XMPPStream *)sender didReceivePresence:(XMPPPresence *)presence方法可以获取到用户B拒绝的消息,然后把用户B好友列表中的用户A删除掉.这个其实添加好友的拒绝好友添加情况的最后一步是一致的.具体代码如下所示.

经过上述的步骤,用户A和用户B就相互解除了好友关系了.

 

SDChat好友添加存在问题(下述问题已于12.21号解决)


现在的SDChat基本上好友添加这一模块逻辑上没有太大的问题,就是一些限制条件还没做,比如限制不能添加自己为好友,比如对方已经请求添加好友了,但是你也请求添加对方为好友,这样两者直接就是为好友关系.逻辑上可能出现问题.再比如优化问题,通过JID并不能很好展现一个联系人的信息,如果我们通过JID获取好友请求人的电子名片是不是能更人性化一些呢,等等.SDChat并不是完美的,所以如果遇到任何问题,可以联系骚栋.谢谢.

161396375-0fb0aa7564dc5d55

结束


XMPPFramework的添加/删除好友到这里就基本结束了,骚栋在搞添加/删除好友这个模块的时候,因为不太了解XMPPFramework中各种方法,所以坑填了比较多,当然了,自己测试的过程中也可能遇到很多坑点,如果有任何疑问欢迎联系骚栋.接下来一篇,我们说一下XMPPFramework的核心模块单人聊天模块,比较简单,希望大家能持续关注.谢谢.最后还把SDChat的传送门送给大家.大家可以对照着Demo来看本篇博客.

–>SDChat传送门🚪

1 收藏 评论

相关文章

可能感兴趣的话题



直接登录
跳到底部
返回顶部