XMPPRoom.h
10.6 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
#import <Foundation/Foundation.h>
#import "XMPP.h"
#import "XMPPRoomMessage.h"
#import "XMPPRoomOccupant.h"
#define _XMPP_ROOM_H
@class XMPPIDTracker;
@protocol XMPPRoomStorage;
@protocol XMPPRoomDelegate;
static NSString *const XMPPMUCNamespace = @"http://jabber.org/protocol/muc";
static NSString *const XMPPMUCUserNamespace = @"http://jabber.org/protocol/muc#user";
static NSString *const XMPPMUCAdminNamespace = @"http://jabber.org/protocol/muc#admin";
static NSString *const XMPPMUCOwnerNamespace = @"http://jabber.org/protocol/muc#owner";
@interface XMPPRoom : XMPPModule
{
/* Inherited from XMPPModule:
XMPPStream *xmppStream;
dispatch_queue_t moduleQueue;
id multicastDelegate;
*/
__strong id <XMPPRoomStorage> xmppRoomStorage;
__strong XMPPJID *roomJID;
__strong XMPPJID *myRoomJID;
__strong NSString *myNickname;
__strong NSString *myOldNickname;
__strong NSString *roomSubject;
XMPPIDTracker *responseTracker;
uint16_t state;
}
- (id)initWithRoomStorage:(id <XMPPRoomStorage>)storage jid:(XMPPJID *)roomJID;
- (id)initWithRoomStorage:(id <XMPPRoomStorage>)storage jid:(XMPPJID *)roomJID 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;
*/
#pragma mark Properties
@property (readonly) id <XMPPRoomStorage> xmppRoomStorage;
@property (readonly) XMPPJID * roomJID; // E.g. xmpp-development@conference.deusty.com
@property (readonly) XMPPJID * myRoomJID; // E.g. xmpp-development@conference.deusty.com/robbiehanson
@property (readonly) NSString * myNickname; // E.g. robbiehanson
@property (readonly) NSString *roomSubject;
@property (readonly) BOOL isJoined;
#pragma mark Room Lifecycle
/**
* Sends a presence element to the join room.
*
* If the room already exists, then the xmppRoomDidJoin: delegate method will be invoked upon
* notifiaction from the server that we successfully joined the room.
*
* If the room did not already exist, and the authenticated user is allowed to create the room,
* then the server will automatically create the room,
* and the xmppRoomDidCreate: delegate method will be invoked (followed by xmppRoomDidJoin:).
* You'll then need to configure the room before others can join.
*
* @param desiredNickname (required)
* The nickname to use within the room.
* If the room is anonymous, this is the only identifier other occupants of the room will see.
*
* @param history (optional)
* A history element specifying how much discussion history to request from the server.
* E.g. <history maxstanzas='100'/>
* For more information, please see XEP-0045, Section 7.1.16 - Managing Discussion History.
* You may also want to query your storage module to see how old the most recent stored message for this room is.
*
* @see fetchConfigurationForm
* @see configureRoomUsingOptions:
**/
- (void)joinRoomUsingNickname:(NSString *)desiredNickname history:(NSXMLElement *)history;
- (void)joinRoomUsingNickname:(NSString *)desiredNickname history:(NSXMLElement *)history password:(NSString *)passwd;
/**
* There are two ways to configure a room.
* 1.) Accept the default configuration
* 2.) Send a custom configuration
*
* To see which configuration options the server supports,
* or to inspect the default options, you'll need to fetch the configuration form.
*
* @see configureRoomUsingOptions:
**/
- (void)fetchConfigurationForm;
/**
* Pass nil to accept the default configuration.
**/
- (void)configureRoomUsingOptions:(NSXMLElement *)roomConfigForm;
- (void)leaveRoom;
- (void)destroyRoom;
#pragma mark Room Interaction
- (void)changeNickname:(NSString *)newNickname;
- (void)changeRoomSubject:(NSString *)newRoomSubject;
- (void)inviteUser:(XMPPJID *)jid withMessage:(NSString *)invitationMessage;
- (void)sendMessage:(XMPPMessage *)message;
- (void)sendMessageWithBody:(NSString *)messageBody;
#pragma mark Room Moderation
- (void)fetchBanList;
- (void)fetchMembersList;
- (void)fetchModeratorsList;
/**
* The ban list, member list, and moderator list are simply subsets of the room privileges list.
* That is, a user's status as 'banned', 'member', 'moderator', etc,
* are simply different priveleges that may be assigned to a user.
*
* You may edit the list of privileges using this method.
* The array of items corresponds with the <item/> stanzas of Section 9 of XEP-0045.
* This class provides helper methods to create these item elements.
*
* @see itemWithAffiliation:jid:
* @see itemWithRole:jid:
*
* The authenticated user must be an admin or owner of the room, or the server will deny the request.
*
* To add a member: <item
*
*
* @return The id of the XMPPIQ that was sent.
* This may be used to match multiple change requests with the responses in xmppRoom:didEditPrivileges:.
**/
- (NSString *)editRoomPrivileges:(NSArray *)items;
+ (NSXMLElement *)itemWithAffiliation:(NSString *)affiliation jid:(XMPPJID *)jid;
+ (NSXMLElement *)itemWithRole:(NSString *)role jid:(XMPPJID *)jid;
@end
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#pragma mark -
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@protocol XMPPRoomStorage <NSObject>
@required
//
//
// -- PUBLIC METHODS --
//
// There are no public methods required by this protocol.
//
// Each individual storage class will provide a proper way to access/enumerate the
// occupants/messages according to the underlying storage mechanism.
//
//
//
// -- PRIVATE METHODS --
//
// These methods are designed to be used ONLY by the XMPPRoom class.
//
//
/**
* Configures the storage class, passing it's parent and parent's dispatch queue.
*
* This method is called by the init method of the XMPPRoom class.
* This method is designed to inform the storage class of it's parent
* and of the dispatch queue the parent will be operating on.
*
* A storage class may choose to operate on the same queue as it's parent,
* as the majority of the time it will be getting called by the parent.
* If both are operating on the same queue, the combination may run faster.
*
* Some storage classes support multiple xmppStreams,
* and may choose to operate on their own internal queue.
*
* This method should return YES if it was configured properly.
* It should return NO only if configuration failed.
* For example, a storage class designed to be used only with a single xmppStream is being added to a second stream.
* The XMPPCapabilites class is configured to ignore the passed
* storage class in it's init method if this method returns NO.
**/
- (BOOL)configureWithParent:(XMPPRoom *)aParent queue:(dispatch_queue_t)queue;
/**
* Updates and returns the occupant for the given presence element.
* If the presence type is "available", and the occupant doesn't already exist, then one should be created.
**/
- (void)handlePresence:(XMPPPresence *)presence room:(XMPPRoom *)room;
/**
* Stores or otherwise handles the given message element.
**/
- (void)handleIncomingMessage:(XMPPMessage *)message room:(XMPPRoom *)room;
- (void)handleOutgoingMessage:(XMPPMessage *)message room:(XMPPRoom *)room;
/**
* Handles leaving the room, which generally means clearing the list of occupants.
**/
- (void)handleDidLeaveRoom:(XMPPRoom *)room;
@optional
/**
* May be used if there's anything special to do when joining a room.
**/
- (void)handleDidJoinRoom:(XMPPRoom *)room withNickname:(NSString *)nickname;
@end
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#pragma mark -
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@protocol XMPPRoomDelegate <NSObject>
@optional
- (void)xmppRoomDidCreate:(XMPPRoom *)sender;
/**
* Invoked with the results of a request to fetch the configuration form.
* The given config form will look something like:
*
* <x xmlns='jabber:x:data' type='form'>
* <title>Configuration for MUC Room</title>
* <field type='hidden'
* var='FORM_TYPE'>
* <value>http://jabber.org/protocol/muc#roomconfig</value>
* </field>
* <field label='Natural-Language Room Name'
* type='text-single'
* var='muc#roomconfig_roomname'/>
* <field label='Enable Public Logging?'
* type='boolean'
* var='muc#roomconfig_enablelogging'>
* <value>0</value>
* </field>
* ...
* </x>
*
* The form is to be filled out and then submitted via the configureRoomUsingOptions: method.
*
* @see fetchConfigurationForm:
* @see configureRoomUsingOptions:
**/
- (void)xmppRoom:(XMPPRoom *)sender didFetchConfigurationForm:(NSXMLElement *)configForm;
- (void)xmppRoom:(XMPPRoom *)sender willSendConfiguration:(XMPPIQ *)roomConfigForm;
- (void)xmppRoom:(XMPPRoom *)sender didConfigure:(XMPPIQ *)iqResult;
- (void)xmppRoom:(XMPPRoom *)sender didNotConfigure:(XMPPIQ *)iqResult;
- (void)xmppRoomDidJoin:(XMPPRoom *)sender;
- (void)xmppRoomDidLeave:(XMPPRoom *)sender;
- (void)xmppRoomDidDestroy:(XMPPRoom *)sender;
- (void)xmppRoom:(XMPPRoom *)sender didFailToDestroy:(XMPPIQ *)iqError;
- (void)xmppRoom:(XMPPRoom *)sender occupantDidJoin:(XMPPJID *)occupantJID withPresence:(XMPPPresence *)presence;
- (void)xmppRoom:(XMPPRoom *)sender occupantDidLeave:(XMPPJID *)occupantJID withPresence:(XMPPPresence *)presence;
- (void)xmppRoom:(XMPPRoom *)sender occupantDidUpdate:(XMPPJID *)occupantJID withPresence:(XMPPPresence *)presence;
/**
* Invoked when a message is received.
* The occupant parameter may be nil if the message came directly from the room, or from a non-occupant.
**/
- (void)xmppRoom:(XMPPRoom *)sender didReceiveMessage:(XMPPMessage *)message fromOccupant:(XMPPJID *)occupantJID;
- (void)xmppRoom:(XMPPRoom *)sender didFetchBanList:(NSArray *)items;
- (void)xmppRoom:(XMPPRoom *)sender didNotFetchBanList:(XMPPIQ *)iqError;
- (void)xmppRoom:(XMPPRoom *)sender didFetchMembersList:(NSArray *)items;
- (void)xmppRoom:(XMPPRoom *)sender didNotFetchMembersList:(XMPPIQ *)iqError;
- (void)xmppRoom:(XMPPRoom *)sender didFetchModeratorsList:(NSArray *)items;
- (void)xmppRoom:(XMPPRoom *)sender didNotFetchModeratorsList:(XMPPIQ *)iqError;
- (void)xmppRoom:(XMPPRoom *)sender didEditPrivileges:(XMPPIQ *)iqResult;
- (void)xmppRoom:(XMPPRoom *)sender didNotEditPrivileges:(XMPPIQ *)iqError;
@end