From 0c38e014b794e82895b857448c4212aab9243113 Mon Sep 17 00:00:00 2001 From: Piotr Wegrzynek Date: Sat, 18 Nov 2017 14:04:16 +0100 Subject: [PATCH] Apply pull request review feedback Squashed commits: [73bf7ae] Rename XMPPElementEvent processingCompleted property [d1bbfce] Move XMPPElementEvent interface declaration to a separate header file [b7ac0a7] Use property syntax for XMPPStream currentElementEvent [ba381c4] Reorder XMPPStream sendElement method parameters --- Core/XMPP.h | 1 + Core/XMPPElementEvent.h | 80 ++++++++++++++++++++++ Core/XMPPStream.h | 89 +++---------------------- Core/XMPPStream.m | 12 ++-- XMPPFramework.xcodeproj/project.pbxproj | 8 +++ 5 files changed, 103 insertions(+), 87 deletions(-) create mode 100644 Core/XMPPElementEvent.h diff --git a/Core/XMPP.h b/Core/XMPP.h index 736e7a508e..6d4e4ffc9c 100644 --- a/Core/XMPP.h +++ b/Core/XMPP.h @@ -9,6 +9,7 @@ #import "XMPPMessage.h" #import "XMPPPresence.h" #import "XMPPModule.h" +#import "XMPPElementEvent.h" // // Authentication diff --git a/Core/XMPPElementEvent.h b/Core/XMPPElementEvent.h new file mode 100644 index 0000000000..dc4feddc81 --- /dev/null +++ b/Core/XMPPElementEvent.h @@ -0,0 +1,80 @@ +#import + +NS_ASSUME_NONNULL_BEGIN + +@class XMPPJID; + +/** + * A handle that allows identifying elements sent or received in the stream across different delegates + * and tracking their processing progress. + * + * While the core XMPP specification does not require stanzas to be uniquely identifiable, you may still want to + * identify them internally across different modules or trace the sent ones to the respective send result delegate callbacks. + * + * An instance of this class is provided in the context of execution of any of the @c didSendXXX/didFailToSendXXX/didReceiveXXX + * stream delegate methods. It is retrieved from the @c currentElementEvent property on the calling stream. + * The delegates can then use it to: + * - identify the corresponding XMPP stanzas. + * - be notified of asynchronous processing completion for a given XMPP stanza. + * + * Using @c XMPPElementEvent handles is a more robust approach than relying on pointer equality of @c XMPPElement instances. + */ +@interface XMPPElementEvent : NSObject + +/// The universally unique identifier of the event that provides the internal identity of the corresponding XMPP stanza. +@property (nonatomic, copy, readonly) NSString *uniqueID; + +/// The value of the stream's @c myJID property at the time when the event occured. +@property (nonatomic, strong, readonly, nullable) XMPPJID *myJID; + +/// The local device time when the event occured. +@property (nonatomic, strong, readonly) NSDate *timestamp; + +/** + * A flag indicating whether all delegates are done processing the given event. + * + * Supports Key-Value Observing. Change notifications are emitted on the stream queue. + * + * @see beginDelayedProcessing + * @see endDelayedProcessingWithToken + */ +@property (nonatomic, assign, readonly) BOOL isProcessingCompleted; + +// Instances are created by the stream only. +- (instancetype)init NS_UNAVAILABLE; + +/** + * Marks the event as being asynchronously processed by a delegate and returns a completion token. + * + * Event processing is completed after every @c beginDelayedProcessing call has been followed + * by @c endDelayedProcessingWithToken: with a matching completion token. + * + * Unpaired invocations may lead to undefined behavior or stalled events. + * + * Events that are not marked for asynchronous processing by any of the delegates complete immediately + * after control returns from all callbacks. + * + * @see endDelayedProcessingWithToken: + * @see isProcessingCompleted + */ +- (id)beginDelayedProcessing; + +/** + * Marks an end of the previously initiated asynchronous delegate processing. + * + * Event processing is completed after every @c beginDelayedProcessing call has been followed + * by @c endDelayedProcessingWithToken: with a matching completion token. + * + * Unpaired invocations may lead to undefined behavior or stalled events. + * + * Events that are not marked for asynchronous processing by any of the delegates complete immediately + * after control returns from all callbacks. + * + * @see beginDelayedProcessing + * @see isProcessingCompleted + */ +- (void)endDelayedProcessingWithToken:(id)delayedProcessingToken; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Core/XMPPStream.h b/Core/XMPPStream.h index 70dbea6212..84c7dbd005 100644 --- a/Core/XMPPStream.h +++ b/Core/XMPPStream.h @@ -646,7 +646,7 @@ extern const NSTimeInterval XMPPStreamTimeoutNone; * Even if you close the xmpp stream after this point, the OS will still do everything it can to send the data. **/ - (void)sendElement:(NSXMLElement *)element andGetReceipt:(XMPPElementReceipt * _Nullable * _Nullable)receiptPtr; -- (void)sendElement:(NSXMLElement *)element registeringEventWithID:(NSString *)eventID andGetReceipt:(XMPPElementReceipt * _Nullable * _Nullable)receiptPtr; +- (void)sendElement:(NSXMLElement *)element andGetReceipt:(XMPPElementReceipt * _Nullable * _Nullable)receiptPtr registeringEventWithID:(NSString *)eventID; /** * Fetches and resends the myPresence element (if available) in a single atomic operation. @@ -741,13 +741,13 @@ extern const NSTimeInterval XMPPStreamTimeoutNone; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** - * Returns the stream metadata corresponding to the currently processed XMPP stanza. + * The stream metadata corresponding to the currently processed XMPP stanza. * * Event information is only available in the context of @c didSendXXX/didFailToSendXXX/didReceiveXXX delegate callbacks. - * This method returns nil if called outside of those callbacks. + * This property is nil if accessed outside of those callbacks. * For more details, please refer to @c XMPPElementEvent documentation. */ -- (nullable XMPPElementEvent *)currentElementEvent; +@property (nonatomic, readonly, nullable) XMPPElementEvent *currentElementEvent; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #pragma mark Utilities @@ -801,79 +801,6 @@ extern const NSTimeInterval XMPPStreamTimeoutNone; @end -/** - * A handle that allows identifying elements sent or received in the stream across different delegates - * and tracking their processing progress. - * - * While the core XMPP specification does not require stanzas to be uniquely identifiable, you may still want to - * identify them internally across different modules or trace the sent ones to the respective send result delegate callbacks. - * - * An instance of this class is provided in the context of execution of any of the @c didSendXXX/didFailToSendXXX/didReceiveXXX - * stream delegate methods. It is retrieved by calling the @c currentElementEvent method on the calling stream. - * The delegates can then use it to: - * - identify the corresponding XMPP stanzas. - * - be notified of asynchronous processing completion for a given XMPP stanza. - * - * Using @c XMPPElementEvent handles is a more robust approach than relying on pointer equality of @c XMPPElement instances. - */ -@interface XMPPElementEvent : NSObject - -/// The universally unique identifier of the event that provides the internal identity of the corresponding XMPP stanza. -@property (nonatomic, copy, readonly) NSString *uniqueID; - -/// The value of the stream's @c myJID property at the time when the event occured. -@property (nonatomic, strong, readonly, nullable) XMPPJID *myJID; - -/// The local device time when the event occured. -@property (nonatomic, strong, readonly) NSDate *timestamp; - -/** - * A flag indicating whether all delegates are done processing the given event. - * - * Supports Key-Value Observing. Change notifications are emitted on the stream queue. - * - * @see beginDelayedProcessing - * @see endDelayedProcessingWithToken - */ -@property (nonatomic, assign, readonly, getter=isProcessingCompleted) BOOL processingCompleted; - -// Instances are created by the stream only. -- (instancetype)init NS_UNAVAILABLE; - -/** - * Marks the event as being asynchronously processed by a delegate and returns a completion token. - * - * Event processing is completed after every @c beginDelayedProcessing call has been followed - * by @c endDelayedProcessingWithToken: with a matching completion token. - * - * Unpaired invocations may lead to undefined behavior or stalled events. - * - * Events that are not marked for asynchronous processing by any of the delegates complete immediately - * after control returns from all callbacks. - * - * @see endDelayedProcessingWithToken: - * @see processingCompleted - */ -- (id)beginDelayedProcessing; - -/** - * Marks an end of the previously initiated asynchronous delegate processing. - * - * Event processing is completed after every @c beginDelayedProcessing call has been followed - * by @c endDelayedProcessingWithToken: with a matching completion token. - * - * Unpaired invocations may lead to undefined behavior or stalled events. - * - * Events that are not marked for asynchronous processing by any of the delegates complete immediately - * after control returns from all callbacks. - * - * @see beginDelayedProcessing - * @see processingCompleted - */ -- (void)endDelayedProcessingWithToken:(id)delayedProcessingToken; - -@end - //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #pragma mark - //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -1077,7 +1004,7 @@ extern const NSTimeInterval XMPPStreamTimeoutNone; * If you have need to modify an element for any reason, * you should copy the element first, and then modify and use the copy. * - * Delegates can obtain event metadata associated with the respective element by calling @c currentElementEvent on @c sender + * Delegates can obtain event metadata associated with the respective element by accessing @c currentElementEvent on @c sender * from within these callbacks. For more details, please refer to @c XMPPElementEvent documentation. **/ - (BOOL)xmppStream:(XMPPStream *)sender didReceiveIQ:(XMPPIQ *)iq; @@ -1125,7 +1052,7 @@ extern const NSTimeInterval XMPPStreamTimeoutNone; * These methods may be used to listen for certain events (such as an unavailable presence having been sent), * or for general logging purposes. (E.g. a central history logging mechanism). * - * Delegates can obtain event metadata associated with the respective element by calling @c currentElementEvent on @c sender + * Delegates can obtain event metadata associated with the respective element by accessing @c currentElementEvent on @c sender * from within these callbacks. For more details, please refer to @c XMPPElementEvent documentation. **/ - (void)xmppStream:(XMPPStream *)sender didSendIQ:(XMPPIQ *)iq; @@ -1136,7 +1063,7 @@ extern const NSTimeInterval XMPPStreamTimeoutNone; * These methods are called after failing to send the respective XML elements over the stream. * This occurs when the stream gets disconnected before the element can get sent out. * - * Delegates can obtain event metadata associated with the respective element by calling @c currentElementEvent on @c sender + * Delegates can obtain event metadata associated with the respective element by accessing @c currentElementEvent on @c sender * from within these callbacks. * Note that if these methods are called, the event context is incomplete, e.g. the stream might have not been connected * and the actual myJID value is not determined. For more details, please refer to @c XMPPElementEvent documentation. @@ -1244,7 +1171,7 @@ NS_SWIFT_NAME(xmppStream(_:didFinishProcessing:)); * If you're using custom elements, you must register the custom element name(s). * Otherwise the xmppStream will treat non-XMPP elements as errors (xmppStream:didReceiveError:). * - * Delegates can obtain event metadata associated with the respective element by calling @c currentElementEvent on @c sender + * Delegates can obtain event metadata associated with the respective element by accessing @c currentElementEvent on @c sender * from within these callbacks. For more details, please refer to @c XMPPElementEvent documentation. * * @see registerCustomElementNames (in XMPPInternal.h) diff --git a/Core/XMPPStream.m b/Core/XMPPStream.m index d5f8011e66..465b7724f5 100644 --- a/Core/XMPPStream.m +++ b/Core/XMPPStream.m @@ -156,7 +156,7 @@ - (void)signalFailure; @interface XMPPElementEvent () @property (nonatomic, unsafe_unretained, readonly) XMPPStream *xmppStream; -@property (nonatomic, assign, readwrite, getter=isProcessingCompleted) BOOL processingCompleted; +@property (nonatomic, assign, readwrite) BOOL isProcessingCompleted; @end @@ -2639,12 +2639,12 @@ - (void)sendElement:(NSXMLElement *)element withTag:(long)tag registeringEventWi **/ - (void)sendElement:(NSXMLElement *)element { - [self sendElement:element registeringEventWithID:[self generateUUID] andGetReceipt:nil]; + [self sendElement:element andGetReceipt:nil registeringEventWithID:[self generateUUID]]; } - (void)sendElement:(NSXMLElement *)element andGetReceipt:(XMPPElementReceipt **)receiptPtr { - [self sendElement:element registeringEventWithID:[self generateUUID] andGetReceipt:receiptPtr]; + [self sendElement:element andGetReceipt:receiptPtr registeringEventWithID:[self generateUUID]]; } /** @@ -2654,7 +2654,7 @@ - (void)sendElement:(NSXMLElement *)element andGetReceipt:(XMPPElementReceipt ** * After the element has been successfully sent, * the xmppStream:didSendElementWithTag: delegate method is called. **/ -- (void)sendElement:(NSXMLElement *)element registeringEventWithID:(NSString *)eventID andGetReceipt:(XMPPElementReceipt **)receiptPtr +- (void)sendElement:(NSXMLElement *)element andGetReceipt:(XMPPElementReceipt **)receiptPtr registeringEventWithID:(NSString *)eventID { if (element == nil) return; @@ -5155,7 +5155,7 @@ - (void)performDelegateActionWithElementEvent:(XMPPElementEvent *)event block:(d [eventProcessingDelegateInvocationContext becomeCurrentOnQueue:self.xmppQueue forActionWithBlock:block]; dispatch_group_notify(eventProcessingDelegateInvocationContext.continuityGroup, self.xmppQueue, ^{ - event.processingCompleted = YES; + event.isProcessingCompleted = YES; [multicastDelegate xmppStream:self didFinishProcessingElementEvent:event]; }); } @@ -5265,7 +5265,7 @@ - (BOOL)isProcessingCompleted __block BOOL result; dispatch_block_t block = ^{ - result = _processingCompleted; + result = _isProcessingCompleted; }; if (dispatch_get_specific(self.xmppStream.xmppQueueTag)) diff --git a/XMPPFramework.xcodeproj/project.pbxproj b/XMPPFramework.xcodeproj/project.pbxproj index a0b10483fd..2979748832 100644 --- a/XMPPFramework.xcodeproj/project.pbxproj +++ b/XMPPFramework.xcodeproj/project.pbxproj @@ -65,6 +65,9 @@ 0D44BB721E537110000930E0 /* XMPPStringPrep.m in Sources */ = {isa = PBXBuildFile; fileRef = 0D44BB641E537110000930E0 /* XMPPStringPrep.m */; }; 0D44BB731E537110000930E0 /* XMPPTimer.h in Headers */ = {isa = PBXBuildFile; fileRef = 0D44BB651E537110000930E0 /* XMPPTimer.h */; settings = {ATTRIBUTES = (Public, ); }; }; 0D44BB741E537110000930E0 /* XMPPTimer.m in Sources */ = {isa = PBXBuildFile; fileRef = 0D44BB661E537110000930E0 /* XMPPTimer.m */; }; + 249704751FC0680900D25EC6 /* XMPPElementEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = 249704731FC0680900D25EC6 /* XMPPElementEvent.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 249704761FC0680900D25EC6 /* XMPPElementEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = 249704731FC0680900D25EC6 /* XMPPElementEvent.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 249704771FC0680900D25EC6 /* XMPPElementEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = 249704731FC0680900D25EC6 /* XMPPElementEvent.h */; settings = {ATTRIBUTES = (Public, ); }; }; D96D6E7D1F8D9701006DEC58 /* XMPPPushModule.m in Sources */ = {isa = PBXBuildFile; fileRef = D96D6E7C1F8D9701006DEC58 /* XMPPPushModule.m */; }; D96D6E7E1F8D9701006DEC58 /* XMPPPushModule.m in Sources */ = {isa = PBXBuildFile; fileRef = D96D6E7C1F8D9701006DEC58 /* XMPPPushModule.m */; }; D96D6E7F1F8D9701006DEC58 /* XMPPPushModule.m in Sources */ = {isa = PBXBuildFile; fileRef = D96D6E7C1F8D9701006DEC58 /* XMPPPushModule.m */; }; @@ -1261,6 +1264,7 @@ 0D44BB641E537110000930E0 /* XMPPStringPrep.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = XMPPStringPrep.m; sourceTree = ""; }; 0D44BB651E537110000930E0 /* XMPPTimer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = XMPPTimer.h; sourceTree = ""; }; 0D44BB661E537110000930E0 /* XMPPTimer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = XMPPTimer.m; sourceTree = ""; }; + 249704731FC0680900D25EC6 /* XMPPElementEvent.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = XMPPElementEvent.h; sourceTree = ""; }; D96D6E6C1F8D9700006DEC58 /* XMPPPushModule.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = XMPPPushModule.h; sourceTree = ""; }; D96D6E7C1F8D9701006DEC58 /* XMPPPushModule.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = XMPPPushModule.m; sourceTree = ""; }; D9DCD11F1E6250920010D1C7 /* XMPPBandwidthMonitor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = XMPPBandwidthMonitor.h; sourceTree = ""; }; @@ -1617,6 +1621,7 @@ 0D44BB0A1E5370ED000930E0 /* XMPPPresence.m */, 0D44BB0B1E5370ED000930E0 /* XMPPStream.h */, 0D44BB0C1E5370ED000930E0 /* XMPPStream.m */, + 249704731FC0680900D25EC6 /* XMPPElementEvent.h */, ); path = Core; sourceTree = SOURCE_ROOT; @@ -2557,6 +2562,7 @@ D9DCD3241E6250930010D1C7 /* XMPPMessage+XEP_0334.h in Headers */, D96D6E801F8D970E006DEC58 /* XMPPPushModule.h in Headers */, D9DCD3281E6250930010D1C7 /* NSXMLElement+XEP_0352.h in Headers */, + 249704751FC0680900D25EC6 /* XMPPElementEvent.h in Headers */, D9DCD2541E6250930010D1C7 /* XMPPOutgoingFileTransfer.h in Headers */, D9DCD2561E6250930010D1C7 /* XMPPGoogleSharedStatus.h in Headers */, D9DCD2B61E6250930010D1C7 /* XMPPvCardTemp.h in Headers */, @@ -2718,6 +2724,7 @@ D9DCD4A51E6256D90010D1C7 /* XMPPMessage+XEP_0334.h in Headers */, D96D6E811F8D970E006DEC58 /* XMPPPushModule.h in Headers */, D9DCD4A61E6256D90010D1C7 /* NSXMLElement+XEP_0352.h in Headers */, + 249704761FC0680900D25EC6 /* XMPPElementEvent.h in Headers */, D9DCD4A71E6256D90010D1C7 /* XMPPOutgoingFileTransfer.h in Headers */, D9DCD4A81E6256D90010D1C7 /* XMPPGoogleSharedStatus.h in Headers */, D9DCD4A91E6256D90010D1C7 /* XMPPvCardTemp.h in Headers */, @@ -2879,6 +2886,7 @@ D9DCD6081E6258CF0010D1C7 /* XMPPMessage+XEP_0334.h in Headers */, D96D6E821F8D970F006DEC58 /* XMPPPushModule.h in Headers */, D9DCD6091E6258CF0010D1C7 /* NSXMLElement+XEP_0352.h in Headers */, + 249704771FC0680900D25EC6 /* XMPPElementEvent.h in Headers */, D9DCD60A1E6258CF0010D1C7 /* XMPPOutgoingFileTransfer.h in Headers */, D9DCD60B1E6258CF0010D1C7 /* XMPPGoogleSharedStatus.h in Headers */, D9DCD60C1E6258CF0010D1C7 /* XMPPvCardTemp.h in Headers */,