// // ViewController.m // Socket1 // // Created by 阿仁歐巴 on 16/5/7. // Copyright © 2016年 aren. All rights reserved. // #import "ViewController.h" @interface ViewController () <NSStreamDelegate, UITextFieldDelegate, UITableViewDataSource, UITableViewDelegate> { NSInputStream *_inputStream; NSOutputStream *_outStream; } //@property (weak, nonatomic) IBOutlet NSLayoutConstraint *bottomViewConstraint; @property (weak, nonatomic) IBOutlet UIView *commentView;//發送消息的文本框的父視圖,根據鍵盤的出現與否設置它的frame @property (weak, nonatomic) IBOutlet UITableView *tableView; @property (nonatomic, strong) NSMutableArray *chatMsgs; //聊天消息數組 @end @implementation ViewController - (NSMutableArray *)chatMsgs { if (!_chatMsgs) { _chatMsgs = [NSMutableArray array]; } return _chatMsgs; } //鏈接服務器的按鈕 - (IBAction)connect:(id)sender { //1.獲取服務器的IP地址和端口號 NSString *host = @"127.0.0.1"; int port = 8080; //2.獲取輸入輸出流 CFReadStreamRef readRef; CFWriteStreamRef writeRef; //3.將C語言對象轉換成OC對象 _inputStream = (__bridge NSInputStream *)(readRef); _outStream = (__bridge NSOutputStream *)(writeRef); //4.創建鏈接 CFStreamCreatePairWithSocketToHost(NULL, (__bridge CFStringRef)host, port, &readRef, &writeRef); //5.設置代理 _inputStream.delegate = self; _outStream.delegate = self; #pragma mark ---若是不添加到主循環,代理方法可能不執行---- //6.扔進主循環 [_inputStream scheduleInRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode]; [_outStream scheduleInRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode]; //7.打開輸入輸出流 [_inputStream open]; [_outStream open]; #pragma mark ---連接結束時,須要將輸入輸出流從主循環中移除 而且關閉輸入輸出流, 在代理方法中執行---- } //登陸按鈕 - (IBAction)login:(id)sender { //登錄的指令 NSString *loginString = @"iam:arenouba"; //轉換成NSData類型的 NSData *data = [loginString dataUsingEncoding:NSUTF8StringEncoding]; //輸出流發送登陸數據給服務器 [_outStream write:data.bytes maxLength:data.length]; } #pragma mark ---輸入流 讀取 服務器 返回的數據 XMPP 已經封裝好了,不用咱們處理--- - (void)readData { //創建一個緩衝區,能夠放1024個字節 uint8_t buf[1024]; // len 返回實際存放的字節數 NSInteger len = [_inputStream read:buf maxLength:sizeof(buf)]; //sizeof(buf) //把字節轉化成字符串 NSData *data = [NSData dataWithBytes:buf length:len]; //轉換成字符串 從服務器接收到的數據 NSString *recieveString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; //刷新數據 [self reloadDataWithText:recieveString]; NSLog(@"%@",recieveString); } #pragma mark --- 點擊發送按鈕時 獲取文本輸入框的文字,並刷新tableView --- - (BOOL)textFieldShouldReturn:(UITextField *)textField { NSString *text = textField.text; NSData *data = [text dataUsingEncoding:NSUTF8StringEncoding]; [self reloadDataWithText:text]; //發送數據給服務器 [_outStream write:data.bytes maxLength:data.length]; //發送完成後,清空文本框 textField.text = nil; return YES; } - (void)reloadDataWithText:(NSString *)text { //添加文本輸入框的數據到消息數組中 [self.chatMsgs addObject:text]; //刷新 [self.tableView reloadData]; //發送一條消息,使tableView跟着向上滾動一行 NSIndexPath *lastIndexPath = [NSIndexPath indexPathForRow:self.chatMsgs.count - 1 inSection:0]; [self.tableView scrollToRowAtIndexPath:lastIndexPath atScrollPosition:UITableViewScrollPositionBottom animated:YES]; } #pragma mark --- 將要拖動時,鍵盤消失--- - (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView { [self.view endEditing:YES]; } #pragma mark ----NSStreamDelegate ----- - (void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode { #warning mark --- 這是在主線程中執行的 NSLog(@"%@",[NSThread currentThread]); /* NSStreamEventNone = 0, NSStreamEventOpenCompleted = 1UL << 0, 輸入輸出流打開完成 NSStreamEventHasBytesAvailable = 1UL << 1, 有字節可讀 NSStreamEventHasSpaceAvailable = 1UL << 2, 能夠發送字節 NSStreamEventErrorOccurred = 1UL << 3, 鏈接出現了錯誤 NSStreamEventEndEncountered = 1UL << 4 鏈接結束 */ switch (eventCode) { case NSStreamEventOpenCompleted: NSLog(@" 輸入輸出流打開完成"); break; case NSStreamEventHasBytesAvailable: NSLog(@"有字節可讀"); break; case NSStreamEventHasSpaceAvailable: NSLog(@"能夠發送字節"); break; case NSStreamEventErrorOccurred: NSLog(@"鏈接錯誤"); break; case NSStreamEventEndEncountered: NSLog(@"鏈接結束"); //關閉輸入輸出流 [_inputStream close]; [_outStream close]; //從主循環移除 [_inputStream removeFromRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode]; [_outStream removeFromRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode]; break; default: break; } } - (void)viewDidLoad { [super viewDidLoad]; //監聽鍵盤將要出現時 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillChang:) name:UIKeyboardWillChangeFrameNotification object:nil]; //監聽鍵盤將要隱藏時 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHidden:) name:UIKeyboardWillHideNotification object:nil]; self.tableView.delegate = self; self.tableView.dataSource = self; [self.view insertSubview:_tableView atIndex:0]; // Do any additional setup after loading the view, typically from a nib. } - (void)keyboardWillChang:(NSNotification *)noti { NSLog(@"%@",noti.userInfo); //鍵盤結束的y值 CGRect kbEndFrame = [noti.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue]; [UIView animateWithDuration:[noti.userInfo[UIKeyboardAnimationDurationUserInfoKey] floatValue] animations:^{ self.commentView.transform = CGAffineTransformMakeTranslation(0, -kbEndFrame.size.height); }]; } - (void)keyboardWillHidden:(NSNotification *)noti { //鍵盤結束的y值 [UIView animateWithDuration:[noti.userInfo[UIKeyboardAnimationDurationUserInfoKey] floatValue] animations:^{ self.commentView.transform = CGAffineTransformIdentity; }]; } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return self.chatMsgs.count; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *ID = @"cell"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
if (cell == nil) {數組
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ID];服務器
}ide
cell.textLabel.text = self.chatMsgs[indexPath.row]; return cell; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } @end