-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
19 changed files
with
950 additions
and
21 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
#import "XMPPModule.h" | ||
|
||
NS_ASSUME_NONNULL_BEGIN | ||
|
||
@class XMPPMessage; | ||
|
||
/// @brief A module that handles one-to-one chat messaging. | ||
/// @discussion This module triggers delegate callbacks for all sent or received messages of type 'chat'. | ||
@interface XMPPOneToOneChat : XMPPModule | ||
|
||
@end | ||
|
||
/// A protocol defining @c XMPPOneToOneChat module delegate API. | ||
@protocol XMPPOneToOneChatDelegate <NSObject> | ||
|
||
@optional | ||
/// Notifies the delegate that a chat message has been received in the stream. | ||
- (void)xmppOneToOneChat:(XMPPOneToOneChat *)xmppOneToOneChat didReceiveChatMessage:(XMPPMessage *)message | ||
NS_SWIFT_NAME(xmppOneToOneChat(_:didReceiveChatMessage:)); | ||
|
||
/// Notifies the delegate that a chat message has been sent in the stream. | ||
- (void)xmppOneToOneChat:(XMPPOneToOneChat *)xmppOneToOneChat didSendChatMessage:(XMPPMessage *)message | ||
NS_SWIFT_NAME(xmppOneToOneChat(_:didSendChatMessage:)); | ||
|
||
@end | ||
|
||
NS_ASSUME_NONNULL_END |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
#import "XMPPOneToOneChat.h" | ||
#import "XMPPMessage.h" | ||
#import "XMPPStream.h" | ||
#import "XMPPLogging.h" | ||
|
||
// Log levels: off, error, warn, info, verbose | ||
// Log flags: trace | ||
#if DEBUG | ||
static const int xmppLogLevel = XMPP_LOG_LEVEL_WARN; // | XMPP_LOG_FLAG_TRACE; | ||
#else | ||
static const int xmppLogLevel = XMPP_LOG_LEVEL_WARN; | ||
#endif | ||
|
||
@implementation XMPPOneToOneChat | ||
|
||
- (void)xmppStream:(XMPPStream *)sender didReceiveMessage:(XMPPMessage *)message | ||
{ | ||
XMPPLogTrace(); | ||
|
||
if (![message isChatMessage]) { | ||
return; | ||
} | ||
|
||
XMPPLogInfo(@"Received chat message from %@", [message from]); | ||
[multicastDelegate xmppOneToOneChat:self didReceiveChatMessage:message]; | ||
} | ||
|
||
- (void)xmppStream:(XMPPStream *)sender didSendMessage:(XMPPMessage *)message | ||
{ | ||
XMPPLogTrace(); | ||
|
||
if (![message isChatMessage]) { | ||
return; | ||
} | ||
|
||
XMPPLogInfo(@"Sent chat message to %@", [message to]); | ||
[multicastDelegate xmppOneToOneChat:self didSendChatMessage:message]; | ||
} | ||
|
||
@end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
34 changes: 34 additions & 0 deletions
34
Extensions/XEP-0198/Managed Messaging/XMPPManagedMessaging.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
#import "XMPPModule.h" | ||
|
||
NS_ASSUME_NONNULL_BEGIN | ||
|
||
@class XMPPMessage; | ||
|
||
/** | ||
A module working in tandem with @c XMPPStreamManagement to trace outgoing message stream acknowledgements. | ||
This module only monitors messages with @c elementID assigned. The rationale behind this is that any potential retransmissions | ||
of messages without IDs will cause deduplication issues on the receiving end. | ||
*/ | ||
@interface XMPPManagedMessaging : XMPPModule | ||
|
||
@end | ||
|
||
/// A protocol defining @c XMPPManagedMessaging module delegate API. | ||
@protocol XMPPManagedMessagingDelegate <NSObject> | ||
|
||
@optional | ||
|
||
/// Notifies the delegate that a message subject to monitoring has been sent in the stream. | ||
- (void)xmppManagedMessaging:(XMPPManagedMessaging *)sender didBeginMonitoringOutgoingMessage:(XMPPMessage *)message; | ||
|
||
/// Notifies the delegate that @c XMPPStreamManagement module has received server acknowledgement for sent messages with given IDs. | ||
- (void)xmppManagedMessaging:(XMPPManagedMessaging *)sender didConfirmSentMessagesWithIDs:(NSArray<NSString *> *)messageIDs; | ||
|
||
/// @brief Notifies the delegate that post-reauthentication message acknowledgement processing is finished. | ||
/// At this point, no more acknowledgements for currently monitored messages are to be expected. | ||
- (void)xmppManagedMessagingDidFinishProcessingPreviousStreamConfirmations:(XMPPManagedMessaging *)sender; | ||
|
||
@end | ||
|
||
NS_ASSUME_NONNULL_END |
112 changes: 112 additions & 0 deletions
112
Extensions/XEP-0198/Managed Messaging/XMPPManagedMessaging.m
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
#import "XMPPManagedMessaging.h" | ||
#import "XMPPStreamManagement.h" | ||
#import "XMPPLogging.h" | ||
|
||
// Log levels: off, error, warn, info, verbose | ||
// Log flags: trace | ||
#if DEBUG | ||
static const int xmppLogLevel = XMPP_LOG_LEVEL_WARN; // | XMPP_LOG_FLAG_TRACE; | ||
#else | ||
static const int xmppLogLevel = XMPP_LOG_LEVEL_WARN; | ||
#endif | ||
|
||
static NSString * const XMPPManagedMessagingURLScheme = @"xmppmanagedmessage"; | ||
|
||
@implementation XMPPManagedMessaging | ||
|
||
- (void)didActivate | ||
{ | ||
XMPPLogTrace(); | ||
[self.xmppStream autoAddDelegate:self delegateQueue:self.moduleQueue toModulesOfClass:[XMPPStreamManagement class]]; | ||
} | ||
|
||
- (void)willDeactivate | ||
{ | ||
XMPPLogTrace(); | ||
[self.xmppStream removeAutoDelegate:self delegateQueue:self.moduleQueue fromModulesOfClass:[XMPPStreamManagement class]]; | ||
} | ||
|
||
- (void)xmppStream:(XMPPStream *)sender didSendMessage:(XMPPMessage *)message | ||
{ | ||
XMPPLogTrace(); | ||
|
||
if (![message elementID]) { | ||
XMPPLogWarn(@"Sent message without an ID excluded from managed messaging"); | ||
return; | ||
} | ||
|
||
XMPPLogInfo(@"Registering message with ID=%@ for managed messaging", [message elementID]); | ||
[multicastDelegate xmppManagedMessaging:self didBeginMonitoringOutgoingMessage:message]; | ||
} | ||
|
||
- (id)xmppStreamManagement:(XMPPStreamManagement *)sender stanzaIdForSentElement:(XMPPElement *)element | ||
{ | ||
if (![element isKindOfClass:[XMPPMessage class]] || ![element elementID]) { | ||
return nil; | ||
} | ||
|
||
NSURLComponents *managedMessageURLComponents = [[NSURLComponents alloc] init]; | ||
managedMessageURLComponents.scheme = XMPPManagedMessagingURLScheme; | ||
managedMessageURLComponents.path = [element elementID]; | ||
|
||
return managedMessageURLComponents.URL; | ||
} | ||
|
||
- (void)xmppStreamManagement:(XMPPStreamManagement *)sender didReceiveAckForStanzaIds:(NSArray *)stanzaIds | ||
{ | ||
XMPPLogTrace(); | ||
|
||
NSArray *resumeStanzaIDs; | ||
[sender didResumeWithAckedStanzaIds:&resumeStanzaIDs serverResponse:nil]; | ||
if ([resumeStanzaIDs isEqualToArray:stanzaIds]) { | ||
// Handled in -xmppStreamDidAuthenticate: | ||
return; | ||
} | ||
|
||
[self processStreamManagementAcknowledgementForStanzaIDs:stanzaIds]; | ||
} | ||
|
||
- (void)xmppStreamDidAuthenticate:(XMPPStream *)sender | ||
{ | ||
XMPPLogTrace(); | ||
|
||
dispatch_group_t stanzaAcknowledgementGroup = dispatch_group_create(); | ||
|
||
[sender enumerateModulesOfClass:[XMPPStreamManagement class] withBlock:^(XMPPModule *module, NSUInteger idx, BOOL *stop) { | ||
NSArray *acknowledgedStanzaIDs; | ||
[(XMPPStreamManagement *)module didResumeWithAckedStanzaIds:&acknowledgedStanzaIDs serverResponse:nil]; | ||
if (acknowledgedStanzaIDs.count == 0) { | ||
return; | ||
} | ||
|
||
dispatch_group_async(stanzaAcknowledgementGroup, self.moduleQueue, ^{ | ||
[self processStreamManagementAcknowledgementForStanzaIDs:acknowledgedStanzaIDs]; | ||
}); | ||
}]; | ||
|
||
dispatch_group_notify(stanzaAcknowledgementGroup, self.moduleQueue, ^{ | ||
[multicastDelegate xmppManagedMessagingDidFinishProcessingPreviousStreamConfirmations:self]; | ||
}); | ||
} | ||
|
||
- (void)processStreamManagementAcknowledgementForStanzaIDs:(NSArray *)stanzaIDs | ||
{ | ||
NSMutableArray *managedMessageIDs = [NSMutableArray array]; | ||
for (id stanzaID in stanzaIDs) { | ||
if (![stanzaID isKindOfClass:[NSURL class]] || ![((NSURL *)stanzaID).scheme isEqualToString:XMPPManagedMessagingURLScheme]) { | ||
continue; | ||
} | ||
// Extracting path directly from NSURL does not work if it doesn't start with "/" | ||
NSURLComponents *managedMessageURLComponents = [[NSURLComponents alloc] initWithURL:stanzaID resolvingAgainstBaseURL:NO]; | ||
[managedMessageIDs addObject:managedMessageURLComponents.path]; | ||
} | ||
|
||
if (managedMessageIDs.count == 0) { | ||
return; | ||
} | ||
|
||
XMPPLogInfo(@"Confirming managed messages with IDs={%@}", [managedMessageIDs componentsJoinedByString:@","]); | ||
[multicastDelegate xmppManagedMessaging:self didConfirmSentMessagesWithIDs:managedMessageIDs]; | ||
} | ||
|
||
@end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,13 @@ | ||
#import <Foundation/Foundation.h> | ||
@import KissXML; | ||
|
||
@class XMPPJID; | ||
|
||
@interface NSXMLElement (XEP_0203) | ||
|
||
@property (nonatomic, readonly) BOOL wasDelayed; | ||
@property (nonatomic, readonly, nullable) NSDate *delayedDeliveryDate; | ||
@property (nonatomic, readonly, nullable) XMPPJID *delayedDeliveryFrom; | ||
@property (nonatomic, readonly, nullable) NSString *delayedDeliveryReasonDescription; | ||
|
||
@end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.