XMPPRoster.h
13.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
#import <Foundation/Foundation.h>
#if TARGET_OS_IPHONE
#import <UIKit/UIKit.h>
#else
#import <Cocoa/Cocoa.h>
#endif
#import "XMPP.h"
#import "XMPPUser.h"
#import "XMPPResource.h"
#define _XMPP_ROSTER_H
@protocol XMPPRosterStorage;
@class DDList;
@class XMPPIDTracker;
/**
* The XMPPRoster provides the scaffolding for a roster solution.
* It handles the basics of the xmpp roster communication,
* and leaves the rest up to the xmppRosterStorage classes.
*
* You are free to extend, change, customize, or tweak the sample storage classes that come with the framework:
* XMPPRosterMemoryStorage
* XMPPRosterCoreDataStorage
*
* You can also completely implment your own roster storage class if you'd like.
* The point of all this customizability is simple:
* The roster is the component of the xmpp stack that is most often customized for a particular application.
*
*
* Inter-Module Interaction:
*
* If you use XMPPvCardAvatarModule, the roster will automatically support user photos.
**/
@interface XMPPRoster : XMPPModule
{
/* Inherited from XMPPModule:
XMPPStream *xmppStream;
dispatch_queue_t moduleQueue;
id multicastDelegate;
*/
__strong id <XMPPRosterStorage> xmppRosterStorage;
XMPPIDTracker *xmppIDTracker;
Byte config;
Byte flags;
NSMutableArray *earlyPresenceElements;
DDList *mucModules;
}
- (id)initWithRosterStorage:(id <XMPPRosterStorage>)storage;
- (id)initWithRosterStorage:(id <XMPPRosterStorage>)storage dispatchQueue:(dispatch_queue_t)queue;
/* Inherited from XMPPModule:
- (BOOL)activate:(XMPPStream *)xmppStream;
- (void)deactivate;
@property (readonly) XMPPStream *xmppStream;
- (void)addDelegate:(id)delegate delegateQueue:(dispatch_queue_t)delegateQueue;
- (void)removeDelegate:(id)delegate delegateQueue:(dispatch_queue_t)delegateQueue;
- (void)removeDelegate:(id)delegate;
- (NSString *)moduleName;
*/
@property (strong, readonly) id <XMPPRosterStorage> xmppRosterStorage;
/**
* Whether or not to automatically fetch the roster from the server.
*
* The default value is YES.
**/
@property (assign) BOOL autoFetchRoster;
/**
* Whether or not to automatically clear all Users and Resources when the stream disconnects.
* If you are using XMPPRosterCoreDataStorage you may want to set autoRemovePreviousDatabaseFile to NO.
*
* All Users and Resources will be cleared when the roster is next populated regardless of this property.
*
* The default value is YES.
**/
@property (assign) BOOL autoClearAllUsersAndResources;
/**
* In traditional IM applications, the "buddy" system is rather straightforward.
* User A sends a request to become "friends" with user B.
* User B accepts the friend request.
* And now user A and B appear in each other's roster.
*
* But, internally, XMPP presence actually works more like twitter.
* User A sends a presence subscription request to user B.
* Think about this more like following on twitter.
* User A is requesting permission to receive presence information from user B (following their presence).
* User B can accept this request, but may not be interested in receiving presence info from user B.
* Again, this is more like twitter following, but with the addition of required permission.
* So when user B accepts the request, this *only* means that user A will receive presence from user B.
* It does *not* mean that user B will receive presence from user A.
* Again, twitter-style, user A is now "following" user B.
* In diagram form, presence is flowing like this:
*
* A <-- B
*
* Now, if B also wants to receive presence from user A, then user B must request this permission.
* And furthermore, user A must accept the request.
* Just because B has granted A permission to receive presence,
* doesn't mean that B gets a free pass to receive presence from A.
* Presence always requires permission.
*
* This property does the following:
* If a presence subscription request is received from user X,
* and user X has already been added to our roster (is a "known" user),
* then the presence subscription request is automatically accepted.
*
* Continuing the example from above, if we were user A, and we've already added B to our roster,
* then if B sends a presence susbcription request, we'll auto accept it.
*
* This makes the roster act more like traditional IM applications.
*
* The default value is YES.
**/
@property (assign) BOOL autoAcceptKnownPresenceSubscriptionRequests;
/**
* Allows the roster module to function without ever fetching the full roster.
* This is helpful for situations in which the roster is very big, yet the application only cares about online users.
*
* Typically, the roster module creates users based on the fetched full roster,
* and then creates resources based on received presence.
*
* In this mode, the roster module will automatically create a user once a presence is received,
* if the user has never been seen before.
*
* If allowRosterlessOperation is enabled, and autoFetchRoster is disabled (and roster is never manually fetched),
* then XMPPUser's will be missing certain information that is only available via a roster fetch
* (such as nickname, group, and subscription information).
*
* The default value is NO.
**/
@property (assign) BOOL allowRosterlessOperation;
/**
* The roster has either been requested manually (fetchRoster:)
* or automatically (autoFetchRoster) but has yet to be populated.
**/
@property (assign, getter = hasRequestedRoster, readonly) BOOL requestedRoster;
/**
* The initial roster has been received by client and is currently being populated.
* @see xmppRosterDidBeginPopulating:withVersion:
* @see xmppRosterDidEndPopulating:
**/
@property (assign, getter = isPopulating, readonly) BOOL populating;
/**
* The initial roster has been received by client and populated.
**/
@property (assign, readonly) BOOL hasRoster;
/**
* Manually fetch the roster from the server.
* Useful if you disable autoFetchRoster.
**/
- (void)fetchRoster;
- (void)fetchRosterVersion:(NSString *)version;
/**
* Adds the given user to the roster with an optional nickname
* and requests permission to receive presence information from them.
**/
- (void)addUser:(XMPPJID *)jid withNickname:(NSString *)optionalName;
/**
* Adds the given user to the roster with an optional nickname,
* adds the given user to groups
* and requests permission to receive presence information from them.
**/
- (void)addUser:(XMPPJID *)jid withNickname:(NSString *)optionalName groups:(NSArray *)groups;
/**
* Adds the given user to the roster with an optional nickname,
* adds the given user to groups
* and optionally requests permission to receive presence information from them.
**/
- (void)addUser:(XMPPJID *)jid withNickname:(NSString *)optionalName groups:(NSArray *)groups subscribeToPresence:(BOOL)subscribe;
/**
* Sets/modifies the nickname for the given user.
**/
- (void)setNickname:(NSString *)nickname forUser:(XMPPJID *)jid;
/**
* Remove the user from the roster, unsubscribe from their presence, AND
* revoke given user's permission to receive our presence (if they have such permission).
*
* This is similar to removing a buddy in a traditional IM model.
*
* @see unsubscribePresenceFromUser:
* @see revokePresencePermissionFromUser:
**/
- (void)removeUser:(XMPPJID *)jid;
/**
* If we don't currently receive presence from the given user,
* this method requests a subscription to start receiving presence updates from the given user.
*
* This is similar to following in the twitter model.
*
* Note: If the given user isn't already in the roster, it is recommended to instead use addUser:withNickname:.
*
* @see addUser:withNickname:
**/
- (void)subscribePresenceToUser:(XMPPJID *)jid;
/**
* If we currently have a presence subscription to the given user,
* this method then removes the subscription.
*
* This is similar to unfollowing in the twitter model.
*
* If the given user has a presence subscription to us (they're following our presence),
* then their presence subscription to us is left intact.
*
* @see removeUser:
* @see revokePresencePermissionFromUser:
**/
- (void)unsubscribePresenceFromUser:(XMPPJID *)jid;
/**
* If we have previously accepted a presence subscription request from the given user,
* this method revokes the previously granted permission.
*
* This is similar to forcing the given user to unfollow us in the twitter model.
*
* If we have a presence subscription to the given user (we're following their presence),
* then our presence subscription to them is left intact.
*
* @see removeUser:
* @see unsubscribePresenceFromUser:
**/
- (void)revokePresencePermissionFromUser:(XMPPJID *)jid;
/**
* Accepts the presence subscription request the given user.
*
* If you also choose, you can add the user to your roster.
* Doing so is similar to the traditional IM model.
**/
- (void)acceptPresenceSubscriptionRequestFrom:(XMPPJID *)jid andAddToRoster:(BOOL)flag;
/**
* Rejects the presence subscription request from the given user.
*
* If you are already subscribed to the given user's presence,
* rejecting they subscription request will not affect your subscription to their presence.
**/
- (void)rejectPresenceSubscriptionRequestFrom:(XMPPJID *)jid;
//
//
// You can access/enumerate the users & resources via the roster storage class (xmppRosterStorage property).
//
// Rember, XMPPRoster is just the scaffolding for a complete and customizable roster solution.
// The roster storage classes hold the majority of the magic.
//
// And since you're free to plug-n-play storage classes, and customize them as much as you want.
// This is where you can really tailor the xmpp stack to meet the needs of your application.
//
//
@end
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#pragma mark -
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@protocol XMPPRosterStorage <NSObject>
@required
//
//
// -- PUBLIC METHODS --
//
// There are no public methods required by this protocol.
//
// Each individual roster storage class will provide a proper way to access/enumerate the
// users/resources according to the underlying storage mechanism.
//
//
//
// -- PRIVATE METHODS --
//
// These methods are designed to be used ONLY by the XMPPRoster class.
//
//
/**
* Configures the storage class, passing its parent and parent's dispatch queue.
*
* This method is called by the init method of the XMPPRoster class.
* This method is designed to inform the storage class of its parent
* and of the dispatch queue the parent will be operating on.
*
* The storage class may choose to operate on the same queue as its parent,
* or it may operate on its own internal dispatch queue.
*
* This method should return YES if it was configured properly.
* If a storage class is designed to be used with a single parent at a time, this method may return NO.
* The XMPPRoster class is configured to ignore the passed
* storage class in its init method if this method returns NO.
**/
- (BOOL)configureWithParent:(XMPPRoster *)aParent queue:(dispatch_queue_t)queue;
- (void)beginRosterPopulationForXMPPStream:(XMPPStream *)stream withVersion:(NSString *)version;
- (void)endRosterPopulationForXMPPStream:(XMPPStream *)stream;
- (void)handleRosterItem:(NSXMLElement *)item xmppStream:(XMPPStream *)stream;
- (void)handlePresence:(XMPPPresence *)presence xmppStream:(XMPPStream *)stream;
- (BOOL)userExistsWithJID:(XMPPJID *)jid xmppStream:(XMPPStream *)stream;
- (void)clearAllResourcesForXMPPStream:(XMPPStream *)stream;
- (void)clearAllUsersAndResourcesForXMPPStream:(XMPPStream *)stream;
- (NSArray *)jidsForXMPPStream:(XMPPStream *)stream;
- (void)getSubscription:(NSString **)subscription
ask:(NSString **)ask
nickname:(NSString **)nickname
groups:(NSArray **)groups
forJID:(XMPPJID *)jid
xmppStream:(XMPPStream *)stream;
@optional
/**
* When XMPPvCardAvatarModule is included in the framework, the roster will integrate with it.
* Implement this method to provide support for storing the downloaded user photos.
**/
#if TARGET_OS_IPHONE
- (void)setPhoto:(UIImage *)image forUserWithJID:(XMPPJID *)jid xmppStream:(XMPPStream *)stream;
#else
- (void)setPhoto:(NSImage *)image forUserWithJID:(XMPPJID *)jid xmppStream:(XMPPStream *)stream;
#endif
@end
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#pragma mark -
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@protocol XMPPRosterDelegate
@optional
/**
* Sent when a presence subscription request is received.
* That is, another user has added you to their roster,
* and is requesting permission to receive presence broadcasts that you send.
*
* The entire presence packet is provided for proper extensibility.
* You can use [presence from] to get the JID of the user who sent the request.
*
* The methods acceptPresenceSubscriptionRequestFrom: and rejectPresenceSubscriptionRequestFrom: can
* be used to respond to the request.
**/
- (void)xmppRoster:(XMPPRoster *)sender didReceivePresenceSubscriptionRequest:(XMPPPresence *)presence;
/**
* Sent when a Roster Push is received as specified in Section 2.1.6 of RFC 6121.
**/
- (void)xmppRoster:(XMPPRoster *)sender didReceiveRosterPush:(XMPPIQ *)iq;
/**
* Sent when the initial roster is received.
**/
- (void)xmppRosterDidBeginPopulating:(XMPPRoster *)sender withVersion:(NSString *)version;
/**
* Sent when the initial roster has been populated into storage.
**/
- (void)xmppRosterDidEndPopulating:(XMPPRoster *)sender;
/**
* 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;
@end