TestChat/TCViewController.m (124 lines of code) (raw):
//
// Copyright 2012 Square Inc.
// Portions Copyright (c) 2016-present, Facebook, Inc.
// All rights reserved.
//
// This source code is licensed under the license found in the
// LICENSE-examples file in the root directory of this source tree.
//
#import "TCViewController.h"
#import <SocketRocket/SocketRocket.h>
#import "TCChatCell.h"
@interface TCMessage : NSObject
- (instancetype)initWithMessage:(NSString *)message incoming:(BOOL)incoming;
@property (nonatomic, copy, readonly) NSString *message;
@property (nonatomic, assign, readonly, getter=isIncoming) BOOL incoming;
@end
@implementation TCMessage
- (instancetype)initWithMessage:(NSString *)message incoming:(BOOL)incoming
{
self = [super init];
if (!self) return self;
_incoming = incoming;
_message = message;
return self;
}
@end
@interface TCViewController () <SRWebSocketDelegate, UITextViewDelegate>
{
SRWebSocket *_webSocket;
NSMutableArray<TCMessage *> *_messages;
}
@end
@implementation TCViewController
///--------------------------------------
#pragma mark - View
///--------------------------------------
- (void)viewDidLoad;
{
[super viewDidLoad];
_messages = [[NSMutableArray alloc] init];
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[self reconnect:nil];
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
[_inputView becomeFirstResponder];
}
- (void)viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:animated];
[_webSocket close];
_webSocket = nil;
}
///--------------------------------------
#pragma mark - Actions
///--------------------------------------
- (IBAction)reconnect:(id)sender
{
_webSocket.delegate = nil;
[_webSocket close];
_webSocket = [[SRWebSocket alloc] initWithURL:[NSURL URLWithString:@"wss://echo.websocket.org"]];
_webSocket.delegate = self;
self.title = @"Opening Connection...";
[_webSocket open];
}
- (void)sendPing:(id)sender;
{
[_webSocket sendPing:nil error:NULL];
}
///--------------------------------------
#pragma mark - Messages
///--------------------------------------
- (void)_addMessage:(TCMessage *)message
{
[_messages addObject:message];
[self.tableView insertRowsAtIndexPaths:@[ [NSIndexPath indexPathForRow:_messages.count - 1 inSection:0] ]
withRowAnimation:UITableViewRowAnimationNone];
[self.tableView scrollRectToVisible:self.tableView.tableFooterView.frame animated:YES];
}
///--------------------------------------
#pragma mark - UITableViewController
///--------------------------------------
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return _messages.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
TCMessage *message = _messages[indexPath.row];
TCChatCell *cell = [self.tableView dequeueReusableCellWithIdentifier:message.incoming ? @"ReceivedCell" : @"SentCell"
forIndexPath:indexPath];
cell.textView.text = message.message;
cell.nameLabel.text = message.incoming ? @"Other" : @"Me";
return cell;
}
///--------------------------------------
#pragma mark - SRWebSocketDelegate
///--------------------------------------
- (void)webSocketDidOpen:(SRWebSocket *)webSocket;
{
NSLog(@"Websocket Connected");
self.title = @"Connected!";
}
- (void)webSocket:(SRWebSocket *)webSocket didFailWithError:(NSError *)error;
{
NSLog(@":( Websocket Failed With Error %@", error);
self.title = @"Connection Failed! (see logs)";
_webSocket = nil;
}
- (void)webSocket:(SRWebSocket *)webSocket didReceiveMessageWithString:(nonnull NSString *)string
{
NSLog(@"Received \"%@\"", string);
[self _addMessage:[[TCMessage alloc] initWithMessage:string incoming:YES]];
}
- (void)webSocket:(SRWebSocket *)webSocket didCloseWithCode:(NSInteger)code reason:(NSString *)reason wasClean:(BOOL)wasClean;
{
NSLog(@"WebSocket closed");
self.title = @"Connection Closed! (see logs)";
_webSocket = nil;
}
- (void)webSocket:(SRWebSocket *)webSocket didReceivePong:(NSData *)pongPayload;
{
NSLog(@"WebSocket received pong");
}
///--------------------------------------
#pragma mark - UITextViewDelegate
///--------------------------------------
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
{
if ([text rangeOfString:@"\n"].location != NSNotFound) {
NSString *message = [textView.text stringByReplacingCharactersInRange:range withString:text];
message = [message stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
[_webSocket sendString:message error:NULL];
[self _addMessage:[[TCMessage alloc] initWithMessage:message incoming:NO]];
textView.text = nil;
return NO;
}
return YES;
}
@end