Advertisement
Guest User

Untitled

a guest
Oct 25th, 2016
98
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. //
  2. //  LETChatService.m
  3. //  Lets
  4. //
  5. //  Created by Surik Sarkisyan on 15.06.16.
  6. //  Copyright © 2016 Lets. All rights reserved.
  7. //
  8.  
  9. #import "LETChatService.h"
  10.  
  11. #import "LETChatServiceDelegate.h"
  12.  
  13. #import "LETPairUser.h"
  14. #import "LETChatSessionsCollector.h"
  15. #import "LETMappingServiceProtocol.h"
  16. #import "LETChatMessagesCollector.h"
  17. #import "LETChatSession.h"
  18.  
  19. #import <XMLDictionary/XMLDictionary.h>
  20. #import <DateTools/NSDate+DateTools.h>
  21.  
  22. typedef NS_ENUM(NSUInteger, LETOperationType)
  23. {
  24.     LETOperationTypeUnknown = 0,
  25.     LETOperationTypeCreateConnection = 1,
  26.     LETOperationTypeSendMessage = 2,
  27.     LETOperationTypeChatSessions = 3,
  28.     LETOperationTypeChatHistory = 4,
  29. };
  30.  
  31. static NSString *const kLETURLKey = @"url";
  32. static NSString *const kLETImageURLStringFormat = @"<image>%@</image>";
  33.  
  34. static NSString *const kLETXMPPArchiveKey = @"urn:xmpp:archive";
  35. static NSString *const kLETXMPPListKey = @"list";
  36. static NSString *const kLETXMPPWithKey = @"with";
  37. static NSString *const kLETXMPPGetKey = @"get";
  38. static NSString *const kLETXMPPRSMKey = @"http://jabber.org/protocol/rsm";
  39. static NSString *const kLETXMPPShowKey = @"show";
  40. static NSString *const kLETXMPPChatKey = @"chat";
  41. static NSString *const kLETXMPPAvailableKey = @"Available";
  42. static NSString *const kLETXMPPStatusKey = @"status";
  43. static NSString *const kLETXMPPStartKey = @"start";
  44. static NSString *const kLETXMPPIQKey = @"iq";
  45. static NSString *const kLETXMPPRetrieveKey = @"retrieve";
  46. static NSString *const kLETXMPPIDKey = @"id";
  47. static NSString *const kLETXMPPTypeKey = @"type";
  48. static NSString *const kLETXMPPSetKey = @"set";
  49. static NSString *const kLETXMPPMaxKey = @"max";
  50. static NSString *const kLETXMPPImageKey = @"image";
  51.  
  52. static NSString *const kLETImageUploadAPIMethod = @"photo/upload";
  53.  
  54. static CGFloat const kLETStreamConnectionTimeOut = 10.;
  55.  
  56. @interface LETChatService ()
  57.  
  58. @property (nonatomic, strong) NSMutableArray<LETChatMessagesCollector *> *messagesCollectorsArray;
  59. @property (nonatomic, strong) LETChatSessionsCollector *sessionsCollector;
  60. @property (nonatomic, assign) NSInteger lastSessionIndex;
  61. @property (nonatomic, assign) NSInteger loadedMessagesCount;
  62. @property (nonatomic, copy) NSString *userID;
  63. @property (nonatomic, copy) NSString *pairUserID;
  64. @property (nonatomic, copy) NSString *password;
  65. @property (nonatomic, strong) NSNumber *neededHistoryMessagesCount;
  66. @property (nonatomic, assign) LETOperationType operationType;
  67.  
  68. @end
  69.  
  70. @implementation LETChatService
  71.  
  72. #pragma mark - LETChatServiceProtocol
  73. - (void)createConnectionForUserWithID:(NSNumber *)userID password:(NSString *)password
  74. {
  75.     self.userID = userID.stringValue;
  76.     self.password = password;
  77.    
  78.     self.stream.myJID = [XMPPJID jidWithUser:self.userID domain:self.stream.hostName resource:nil];
  79.    
  80.     NSError *error = nil;
  81.    
  82.     self.operationType = LETOperationTypeCreateConnection;
  83.     [self.reconnect activate:self.stream];
  84.    
  85.     if ( ![self.stream connectWithTimeout:kLETStreamConnectionTimeOut error:&error] )
  86.     {
  87.         if ( [self.delegate respondsToSelector:@selector(chatService:connectionDidCreatedWithSuccess:)] )
  88.         {
  89.             [self.delegate chatService:self connectionDidCreatedWithSuccess:NO];
  90.         }
  91.     }
  92. }
  93.  
  94. - (void)sendMessage:(NSString *)text toUserWithID:(NSNumber *)userID
  95. {
  96.     self.pairUserID = userID.stringValue;
  97.    
  98.     XMPPJID *jid = [XMPPJID jidWithUser:userID.stringValue domain:self.stream.hostName resource:nil];
  99.     XMPPMessage *message = [XMPPMessage messageWithType:kLETXMPPChatKey to:jid];
  100.     [message addBody:[text stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
  101.    
  102.     self.operationType = LETOperationTypeSendMessage;
  103.    
  104.     [self.stream sendElement:message];
  105. }
  106.  
  107. - (void)sendImage:(UIImage *)image toUserWithID:(NSNumber *)userID
  108. {
  109.     if ( !image )
  110.     {
  111.         return;
  112.     }
  113.    
  114.     self.pairUserID = userID.stringValue;
  115.    
  116.     LETNetworkServiceSuccessBlock success = ^(NSURLSessionDataTask *task, id responseObject)
  117.     {
  118.         NSString *imageURLString = responseObject[kLETURLKey];
  119.        
  120.         if ( imageURLString.length )
  121.         {
  122.             XMPPJID *jid = [XMPPJID jidWithUser:userID.stringValue domain:self.stream.hostName resource:nil];
  123.             XMPPMessage *message = [XMPPMessage messageWithType:kLETXMPPChatKey to:jid];
  124.             [message addBody:[NSString stringWithFormat:kLETImageURLStringFormat, imageURLString]];
  125.  
  126.             self.operationType = LETOperationTypeSendMessage;
  127.            
  128.             [self.stream sendElement:message];
  129.         }
  130.     };
  131.    
  132.     LETNetworkServiceFailureBlock failure = ^(NSURLSessionDataTask *task, NSError *error)
  133.     {
  134.         NSLog(@"Handle error here");
  135.     };
  136.    
  137.     [self.networkService POST:kLETImageUploadAPIMethod
  138.                    parameters:image
  139.                       success:success
  140.                       failure:failure];
  141. }
  142.  
  143. #pragma mark - Helpers
  144. - (void)goOnline
  145. {
  146.     XMPPPresence *presence = [XMPPPresence presence];
  147.    
  148.     NSXMLElement *show = [NSXMLElement elementWithName:kLETXMPPShowKey];
  149.     NSXMLElement *status = [NSXMLElement elementWithName:kLETXMPPStatusKey];
  150.    
  151.     [show setStringValue:kLETXMPPChatKey];
  152.     [status setStringValue:kLETXMPPAvailableKey];
  153.    
  154.     [presence addChild:show];
  155.     [presence addChild:status];
  156.    
  157.     [self.stream sendElement:presence];
  158. }
  159.  
  160. - (void)loadChatHistoryForUserWithID:(NSNumber *)userID messagesCount:(NSNumber *)messagesCount
  161. {
  162.     if ( !!self.messagesCollectorsArray.count )
  163.     {
  164.         return;
  165.     }
  166.    
  167.     self.neededHistoryMessagesCount = messagesCount;
  168.     self.pairUserID = userID.stringValue;
  169.    
  170.     self.operationType = LETOperationTypeChatSessions;
  171.    
  172.     XMPPJID *withJID = [XMPPJID jidWithUser:userID.stringValue domain:self.stream.hostName resource:nil];
  173.    
  174.     DDXMLElement *query = [DDXMLElement elementWithName:kLETXMPPListKey xmlns:kLETXMPPArchiveKey];
  175.     [query addAttributeWithName:kLETXMPPWithKey stringValue:[withJID full]];
  176.    
  177.     XMPPIQ *iQ = [XMPPIQ iqWithType:kLETXMPPGetKey];
  178.     [iQ addAttributeWithName:kLETXMPPIDKey stringValue:self.userID];
  179.     [iQ addChild:query];
  180.    
  181.     [self.stream sendElement:iQ];
  182. }
  183.  
  184. - (void)loadEarlierMessagesWithUser:(NSNumber *)userID messagesCount:(NSNumber *)messagesCount
  185. {
  186.     if ( !self.sessionsCollector || self.lastSessionIndex < 0 )
  187.     {
  188.         if ( [self.delegate respondsToSelector:@selector(noEarlierMessagesFromChatService:)] )
  189.         {
  190.             [self.delegate noEarlierMessagesFromChatService:self];
  191.         }
  192.     }
  193.     else
  194.     {
  195.         LETChatSession *session = self.sessionsCollector.sesionsArray[self.lastSessionIndex];
  196.         [self loadMessagesWithSessionStartTime:session.startDateString];
  197.     }
  198. }
  199.  
  200. - (void)loadMessagesWithSessionStartTime:(NSString *)start
  201. {
  202.     self.operationType = LETOperationTypeChatHistory;
  203.    
  204.     XMPPJID *withJID = [XMPPJID jidWithUser:self.pairUserID domain:self.stream.hostName resource:nil];
  205.    
  206.     NSXMLElement *iq = [NSXMLElement elementWithName:kLETXMPPIQKey];
  207.     [iq addAttributeWithName:kLETXMPPTypeKey stringValue:kLETXMPPGetKey];
  208.     [iq addAttributeWithName:kLETXMPPIDKey stringValue:self.userID];
  209.    
  210.     NSXMLElement *retrieve = [NSXMLElement elementWithName:kLETXMPPRetrieveKey xmlns:kLETXMPPArchiveKey];
  211.     [retrieve addAttributeWithName:kLETXMPPWithKey stringValue:[withJID full]];
  212.     [retrieve addAttributeWithName:kLETXMPPStartKey stringValue:start];
  213.    
  214.     NSXMLElement *set = [NSXMLElement elementWithName:kLETXMPPSetKey xmlns:kLETXMPPRSMKey];
  215.    
  216.     [retrieve addChild:set];
  217.     [iq addChild:retrieve];
  218.    
  219.     [self.stream sendElement:iq];
  220. }
  221.  
  222. #pragma mark - XMPPStreamDelegate
  223. - (void)xmppStreamDidConnect:(XMPPStream *)sender
  224. {
  225.     NSError *error = nil;
  226.    
  227.     if ( ![self.stream authenticateWithPassword:self.password error:&error] )
  228.     {
  229.         if ( [self.delegate respondsToSelector:@selector(chatService:connectionDidCreatedWithSuccess:)] )
  230.         {
  231.             [self.delegate chatService:self connectionDidCreatedWithSuccess:NO];
  232.         }
  233.     }
  234. }
  235.  
  236. - (void)xmppStreamConnectDidTimeout:(XMPPStream *)sender
  237. {
  238.     NSLog(@"Handle error here");
  239. }
  240.  
  241. - (void)xmppStreamDidDisconnect:(XMPPStream *)sender withError:(NSError *)error
  242. {
  243.     NSLog(@"Handle error here");
  244. }
  245.  
  246. - (void)xmppStreamDidAuthenticate:(XMPPStream *)sender
  247. {
  248.     [self goOnline];
  249.    
  250.     if ( [self.delegate respondsToSelector:@selector(chatService:connectionDidCreatedWithSuccess:)] )
  251.     {
  252.         [self.delegate chatService:self connectionDidCreatedWithSuccess:YES];
  253.     }
  254. }
  255.  
  256. - (void)xmppStream:(XMPPStream *)sender didNotAuthenticate:(DDXMLElement *)error
  257. {
  258.     if ( [self.delegate respondsToSelector:@selector(chatService:connectionDidCreatedWithSuccess:)] )
  259.     {
  260.         [self.delegate chatService:self connectionDidCreatedWithSuccess:NO];
  261.     }
  262. }
  263.  
  264. - (void)xmppStream:(XMPPStream *)sender didReceiveMessage:(XMPPMessage *)message
  265. {
  266.     NSString *text = [message body];
  267.    
  268.     if ( !text || [message isErrorMessage])
  269.     {
  270.         return;
  271.     }
  272.    
  273.     if ( [self.delegate respondsToSelector:@selector(chatService:didReceiveMessage:)] )
  274.     {
  275.         text = [text stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
  276.         [self.delegate chatService:self didReceiveMessage:text];
  277.     }
  278. }
  279.  
  280. - (void)xmppStream:(XMPPStream *)sender didSendMessage:(XMPPMessage *)message
  281. {
  282.     if ( [self.delegate respondsToSelector:@selector(chatService:messageDidSendedWithSuccess:)] )
  283.     {
  284.         [self.delegate chatService:self messageDidSendedWithSuccess:YES];
  285.     }
  286. }
  287.  
  288. - (void)xmppStream:(XMPPStream *)sender didFailToSendMessage:(XMPPMessage *)message error:(NSError *)error
  289. {
  290.     if ( [self.delegate respondsToSelector:@selector(chatService:messageDidSendedWithSuccess:)] )
  291.     {
  292.         [self.delegate chatService:self messageDidSendedWithSuccess:NO];
  293.     }
  294. }
  295.  
  296. - (void)xmppStream:(XMPPStream *)sender didReceiveError:(NSXMLElement *)error
  297. {
  298.     if ( [self.delegate respondsToSelector:@selector(chatService:didReceiveError:)] )
  299.     {
  300.         [self.delegate chatService:self didReceiveError:nil];
  301.     }
  302. }
  303.  
  304. - (BOOL)xmppStream:(XMPPStream *)sender didReceiveIQ:(XMPPIQ *)iq
  305. {
  306.     if ( self.operationType == LETOperationTypeChatSessions )
  307.     {
  308.         NSDictionary *iqDict = [NSDictionary dictionaryWithXMLString:[iq description]];
  309.        
  310.         self.sessionsCollector = [self.mappingService convertJSONDictionary:iqDict
  311.                                                           toObjectWithClass:[LETChatSessionsCollector class]
  312.                                                               objectMapping:[LETChatSessionsCollector chatSessionsCollectorJSONToObjectMapping]
  313.                                                                       error:nil];
  314.        
  315.         if ( self.sessionsCollector.sesionsArray.count )
  316.         {
  317.             self.lastSessionIndex = self.sessionsCollector.sesionsArray.count - 1;
  318.            
  319.             LETChatSession *session = self.sessionsCollector.sesionsArray[self.lastSessionIndex];
  320.             [self loadMessagesWithSessionStartTime:session.startDateString];
  321.         }
  322.         else if ( [self.delegate respondsToSelector:@selector(chatService:messagesDidLoad:forSessionIndex:)] )
  323.         {
  324.             [self.delegate chatService:self messagesDidLoad:nil forSessionIndex:self.lastSessionIndex];
  325.         }
  326.     }
  327.     else if ( self.operationType == LETOperationTypeChatHistory )
  328.     {
  329.         self.lastSessionIndex--;
  330.        
  331.         NSDictionary *iqDict = [NSDictionary dictionaryWithXMLString:[iq description]];
  332.        
  333.         LETChatMessagesCollector *messagesCollector = [self.mappingService convertJSONDictionary:iqDict
  334.                                                                                toObjectWithClass:[LETChatMessagesCollector class]
  335.                                                                                    objectMapping:[LETChatMessagesCollector                          chatMessagesCollectorJSONToObjectMapping]
  336.                                                                                            error:nil];
  337.        
  338.         [self.messagesCollectorsArray addObject:messagesCollector];
  339.        
  340.         self.loadedMessagesCount += messagesCollector.messagesCount;
  341.        
  342.         BOOL isMessagesNotEnough = self.loadedMessagesCount < self.neededHistoryMessagesCount.integerValue;
  343.         BOOL isNotLastSessionIndex = self.lastSessionIndex >= 0;
  344.        
  345.         if ( isMessagesNotEnough && isNotLastSessionIndex )
  346.         {
  347.             LETChatSession *session = self.sessionsCollector.sesionsArray[self.lastSessionIndex];
  348.             [self loadMessagesWithSessionStartTime:session.startDateString];
  349.         }
  350.         else if ( [self.delegate respondsToSelector:@selector(chatService:messagesDidLoad:forSessionIndex:)] )
  351.         {
  352.             self.loadedMessagesCount = 0;
  353.             [self.delegate chatService:self messagesDidLoad:self.messagesCollectorsArray forSessionIndex:self.lastSessionIndex];
  354.         }
  355.     }
  356.    
  357.     return YES;
  358. }
  359.  
  360. #pragma mark - Lazy Init
  361. - (NSMutableArray<LETChatMessagesCollector *> *)messagesCollectorsArray
  362. {
  363.     if ( !_messagesCollectorsArray )
  364.     {
  365.         _messagesCollectorsArray = [NSMutableArray new];
  366.     }
  367.    
  368.     return _messagesCollectorsArray;
  369. }
  370.  
  371. @end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement