Skip to content
This repository
tree: 07dfba62a8
Fetching contributors…

Cannot retrieve contributors at this time

file 320 lines (272 sloc) 11.352 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
#import <Foundation/Foundation.h>

#if !TARGET_OS_IPHONE
#import <Cocoa/Cocoa.h>
#endif

#import "XMPP.h"
#import "XMPPUser.h"
#import "XMPPResource.h"

@protocol XMPPRosterStorage;
@class DDList;

/**
* 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;

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;

/**
* 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;

/**
* Manually fetch the roster from the server.
* Useful if you disable autoFetchRoster.
**/
- (void)fetchRoster;

/**
* Adds the given user to the roster and requests permission to receive presence information from them.
**/
- (void)addUser:(XMPPJID *)jid withNickname:(NSString *)optionalName;

/**
* 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;
- (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;

@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;

@end
Something went wrong with that request. Please try again.