Permalink
Browse files

Merge pull request #69 from binarybucks/xep-0224

Added XEP-0224
  • Loading branch information...
2 parents 7ade49d + 7a4b4cf commit 2075ebd2337c9a7cbd5869cf3e3ecb59a97a5fb2 @robbiehanson committed Aug 1, 2012
@@ -0,0 +1,22 @@
+#import "XMPPModule.h"
+#import "XMPPMessage+XEP_0224.h"
+
+@interface XMPPAttentionModule : XMPPModule {
+ BOOL respondsToQueries;
+}
+
+/**
+ * Whether or not the module should respond to incoming attention request queries.
+ * It you create multiple instances of this module, only one instance should respond to queries.
+ *
+ * It is recommended you set this (if needed) before you activate the module.
+ * The default value is YES.
+ **/
+@property (readwrite) BOOL respondsToQueries;
+
+@end
+
+@protocol XMPPAttentionDelegate
+@optional
+- (void)xmppAttention:(XMPPAttentionModule *)sender didReceiveAttentionHeadlineMessage:(XMPPMessage *)attentionRequest;
+@end
@@ -0,0 +1,128 @@
+#import "XMPPAttentionModule.h"
+
+#if ! __has_feature(objc_arc)
+#warning This file must be compiled with ARC. Use -fobjc-arc flag (or convert project to ARC).
+#endif
+
+@implementation XMPPAttentionModule
+
+- (id)init
+{
+ return [self initWithDispatchQueue:NULL];
+}
+
+- (id)initWithDispatchQueue:(dispatch_queue_t)queue
+{
+ if ((self = [super initWithDispatchQueue:queue]))
+ {
+ respondsToQueries = YES;
+ }
+ return self;
+}
+
+- (BOOL)activate:(XMPPStream *)aXmppStream
+{
+ if ([super activate:aXmppStream])
+ {
+#ifdef _XMPP_CAPABILITIES_H
+ [xmppStream autoAddDelegate:self delegateQueue:moduleQueue toModulesOfClass:[XMPPCapabilities class]];
+#endif
+ return YES;
+ }
+
+ return NO;
+}
+
+- (void)deactivate
+{
+#ifdef _XMPP_CAPABILITIES_H
+ [xmppStream removeAutoDelegate:self delegateQueue:moduleQueue fromModulesOfClass:[XMPPCapabilities class]];
+#endif
+
+ [super deactivate];
+}
+
+- (BOOL)respondsToQueries
+{
+ if (dispatch_get_current_queue() == moduleQueue)
+ {
+ return respondsToQueries;
+ }
+ else
+ {
+ __block BOOL result;
+
+ dispatch_sync(moduleQueue, ^{
+ result = respondsToQueries;
+ });
+ return result;
+ }
+}
+
+- (void)setRespondsToQueries:(BOOL)flag
+{
+ dispatch_block_t block = ^{
+
+ if (respondsToQueries != flag)
+ {
+ respondsToQueries = flag;
+
+#ifdef _XMPP_CAPABILITIES_H
+ @autoreleasepool {
+ // Capabilities may have changed, need to notify others.
+ [xmppStream resendMyPresence];
+ }
+#endif
+ }
+ };
+
+ if (dispatch_get_current_queue() == moduleQueue)
+ block();
+ else
+ dispatch_async(moduleQueue, block);
+}
+
+
+- (BOOL)xmppStream:(XMPPStream *)sender didReceiveMessage:(XMPPMessage *)message
+{
+ // This method is invoked on the moduleQueue.
+
+ // Format of an attention message. Body is optional and not used by clients like Pidgin
+ // <message from='calvin@usrobots.lit/lab' to='herbie@usrobots.lit/home' type='headline'>
+ // <attention xmlns='urn:xmpp:attention:0'/>
+ // <body>Why don't you answer, Herbie?</body>
+ // </message>
+
+ if ([message isAttentionMessage])
+ {
+ [multicastDelegate xmppAttention:self didReceiveAttentionHeadlineMessage:message];
+ }
+ return YES;
+}
+
+
+#ifdef _XMPP_CAPABILITIES_H
+/**
+ * If an XMPPCapabilites instance is used we want to advertise our support for attention requests.
+ **/
+- (void)xmppCapabilities:(XMPPCapabilities *)sender collectingMyCapabilities:(NSXMLElement *)query
+{
+ // This method is invoked on the moduleQueue.
+
+ if (respondsToQueries)
+ {
+ // <query xmlns="http://jabber.org/protocol/disco#info">
+ // ...
+ // <feature var="urn:xmpp:attention:0"/>
+ // ...
+ // </query>
+
+ NSXMLElement *feature = [NSXMLElement elementWithName:@"feature"];
+ [feature addAttributeWithName:@"var" stringValue:XMLNS_ATTENTION];
+
+ [query addChild:feature];
+ }
+}
+#endif
+
+@end
@@ -0,0 +1,8 @@
+#import "XMPPMessage.h"
+#define XMLNS_ATTENTION @"urn:xmpp:attention:0"
+
+@interface XMPPMessage (XEP_0224)
+- (BOOL)isHeadLineMessage;
+- (BOOL)isAttentionMessage;
+- (BOOL)isAttentionMessageWithBody;
+@end
@@ -0,0 +1,23 @@
+#import "XMPPMessage+XEP_0224.h"
+
+@implementation XMPPMessage (XEP_0224)
+
+- (BOOL)isHeadLineMessage {
+ return [[[self attributeForName:@"type"] stringValue] isEqualToString:@"headline"];
+}
+
+- (BOOL)isAttentionMessage
+{
+ return [self isHeadLineMessage] && [self elementForName:@"attention" xmlns:XMLNS_ATTENTION];
+}
+
+- (BOOL)isAttentionMessageWithBody
+{
+ if([self isAttentionMessage])
+ {
+ return [self isMessageWithBody];
+ }
+ return NO;
+}
+
+@end

0 comments on commit 2075ebd

Please sign in to comment.