diff --git a/Pod/Classes/Phoenix.h b/Pod/Classes/Phoenix.h index 416bf2e..9bc5269 100644 --- a/Pod/Classes/Phoenix.h +++ b/Pod/Classes/Phoenix.h @@ -14,7 +14,7 @@ @interface Phoenix : NSObject @property (nonatomic, strong, readonly) NSURL *url; -@property (nonatomic, assign) id delegate; +@property (nonatomic, weak) id delegate; - (instancetype)initWithURL:(NSURL*)url; @@ -37,6 +37,7 @@ @interface PhoenixChannel : NSObject typedef void(^HandleEventBlock)(id message); +typedef void(^HandleReplyBlock)(id reply); @property (nonatomic, strong, readonly) NSString *topic; @property (nonatomic, strong, readonly) NSDictionary *payload; @@ -47,7 +48,7 @@ typedef void(^HandleEventBlock)(id message); - (BOOL)join; - (BOOL)leave; -- (void)sendEvent:(NSString*)event payload:(id)payload; +- (void)sendEvent:(NSString*)event payload:(id)payload onReply:(HandleReplyBlock)handleReplyBlock; - (void)on:(NSString*)event handleEventBlock:(HandleEventBlock)handleEventBlock; diff --git a/Pod/Classes/Phoenix.m b/Pod/Classes/Phoenix.m index c00744a..c1fb965 100644 --- a/Pod/Classes/Phoenix.m +++ b/Pod/Classes/Phoenix.m @@ -14,6 +14,7 @@ @interface Phoenix() @property (nonatomic, strong) SRWebSocket *webSocket; @property (nonatomic, assign) BOOL isOpen; +@property (nonatomic, assign) NSInteger ref; @property (nonatomic, strong) NSMutableDictionary *channels; @@ -25,8 +26,9 @@ @interface Phoenix() @interface PhoenixChannel() @property (nonatomic, strong) NSMutableDictionary *listeners; +@property (nonatomic, strong) NSMutableDictionary *replyHandlers; -- (void)handleEvent:(NSString*)event withMessage:(id)message; +- (void)handleEvent:(NSString*)event withMessage:(id)message ref:(NSString *)ref; @end @@ -70,7 +72,7 @@ - (BOOL)joinChannel:(PhoenixChannel*)channel { _channels[channel.topic] = channel; // Joins channel - [self send:channel.topic event:@"join" payload:channel.payload]; + [self send:channel.topic event:@"phx_join" payload:channel.payload]; return YES; } @@ -84,7 +86,7 @@ - (BOOL)leaveChannel:(PhoenixChannel*)channel { [_channels removeObjectForKey:channel.topic]; // Leaves channel - [self send:channel.topic event:@"leave" payload:nil]; + [self send:channel.topic event:@"phx_leave" payload:nil]; return YES; } @@ -97,12 +99,13 @@ - (void)sendHeartbeat { #pragma mark - Helpers -- (void)send:(NSString*)topic event:(NSString*)event payload:(id)payload { - +- (NSString *)send:(NSString*)topic event:(NSString*)event payload:(id)payload { + NSString *ref = @(_ref++).stringValue; NSDictionary *message = @{ @"topic": topic, @"event": event, - @"payload": payload ?: [NSNull null] + @"payload": payload ?: [NSNull null], + @"ref": ref }; NSData *data = [NSJSONSerialization dataWithJSONObject:message options:0 error:nil]; @@ -115,7 +118,7 @@ - (void)send:(NSString*)topic event:(NSString*)event payload:(id)payload { [_delegate phoenix:self sentEvent:event onTopic:topic withPayload:payload]; } }]; - + return ref; } #pragma mark - SRWebSocketDelegate @@ -124,7 +127,8 @@ - (void)webSocket:(SRWebSocket *)webSocket didReceiveMessage:(id)message { NSDictionary *resp = [NSJSONSerialization JSONObjectWithData:[message dataUsingEncoding:NSUTF8StringEncoding] options:0 error:nil]; PhoenixChannel *channel = _channels[resp[@"topic"]]; - [channel handleEvent:resp[@"event"] withMessage:resp[@"payload"]]; + NSString *ref = [resp[@"ref"] isKindOfClass:[NSString class]] ? resp[@"ref"] : nil; + [channel handleEvent:resp[@"event"] withMessage:resp[@"payload"] ref:ref]; } - (void)webSocketDidOpen:(SRWebSocket *)webSocket { @@ -172,7 +176,8 @@ - (instancetype)initWithTopic:(NSString*)topic payload:(NSDictionary*)payload wi _payload = payload; _phoenix = phoenix; - _listeners = @{}.mutableCopy; + _listeners = [NSMutableDictionary new]; + _replyHandlers = [NSMutableDictionary new]; } return self; } @@ -187,8 +192,11 @@ - (BOOL)leave { return [_phoenix leaveChannel:self]; } -- (void)sendEvent:(NSString*)event payload:(id)payload { - [_phoenix send:_topic event:event payload:payload]; +- (void)sendEvent:(NSString*)event payload:(id)payload onReply:(HandleReplyBlock)handleReplyBlock { + NSString *msgRef = [_phoenix send:_topic event:event payload:payload]; + if (handleReplyBlock) { + _replyHandlers[msgRef] = handleReplyBlock; + } } - (void)on:(NSString*)event handleEventBlock:(HandleEventBlock)handleEventBlock { @@ -197,11 +205,19 @@ - (void)on:(NSString*)event handleEventBlock:(HandleEventBlock)handleEventBlock #pragma mark - Private -- (void)handleEvent:(NSString*)event withMessage:(id)message { +- (void)handleEvent:(NSString*)event withMessage:(id)message ref:(NSString *)ref { HandleEventBlock block = _listeners[event]; if (block) { block(message); } + + if (ref) { + HandleReplyBlock replyBlock = _replyHandlers[ref]; + if (replyBlock) { + replyBlock(message); + [_replyHandlers removeObjectForKey:ref]; + } + } } @end