// // This file is for XMPPStream and various internal components. // #import "XMPPStream.h" #import "XMPPModule.h" // Define the various states we'll use to track our progress typedef NS_ENUM(NSInteger, XMPPStreamState) { STATE_XMPP_DISCONNECTED, STATE_XMPP_RESOLVING_SRV, STATE_XMPP_CONNECTING, STATE_XMPP_OPENING, STATE_XMPP_NEGOTIATING, STATE_XMPP_STARTTLS_1, STATE_XMPP_STARTTLS_2, STATE_XMPP_POST_NEGOTIATION, STATE_XMPP_REGISTERING, STATE_XMPP_AUTH, STATE_XMPP_BINDING, STATE_XMPP_START_SESSION, STATE_XMPP_CONNECTED, }; /** * It is recommended that storage classes cache a stream's myJID. * This prevents them from constantly querying the property from the xmppStream instance, * as doing so goes through xmppStream's dispatch queue. * Caching the stream's myJID frees the dispatch queue to handle xmpp processing tasks. * * The object of the notification will be the XMPPStream instance. * * Note: We're not using the typical MulticastDelegate paradigm for this task as * storage classes are not typically added as a delegate of the xmppStream. **/ extern NSString *const XMPPStreamDidChangeMyJIDNotification; @interface XMPPStream (/* Internal */) /** * XMPPStream maintains thread safety by dispatching through the internal serial xmppQueue. * Subclasses of XMPPStream MUST follow the same technique: * * dispatch_block_t block = ^{ * // Code goes here * }; * * if (dispatch_get_specific(xmppQueueTag)) * block(); * else * dispatch_sync(xmppQueue, block); * * Category methods may or may not need to dispatch through the xmppQueue. * It depends entirely on what properties of xmppStream the category method needs to access. * For example, if a category only accesses a single property, such as the rootElement, * then it can simply fetch the atomic property, inspect it, and complete its job. * However, if the category needs to fetch multiple properties, then it likely needs to fetch all such * properties in an atomic fashion. In this case, the category should likely go through the xmppQueue, * to ensure that it gets an atomic state of the xmppStream in order to complete its job. **/ @property (nonatomic, readonly) dispatch_queue_t xmppQueue; @property (nonatomic, readonly) void *xmppQueueTag; /** * Returns the current state of the xmppStream. **/ @property (atomic, readonly) XMPPStreamState state; /** * This method is for use by xmpp authentication mechanism classes. * They should send elements using this method instead of the public sendElement methods, * as those methods don't send the elements while authentication is in progress. * * @see XMPPSASLAuthentication **/ - (void)sendAuthElement:(NSXMLElement *)element; /** * This method is for use by xmpp custom binding classes. * They should send elements using this method instead of the public sendElement methods, * as those methods don't send the elements while authentication/binding is in progress. * * @see XMPPCustomBinding **/ - (void)sendBindElement:(NSXMLElement *)element; /** * This method allows you to inject an element into the stream as if it was received on the socket. * This is an advanced technique, but makes for some interesting possibilities. **/ - (void)injectElement:(NSXMLElement *)element; /** * The XMPP standard only supports , and stanzas (excluding session setup stuff). * But some extensions use non-standard element types. * The standard example is XEP-0198, which uses & elements. * * XMPPStream will assume that any non-standard element types are errors, unless you register them. * Once registered the stream can recognize them, and will use the following delegate methods: * * xmppStream:didSendCustomElement: * xmppStream:didReceiveCustomElement: **/ - (void)registerCustomElementNames:(NSSet *)names; - (void)unregisterCustomElementNames:(NSSet *)names; @end @interface XMPPModule (/* Internal */) /** * Used internally by methods like XMPPStream's unregisterModule:. * Normally removing a delegate is a synchronous operation, but due to multiple dispatch_sync operations, * it must occasionally be done asynchronously to avoid deadlock. **/ - (void)removeDelegate:(id)delegate delegateQueue:(dispatch_queue_t)delegateQueue synchronously:(BOOL)synchronously; @end