Skip to content

Commit 300cb9a

Browse files
committed
XMPPStream now supports the ability to filter outgoing elements via the xmppStream:willSendX: methods. (Notice: this is an API change as these method are no longer void. A proper assert has been added to aid in debugging.)
1 parent f8b05bd commit 300cb9a

File tree

6 files changed

+109
-40
lines changed

6 files changed

+109
-40
lines changed

Core/XMPPStream.h

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -842,10 +842,16 @@ typedef enum XMPPStreamErrorCode XMPPStreamErrorCode;
842842
* These methods are called before their respective XML elements are sent over the stream.
843843
* These methods can be used to customize elements on the fly.
844844
* (E.g. add standard information for custom protocols.)
845+
*
846+
* You may also filter outgoing elements by returning nil.
847+
*
848+
* When implementing these methods to modify the element, you do not need to copy the given element.
849+
* You can simply edit the given element, and return it.
850+
* The reason these methods return an element, instead of void, is to allow filtering.
845851
**/
846-
- (void)xmppStream:(XMPPStream *)sender willSendIQ:(XMPPIQ *)iq;
847-
- (void)xmppStream:(XMPPStream *)sender willSendMessage:(XMPPMessage *)message;
848-
- (void)xmppStream:(XMPPStream *)sender willSendPresence:(XMPPPresence *)presence;
852+
- (XMPPIQ *)xmppStream:(XMPPStream *)sender willSendIQ:(XMPPIQ *)iq;
853+
- (XMPPMessage *)xmppStream:(XMPPStream *)sender willSendMessage:(XMPPMessage *)message;
854+
- (XMPPPresence *)xmppStream:(XMPPStream *)sender willSendPresence:(XMPPPresence *)presence;
849855

850856
/**
851857
* These methods are called after their respective XML elements are sent over the stream.

Core/XMPPStream.m

Lines changed: 90 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#import "NSData+XMPP.h"
77
#import "DDList.h"
88

9+
#import <objc/runtime.h>
910
#import <libkern/OSAtomic.h>
1011

1112
#if TARGET_OS_IPHONE
@@ -1758,7 +1759,6 @@ - (void)sendIQ:(XMPPIQ *)iq withTag:(long)tag
17581759
NSAssert(dispatch_get_current_queue() == xmppQueue, @"Invoked on incorrect queue");
17591760
NSAssert(state == STATE_XMPP_CONNECTED, @"Invoked with incorrect state");
17601761

1761-
17621762
// We're getting ready to send an IQ.
17631763
// We need to notify delegates of this action to allow them to optionally alter the IQ element.
17641764

@@ -1781,27 +1781,46 @@ - (void)sendIQ:(XMPPIQ *)iq withTag:(long)tag
17811781
dispatch_queue_t concurrentQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
17821782
dispatch_async(concurrentQueue, ^{ @autoreleasepool {
17831783

1784-
// Allow delegates to modify outgoing element
1784+
// Allow delegates to modify and/or filter outgoing element
1785+
1786+
__block XMPPIQ *modifiedIQ = iq;
17851787

17861788
id del;
17871789
dispatch_queue_t dq;
17881790

1789-
while ([delegateEnumerator getNextDelegate:&del delegateQueue:&dq forSelector:selector])
1791+
while (modifiedIQ && [delegateEnumerator getNextDelegate:&del delegateQueue:&dq forSelector:selector])
17901792
{
1793+
#if DEBUG
1794+
{
1795+
char methodReturnType[32];
1796+
1797+
Method method = class_getInstanceMethod([del class], selector);
1798+
method_getReturnType(method, methodReturnType, sizeof(methodReturnType));
1799+
1800+
if (strcmp(methodReturnType, @encode(XMPPIQ*)) != 0)
1801+
{
1802+
NSAssert(NO, @"Method xmppStream:willSendIQ: is no longer void (see XMPPStream.h). "
1803+
@"Culprit = %@", NSStringFromClass([del class]));
1804+
}
1805+
}
1806+
#endif
1807+
17911808
dispatch_sync(dq, ^{ @autoreleasepool {
17921809

1793-
[del xmppStream:self willSendIQ:iq];
1810+
modifiedIQ = [del xmppStream:self willSendIQ:modifiedIQ];
17941811

17951812
}});
17961813
}
17971814

1798-
dispatch_async(xmppQueue, ^{ @autoreleasepool {
1799-
1800-
if (state == STATE_XMPP_CONNECTED) {
1801-
[self continueSendIQ:iq withTag:tag];
1802-
}
1803-
}});
1804-
1815+
if (modifiedIQ)
1816+
{
1817+
dispatch_async(xmppQueue, ^{ @autoreleasepool {
1818+
1819+
if (state == STATE_XMPP_CONNECTED) {
1820+
[self continueSendIQ:modifiedIQ withTag:tag];
1821+
}
1822+
}});
1823+
}
18051824
}});
18061825
}
18071826
}
@@ -1811,7 +1830,6 @@ - (void)sendMessage:(XMPPMessage *)message withTag:(long)tag
18111830
NSAssert(dispatch_get_current_queue() == xmppQueue, @"Invoked on incorrect queue");
18121831
NSAssert(state == STATE_XMPP_CONNECTED, @"Invoked with incorrect state");
18131832

1814-
18151833
// We're getting ready to send a message.
18161834
// We need to notify delegates of this action to allow them to optionally alter the message element.
18171835

@@ -1836,25 +1854,44 @@ - (void)sendMessage:(XMPPMessage *)message withTag:(long)tag
18361854

18371855
// Allow delegates to modify outgoing element
18381856

1857+
__block XMPPMessage *modifiedMessage = message;
1858+
18391859
id del;
18401860
dispatch_queue_t dq;
18411861

1842-
while ([delegateEnumerator getNextDelegate:&del delegateQueue:&dq forSelector:selector])
1862+
while (modifiedMessage && [delegateEnumerator getNextDelegate:&del delegateQueue:&dq forSelector:selector])
18431863
{
1864+
#if DEBUG
1865+
{
1866+
char methodReturnType[32];
1867+
1868+
Method method = class_getInstanceMethod([del class], selector);
1869+
method_getReturnType(method, methodReturnType, sizeof(methodReturnType));
1870+
1871+
if (strcmp(methodReturnType, @encode(XMPPMessage*)) != 0)
1872+
{
1873+
NSAssert(NO, @"Method xmppStream:willSendMessage: is no longer void (see XMPPStream.h). "
1874+
@"Culprit = %@", NSStringFromClass([del class]));
1875+
}
1876+
}
1877+
#endif
1878+
18441879
dispatch_sync(dq, ^{ @autoreleasepool {
18451880

1846-
[del xmppStream:self willSendMessage:message];
1881+
modifiedMessage = [del xmppStream:self willSendMessage:modifiedMessage];
18471882

18481883
}});
18491884
}
18501885

1851-
dispatch_async(xmppQueue, ^{ @autoreleasepool {
1852-
1853-
if (state == STATE_XMPP_CONNECTED) {
1854-
[self continueSendMessage:message withTag:tag];
1855-
}
1856-
}});
1857-
1886+
if (modifiedMessage)
1887+
{
1888+
dispatch_async(xmppQueue, ^{ @autoreleasepool {
1889+
1890+
if (state == STATE_XMPP_CONNECTED) {
1891+
[self continueSendMessage:modifiedMessage withTag:tag];
1892+
}
1893+
}});
1894+
}
18581895
}});
18591896
}
18601897
}
@@ -1864,7 +1901,6 @@ - (void)sendPresence:(XMPPPresence *)presence withTag:(long)tag
18641901
NSAssert(dispatch_get_current_queue() == xmppQueue, @"Invoked on incorrect queue");
18651902
NSAssert(state == STATE_XMPP_CONNECTED, @"Invoked with incorrect state");
18661903

1867-
18681904
// We're getting ready to send a presence element.
18691905
// We need to notify delegates of this action to allow them to optionally alter the presence element.
18701906

@@ -1889,25 +1925,44 @@ - (void)sendPresence:(XMPPPresence *)presence withTag:(long)tag
18891925

18901926
// Allow delegates to modify outgoing element
18911927

1928+
__block XMPPPresence *modifiedPresence = presence;
1929+
18921930
id del;
18931931
dispatch_queue_t dq;
18941932

1895-
while ([delegateEnumerator getNextDelegate:&del delegateQueue:&dq forSelector:selector])
1933+
while (modifiedPresence && [delegateEnumerator getNextDelegate:&del delegateQueue:&dq forSelector:selector])
18961934
{
1935+
#if DEBUG
1936+
{
1937+
char methodReturnType[32];
1938+
1939+
Method method = class_getInstanceMethod([del class], selector);
1940+
method_getReturnType(method, methodReturnType, sizeof(methodReturnType));
1941+
1942+
if (strcmp(methodReturnType, @encode(XMPPPresence*)) != 0)
1943+
{
1944+
NSAssert(NO, @"Method xmppStream:willSendPresence: is no longer void (see XMPPStream.h). "
1945+
@"Culprit = %@", NSStringFromClass([del class]));
1946+
}
1947+
}
1948+
#endif
1949+
18971950
dispatch_sync(dq, ^{ @autoreleasepool {
18981951

1899-
[del xmppStream:self willSendPresence:presence];
1952+
modifiedPresence = [del xmppStream:self willSendPresence:modifiedPresence];
19001953

19011954
}});
19021955
}
19031956

1904-
dispatch_async(xmppQueue, ^{ @autoreleasepool {
1905-
1906-
if (state == STATE_XMPP_CONNECTED) {
1907-
[self continueSendPresence:presence withTag:tag];
1908-
}
1909-
}});
1910-
1957+
if (modifiedPresence)
1958+
{
1959+
dispatch_async(xmppQueue, ^{ @autoreleasepool {
1960+
1961+
if (state == STATE_XMPP_CONNECTED) {
1962+
[self continueSendPresence:presence withTag:tag];
1963+
}
1964+
}});
1965+
}
19111966
}});
19121967
}
19131968
}
@@ -2047,6 +2102,8 @@ - (void)sendElement:(NSXMLElement *)element withTag:(long)tag
20472102
**/
20482103
- (void)sendElement:(NSXMLElement *)element
20492104
{
2105+
if (element == nil) return;
2106+
20502107
dispatch_block_t block = ^{ @autoreleasepool {
20512108

20522109
if (state == STATE_XMPP_CONNECTED)
@@ -2070,6 +2127,8 @@ - (void)sendElement:(NSXMLElement *)element
20702127
**/
20712128
- (void)sendElement:(NSXMLElement *)element andGetReceipt:(XMPPElementReceipt **)receiptPtr
20722129
{
2130+
if (element == nil) return;
2131+
20732132
if (receiptPtr == nil)
20742133
{
20752134
[self sendElement:element];

Extensions/XEP-0115/XMPPCapabilities.m

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
// Log levels: off, error, warn, info, verbose
3737
// Log flags: trace
3838
#if DEBUG
39-
static const int xmppLogLevel = XMPP_LOG_LEVEL_VERBOSE; // | XMPP_LOG_FLAG_TRACE;
39+
static const int xmppLogLevel = XMPP_LOG_LEVEL_WARN;
4040
#else
4141
static const int xmppLogLevel = XMPP_LOG_LEVEL_WARN;
4242
#endif
@@ -1520,7 +1520,7 @@ - (BOOL)xmppStream:(XMPPStream *)sender didReceiveIQ:(XMPPIQ *)iq
15201520
return YES;
15211521
}
15221522

1523-
- (void)xmppStream:(XMPPStream *)sender willSendPresence:(XMPPPresence *)presence
1523+
- (XMPPPresence *)xmppStream:(XMPPStream *)sender willSendPresence:(XMPPPresence *)presence
15241524
{
15251525
// This method is invoked on the moduleQueue.
15261526

@@ -1546,6 +1546,8 @@ - (void)xmppStream:(XMPPStream *)sender willSendPresence:(XMPPPresence *)presenc
15461546
[presence addChild:c];
15471547
}
15481548
}
1549+
1550+
return presence;
15491551
}
15501552

15511553
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

Extensions/XEP-0153/XMPPvCardAvatarModule.m

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ - (void)xmppStreamDidAuthenticate:(XMPPStream *)sender {
157157
}
158158

159159

160-
- (void)xmppStream:(XMPPStream *)sender willSendPresence:(XMPPPresence *)presence {
160+
- (XMPPPresence *)xmppStream:(XMPPStream *)sender willSendPresence:(XMPPPresence *)presence {
161161
XMPPLogTrace();
162162

163163
// add our photo info to the presence stanza
@@ -176,6 +176,8 @@ - (void)xmppStream:(XMPPStream *)sender willSendPresence:(XMPPPresence *)presenc
176176
[presence addChild:xElement];
177177

178178
// Question: If photoElement is nil, should we be adding xElement?
179+
180+
return presence;
179181
}
180182

181183

Xcode/DesktopXMPP/AppDelegate.m

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ - (id)init
4242
xmppRosterStorage = [[XMPPRosterMemoryStorage alloc] init];
4343
xmppRoster = [[XMPPRoster alloc] initWithRosterStorage:xmppRosterStorage];
4444

45-
// xmppCapabilitiesStorage = [[XMPPCapabilitiesCoreDataStorage alloc] init];
45+
// xmppCapabilitiesStorage = [XMPPCapabilitiesCoreDataStorage sharedInstance];
4646
// xmppCapabilities = [[XMPPCapabilities alloc] initWithCapabilitiesStorage:xmppCapabilitiesStorage];
4747

4848
// xmppCapabilities.autoFetchHashedCapabilities = YES;

Xcode/DesktopXMPP/XMPPStream.xcodeproj/project.pbxproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1250,7 +1250,7 @@
12501250
"$(inherited)",
12511251
"\"$(SRCROOT)/../../Vendor/libidn\"",
12521252
);
1253-
MACOSX_DEPLOYMENT_TARGET = 10.8;
1253+
MACOSX_DEPLOYMENT_TARGET = 10.7;
12541254
PRODUCT_NAME = XMPPStream;
12551255
WRAPPER_EXTENSION = app;
12561256
};
@@ -1273,7 +1273,7 @@
12731273
"$(inherited)",
12741274
"\"$(SRCROOT)/../../Vendor/libidn\"",
12751275
);
1276-
MACOSX_DEPLOYMENT_TARGET = 10.8;
1276+
MACOSX_DEPLOYMENT_TARGET = 10.7;
12771277
PRODUCT_NAME = XMPPStream;
12781278
WRAPPER_EXTENSION = app;
12791279
};

0 commit comments

Comments
 (0)