TCViewController.m 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. //
  2. // Copyright 2012 Square Inc.
  3. // Portions Copyright (c) 2016-present, Facebook, Inc.
  4. // All rights reserved.
  5. //
  6. // This source code is licensed under the license found in the
  7. // LICENSE-examples file in the root directory of this source tree.
  8. //
  9. #import "TCViewController.h"
  10. #import <SocketRocket/SRWebSocket.h>
  11. #import "TCChatCell.h"
  12. @interface TCMessage : NSObject
  13. - (instancetype)initWithMessage:(NSString *)message fromMe:(BOOL)fromMe;
  14. @property (nonatomic, retain, readonly) NSString *message;
  15. @property (nonatomic, readonly) BOOL fromMe;
  16. @end
  17. @interface TCViewController () <SRWebSocketDelegate, UITextViewDelegate>
  18. @end
  19. @implementation TCViewController {
  20. SRWebSocket *_webSocket;
  21. NSMutableArray *_messages;
  22. }
  23. @synthesize inputView = _inputView;
  24. #pragma mark - View lifecycle
  25. - (void)viewDidLoad;
  26. {
  27. [super viewDidLoad];
  28. _messages = [[NSMutableArray alloc] init];
  29. [self.tableView reloadData];
  30. }
  31. - (void)_reconnect;
  32. {
  33. _webSocket.delegate = nil;
  34. [_webSocket close];
  35. _webSocket = [[SRWebSocket alloc] initWithURLRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"ws://localhost:9000/chat"]]];
  36. _webSocket.delegate = self;
  37. self.title = @"Opening Connection...";
  38. [_webSocket open];
  39. }
  40. - (void)viewWillAppear:(BOOL)animated
  41. {
  42. [super viewWillAppear:animated];
  43. [self _reconnect];
  44. }
  45. - (void)reconnect:(id)sender;
  46. {
  47. [self _reconnect];
  48. }
  49. - (void)sendPing:(id)sender;
  50. {
  51. [_webSocket sendPing:nil];
  52. }
  53. - (void)viewDidAppear:(BOOL)animated;
  54. {
  55. [super viewDidAppear:animated];
  56. [_inputView becomeFirstResponder];
  57. }
  58. - (void)viewDidDisappear:(BOOL)animated
  59. {
  60. [super viewDidDisappear:animated];
  61. _webSocket.delegate = nil;
  62. [_webSocket close];
  63. _webSocket = nil;
  64. }
  65. #pragma mark - UITableViewController
  66. - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section;
  67. {
  68. return _messages.count;
  69. }
  70. - (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath;
  71. {
  72. TCChatCell *chatCell = (id)cell;
  73. TCMessage *message = [_messages objectAtIndex:indexPath.row];
  74. chatCell.textView.text = message.message;
  75. chatCell.nameLabel.text = message.fromMe ? @"Me" : @"Other";
  76. }
  77. - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;
  78. {
  79. TCMessage *message = [_messages objectAtIndex:indexPath.row];
  80. return [self.tableView dequeueReusableCellWithIdentifier:message.fromMe ? @"SentCell" : @"ReceivedCell"];
  81. }
  82. #pragma mark - SRWebSocketDelegate
  83. - (void)webSocketDidOpen:(SRWebSocket *)webSocket;
  84. {
  85. NSLog(@"Websocket Connected");
  86. self.title = @"Connected!";
  87. }
  88. - (void)webSocket:(SRWebSocket *)webSocket didFailWithError:(NSError *)error;
  89. {
  90. NSLog(@":( Websocket Failed With Error %@", error);
  91. self.title = @"Connection Failed! (see logs)";
  92. _webSocket = nil;
  93. }
  94. - (void)webSocket:(SRWebSocket *)webSocket didReceiveMessage:(id)message;
  95. {
  96. NSLog(@"Received \"%@\"", message);
  97. [_messages addObject:[[TCMessage alloc] initWithMessage:message fromMe:NO]];
  98. [self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:_messages.count - 1 inSection:0]] withRowAnimation:UITableViewRowAnimationNone];
  99. [self.tableView scrollRectToVisible:self.tableView.tableFooterView.frame animated:YES];
  100. }
  101. - (void)webSocket:(SRWebSocket *)webSocket didCloseWithCode:(NSInteger)code reason:(NSString *)reason wasClean:(BOOL)wasClean;
  102. {
  103. NSLog(@"WebSocket closed");
  104. self.title = @"Connection Closed! (see logs)";
  105. _webSocket = nil;
  106. }
  107. - (void)webSocket:(SRWebSocket *)webSocket didReceivePong:(NSData *)pongPayload;
  108. {
  109. NSLog(@"Websocket received pong");
  110. }
  111. - (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text;
  112. {
  113. if ([text rangeOfString:@"\n"].location != NSNotFound) {
  114. NSString *message = [[textView.text stringByReplacingCharactersInRange:range withString:text] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
  115. [_webSocket send:message];
  116. [_messages addObject:[[TCMessage alloc] initWithMessage:message fromMe:YES]];
  117. [self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:_messages.count - 1 inSection:0]] withRowAnimation:UITableViewRowAnimationNone];
  118. [self.tableView scrollRectToVisible:self.tableView.tableFooterView.frame animated:YES];
  119. textView.text = @"";
  120. return NO;
  121. }
  122. return YES;
  123. }
  124. - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation;
  125. {
  126. return YES;
  127. }
  128. @end
  129. @implementation TCMessage
  130. @synthesize message = _message;
  131. @synthesize fromMe = _fromMe;
  132. - (instancetype)initWithMessage:(NSString *)message fromMe:(BOOL)fromMe;
  133. {
  134. self = [super init];
  135. if (self) {
  136. _fromMe = fromMe;
  137. _message = message;
  138. }
  139. return self;
  140. }
  141. @end