GCDAsyncSocket通信


//
//  ViewController.m
//  Socket1
//
//  Created by 阿仁歐巴 on 16/5/7.
//  Copyright © 2016年 aren. All rights reserved.
//

#import "ViewController.h"
#import "GCDAsyncSocket.h"

@interface ViewController () < UITextFieldDelegate, UITableViewDataSource, UITableViewDelegate, GCDAsyncSocketDelegate>
{
    GCDAsyncSocket *_socket; //成員變量
}
//@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
{
    //和服務器建立連接的步驟
    NSString *host = @"127.0.0.1";
    int port = 8080;
    //創建一個socket對象  代理方法都會在子線程調用,在刷新UI時就要回到主線程
    _socket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)];
    //鏈接服務器
    NSError *error = nil;
    
#pragma mark ---使用GCDAsyncSocket就不用將C語言形式的輸入輸出流轉換成OC對象了,因為已經幫我們封裝好了---
    
    [_socket connectToHost:host onPort:port error:&error];
    if (error) {
        NSLog(@"%@",error);
    }
    
}

//登錄按鈕
- (IBAction)login:(id)sender {
    
    //登錄的指令
    NSString *logStr = @"iam:阿仁";
    NSData *data = [logStr dataUsingEncoding:NSUTF8StringEncoding];
    //發送登錄消息數據給服務器 登錄的時候
    [_socket writeData:data withTimeout:-1 tag:101];
    
}

#pragma mark --當數據成功發送到服務器, 才會執行下面的代理方法---

- (void)socket:(GCDAsyncSocket *)sock didWriteDataWithTag:(long)tag
{
    NSLog(@"數據成功發送到服務器");
    //,自己調用一下讀取數據的方法, 發送數據成功后,接着_socket才會執行下面的方法,
    [_socket readDataWithTimeout:-1 tag:tag];
}

#pragma mark ---GCDAsyncSocketDelegate---

- (void)socket:(GCDAsyncSocket *)sock didConnectToHost:(NSString *)host port:(uint16_t)port
{
    NSLog(@"鏈接主機成功");
}

- (void)socketDidDisconnect:(GCDAsyncSocket *)sock withError:(NSError *)err
{
    if (err) {
        NSLog(@"和主機斷開鏈接");
    }
}

#pragma mark ---服務器有數據, 就會執行這個方法---
//接收到數據
//點擊鍵盤發送按鈕,發送消息數據
- (void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag
{
    //將接收到的數據轉換成字符串形式,在tableView中展示出來
    NSString *dataString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
    NSLog(@"%@",dataString);
    //刷新表格
    if (tag == 102) {
        [self reloadDataWithText:dataString];
        NSLog(@"發送的是鍵盤輸入的消息數據");
    } else if (tag == 101) {
        NSLog(@"發送的是登錄數據");
    }
    
}
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
    NSLog(@"%@",textField.text);
    NSString *msStr = textField.text;
    NSData *data = [msStr dataUsingEncoding:NSUTF8StringEncoding];
    //刷新表格 並且讓表格自動滾動到最后一行的位置
    [self reloadDataWithText:textField.text];
    //_socket發送數據
    [_socket writeData:data withTimeout:-1 tag:102];
    //發送完成清空輸入框
    textField.text = nil;
    
    return YES;
}

- (void)reloadDataWithText:(NSString *)text
{
    //將發送的消息存入本地數組中,作為數據源 展示在tableView上
    
    [self.chatMsgs addObject:text];
    
#pragma mark ---回到主線程刷新UI,因為在剛開始創建Socket設置代理的時候代理隊列是全局並發隊列,在子線程中執行---

    dispatch_async(dispatch_get_main_queue(), ^{
        [self.tableView reloadData];
    });
    
    //獲取最后一行的indexPath
    NSIndexPath *lastPath = [NSIndexPath indexPathForRow:self.chatMsgs.count - 1 inSection:0];
    //tableView 自動滾動到最后一行
    [self.tableView scrollToRowAtIndexPath:lastPath atScrollPosition:UITableViewScrollPositionBottom animated:YES];
    
}

#pragma mark --- 將要拖動時,鍵盤消失---
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
    [self.view endEditing:YES];
}

- (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) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ID];
    }
    cell.textLabel.text = self.chatMsgs[indexPath.row];
    return cell;
}


- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM