Skip to content

Commit 66e1709

Browse files
committed
Adding ability for XMPPStream to handle custom stanzas (non iq, message, presence), along with corresponding delegate methods.
1 parent a12f9c1 commit 66e1709

File tree

3 files changed

+79
-0
lines changed

3 files changed

+79
-0
lines changed

Core/XMPPInternal.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,20 @@ extern NSString *const XMPPStreamDidChangeMyJIDNotification;
6161
**/
6262
- (void)injectElement:(NSXMLElement *)element;
6363

64+
/**
65+
* The XMPP standard only supports <iq>, <message> and <presence> stanzas (excluding session setup stuff).
66+
* But some extensions use non-standard element types.
67+
* The standard example is XEP-0198, which uses <r> & <a> elements.
68+
*
69+
* XMPPStream will assume that any non-standard element types are errors, unless you register them.
70+
* Once registered the stream can recognize them, and will use the following delegate methods:
71+
*
72+
* xmppStream:didSendCustomElement:
73+
* xmppStream:didReceiveCustomElement:
74+
**/
75+
- (void)registerCustomElementNames:(NSSet *)names;
76+
- (void)unregisterCustomElementNames:(NSSet *)names;
77+
6478
@end
6579

6680
@interface XMPPModule (/* Internal */)

Core/XMPPStream.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1061,4 +1061,20 @@ extern const NSTimeInterval XMPPStreamTimeoutNone;
10611061
- (void)xmppStream:(XMPPStream *)sender didRegisterModule:(id)module;
10621062
- (void)xmppStream:(XMPPStream *)sender willUnregisterModule:(id)module;
10631063

1064+
/**
1065+
* Custom elements are Non-XMPP elements.
1066+
* In other words, not <iq>, <message> or <presence> elements.
1067+
*
1068+
* Typically these kinds of elements are not allowed by the XMPP server.
1069+
* But some custom implementations may use them.
1070+
* The standard example is XEP-0198, which uses <r> & <a> elements.
1071+
*
1072+
* If you're using custom elements, you must register the custom element name(s).
1073+
* Otherwise the xmppStream will treat an non-XMPP elements as errors (xmppStream:didReceiveError:).
1074+
*
1075+
* @see registerCustomElementNames (in XMPPInternal.h)
1076+
**/
1077+
- (void)xmppStream:(XMPPStream *)sender didSendCustomElement:(NSXMLElement *)element;
1078+
- (void)xmppStream:(XMPPStream *)sender didReceiveCustomElement:(NSXMLElement *)element;
1079+
10641080
@end

Core/XMPPStream.m

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@ @interface XMPPStream ()
138138
XMPPIDTracker *idTracker;
139139

140140
NSMutableArray *receipts;
141+
NSCountedSet *customElementNames;
141142

142143
id userTag;
143144
}
@@ -2473,6 +2474,11 @@ - (void)continueSendElement:(NSXMLElement *)element withTag:(long)tag
24732474
[asyncSocket writeData:outgoingData
24742475
withTimeout:TIMEOUT_XMPP_WRITE
24752476
tag:tag];
2477+
2478+
if ([customElementNames countForObject:[element name]])
2479+
{
2480+
[multicastDelegate xmppStream:self didSendCustomElement:element];
2481+
}
24762482
}
24772483

24782484
/**
@@ -3027,6 +3033,10 @@ - (void)injectElement:(NSXMLElement *)element
30273033
{
30283034
[self receivePresence:[XMPPPresence presenceFromElement:element]];
30293035
}
3036+
else if ([customElementNames countForObject:elementName])
3037+
{
3038+
[multicastDelegate xmppStream:self didReceiveCustomElement:element];
3039+
}
30303040
else
30313041
{
30323042
[multicastDelegate xmppStream:self didReceiveError:element];
@@ -3040,6 +3050,41 @@ - (void)injectElement:(NSXMLElement *)element
30403050
dispatch_async(xmppQueue, block);
30413051
}
30423052

3053+
- (void)registerCustomElementNames:(NSSet *)names
3054+
{
3055+
dispatch_block_t block = ^{
3056+
3057+
if (customElementNames == nil)
3058+
customElementNames = [[NSCountedSet alloc] init];
3059+
3060+
for (NSString *name in names)
3061+
{
3062+
[customElementNames addObject:name];
3063+
}
3064+
};
3065+
3066+
if (dispatch_get_specific(xmppQueueTag))
3067+
block();
3068+
else
3069+
dispatch_sync(xmppQueue, block);
3070+
}
3071+
3072+
- (void)unregisterCustomElementNames:(NSSet *)names
3073+
{
3074+
dispatch_block_t block = ^{
3075+
3076+
for (NSString *name in names)
3077+
{
3078+
[customElementNames removeObject:name];
3079+
}
3080+
};
3081+
3082+
if (dispatch_get_specific(xmppQueueTag))
3083+
block();
3084+
else
3085+
dispatch_sync(xmppQueue, block);
3086+
}
3087+
30433088
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
30443089
#pragma mark Stream Negotiation
30453090
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -4235,6 +4280,10 @@ - (void)xmppParser:(XMPPParser *)sender didReadElement:(NSXMLElement *)element
42354280
{
42364281
[multicastDelegate xmppStream:self didReceiveP2PFeatures:element];
42374282
}
4283+
else if ([customElementNames countForObject:elementName])
4284+
{
4285+
[multicastDelegate xmppStream:self didReceiveCustomElement:element];
4286+
}
42384287
else
42394288
{
42404289
[multicastDelegate xmppStream:self didReceiveError:element];

0 commit comments

Comments
 (0)