• 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
  • 相关阅读:
    Android随笔使用ViewPager实现简单地图片的左右滑动切换
    简单地Android中图片的三级缓存机制
    Java中怎么遍历map中value值 (转载)
    创建可执行的jar包
    写出优秀的java代码(转载)
    [JS脚本]ajax status 错误定义
    jsonlib 之jsonConfig详细使用(转载写的不错)
    Driver not found Error when sonar server is just not running
    使用Maven生成manifest
    ECMAScript 面向对象技术
  • 原文地址:https://www.cnblogs.com/arenouba/p/5469665.html
Copyright © 2020-2023  润新知