Skip to content

Commit 65a8765

Browse files
committed
no message
1 parent be5f553 commit 65a8765

File tree

1 file changed

+98
-5
lines changed

1 file changed

+98
-5
lines changed

XMPP系列教程4-好友列表.md

Lines changed: 98 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
# XMPP获取好友列表
22

3-
## 报文格式
3+
本篇文章主要是介绍如何获取好友列表, 包括客户端的请求和服务器返回的数据.
4+
关于XMPP的好友协议, 可以参考[RFC3921](http://wiki.jabbercn.org/RFC3921)
5+
6+
## 获取好友列表报文格式
47

58
### 发送的报文
69

@@ -77,6 +80,9 @@ XMPPRoster类继承自XMPPModule,主要用于处理Roster相关的网络请求
7780
//设置xmppStream, 并将 _xmppRoster添加到 _xmppStream 的广播中
7881
[_xmppRoster activate:_xmppStream];
7982

83+
//将 self 添加到广播队列中
84+
[_xmppRoster addDelegate:self delegateQueue:_xmppQueue]
85+
8086
至此, XMPPRoster 对象初始化完成
8187

8288
### XMPPRoster如何自动获取好友列表?
@@ -112,7 +118,14 @@ XMPPStream 登录成功后, 会发送 xmppStreamDidAuthenticate 广播, XMPPRost
112118
...
113119
}
114120

115-
上面的代码, 其实只是构造了如下的一个XML报文发送出去到服务器(注意看这里的xmlns是 jabber:iq:roster):
121+
上面的代码, 添加了一个element到 xmppIDTracker对象中, 用于处理请求超时以及服务器正常返回数据时的操作, 如下代码:
122+
123+
[xmppIDTracker addElement:iq
124+
target:self
125+
selector:@selector(handleFetchRosterQueryIQ:withInfo:)
126+
timeout:60];
127+
128+
同时构造了如下的一个XML报文发送出去到服务器(注意看这里的xmlns是 jabber:iq:roster):
116129

117130
<iq id="5nKV7-6" type="get"><query xmlns="jabber:iq:roster"></query></iq>
118131

@@ -152,8 +165,88 @@ XMPPRoster解析报文(从服务器返回的报文能看出来,服务器返回
152165
return NO;
153166
}
154167

155-
从服务器返回的报文来看, XMPPRoster应该会走如下方法:
168+
服务器返回roster列表时, 执行了 [xmppIDTracker invokeForElement:iq withObject:iq]; 方法, 根据上一节XMPPIDTracker的介绍, 该方法会调用 handleFetchRosterQueryIQ:withInfo: 方法, 如下:
156169

157-
[xmppIDTracker invokeForElement:iq withObject:iq];
170+
- (void)handleFetchRosterQueryIQ:(XMPPIQ *)iq withInfo:(XMPPBasicTrackingInfo *)basicTrackingInfo{
171+
172+
dispatch_block_t block = ^{ @autoreleasepool {
173+
174+
NSXMLElement *query = [iq elementForName:@"query" xmlns:@"jabber:iq:roster"];
175+
176+
BOOL hasRoster = [self hasRoster];
177+
178+
//如果之前未获取过好友列表, 则发送的广播
179+
if (!hasRoster)
180+
{
181+
[xmppRosterStorage clearAllUsersAndResourcesForXMPPStream:xmppStream];
182+
[self _setPopulatingRoster:YES];
183+
184+
//发送一个 xmppRosterDidBeginPopulating 广播
185+
[multicastDelegate xmppRosterDidBeginPopulating:self];
186+
[xmppRosterStorage beginRosterPopulationForXMPPStream:xmppStream];
187+
}
188+
189+
NSArray *items = [query elementsForName:@"item"];
190+
[self _addRosterItems:items];
191+
192+
if (!hasRoster)
193+
{
194+
// We should have our roster now
195+
196+
[self _setHasRoster:YES];
197+
[self _setPopulatingRoster:NO];
198+
[multicastDelegate xmppRosterDidEndPopulating:self];
199+
[xmppRosterStorage endRosterPopulationForXMPPStream:xmppStream];
200+
201+
// Process any premature presence elements we received.
202+
203+
for (XMPPPresence *presence in earlyPresenceElements)
204+
{
205+
[self xmppStream:xmppStream didReceivePresence:presence];
206+
}
207+
208+
[earlyPresenceElements removeAllObjects];
209+
}
210+
211+
}};
212+
213+
if (dispatch_get_specific(moduleQueueTag))
214+
block();
215+
else
216+
dispatch_async(moduleQueue, block);
217+
218+
}
219+
220+
### 监听Roster获取完成时的回调
221+
222+
/**
223+
* Sent when the initial roster is received.<br/>
224+
* 当roster开始往 storage(coreData 或者 memory) 添加数据时的回调
225+
**/
226+
227+
- (void)xmppRosterDidBeginPopulating:(XMPPRoster *)sender;
228+
229+
/**
230+
* Sent when the initial roster has been populated into storage.<br/>
231+
* 当roster往 storage(coreData 或者 memory) 添加数据完成后的回调
232+
**/
233+
234+
- (void)xmppRosterDidEndPopulating:(XMPPRoster *)sender;
235+
236+
/**
237+
* Sent when the roster receives a roster item.<br/>
238+
* 在 发送 xmppRosterDidBeginPopulating 广播后, 会陆续收到didReceiveRosterItem 的回调<br/>
239+
* 在 发送 xmppRosterDidEndPopulating 广播后, 表示roster列表遍历完成
240+
**/
241+
242+
- (void)xmppRoster:(XMPPRoster *)sender didReceiveRosterItem:(NSXMLElement *)item;
243+
244+
监听以上三个方法, 可以完成基本的好友获取操作, 使用 XMPPRosterMemoryStorage 类的回调则可以监听到更多的回调, 可以自己参照代码进行查看.
245+
好友列表完成时的回调方法如下:
246+
247+
- (void)xmppRosterDidPopulate:(XMPPRosterMemoryStorage *)sender{
248+
//通过 sortedUsersByName 方法可以从 memory对象中获取roster列表
249+
NSArray *roster = [sender sortedUsersByName];
250+
}
158251

159-
###
252+
**其它回调方法, 比如: 删除好友、添加好友、接收到好友请求等操作,将会慢慢道来**

0 commit comments

Comments
 (0)