GCDAsyncSocket编程

同上一篇文章一样,这里也是使用Socket实现一个聊天室,但是这里使用的是一个常用的框架实现的:GCDAsyncSocket

一:导入这个框架

二:声明这个Socket的成员变量,定义一个消息数组  

 @interface ViewController ()<UITextFieldDelegate,UITableViewDataSource,UITableViewDelegate,GCDAsyncSocketDelegate>{

     GCDAsyncSocket *_socket;
 }
 @property (weak, nonatomic) IBOutlet NSLayoutConstraint *inputViewConstraint;
 @property (weak, nonatomic) IBOutlet UITableView *tableView;

 @property (nonatomic, strong) NSMutableArray *chatMsgs;//聊天消息数组

 @end

懒加载消息数组

 -(NSMutableArray *)chatMsgs{
     if (!_chatMsgs) {
         _chatMsgs = [NSMutableArray array];
     }

     return _chatMsgs;
 }

三:链接服务器

 - (IBAction)connectToHost:(id)sender {
     // 1.建立连接
     NSString *host = @"127.0.0.1";
     ;

     // 创建一个Socket对象
     _socket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, )];

     // 连接
     NSError *error = nil;
     [_socket connectToHost:host onPort:port error:&error];
     if (error) {
         NSLog(@"%@",error);
     }
 }

链接与断开连接的代理方法

 #pragma mark -AsyncSocket的代理
 #pragma mark 连接主机成功
 -(void)socket:(GCDAsyncSocket *)sock didConnectToHost:(NSString *)host port:(uint16_t)port{
     NSLog(@"连接主机成功");
 }

 #pragma mark 与主机断开连接
 -(void)socketDidDisconnect:(GCDAsyncSocket *)sock withError:(NSError *)err{

     if(err){
         NSLog(@"断开连接 %@",err);
     }
 }

四:登陆

 - (IBAction)loginBtnClick:(id)sender {

     // 登录
     // 发送用户名和密码
     // 在这里做的时候,只发用户名,密码就不用发送

     // 如果要登录,发送的数据格式为 "iam:zhangsan";
     // 如果要发送聊天消息,数据格式为 "msg:did you have dinner";

     //登录的指令
     NSString *loginStr = @"iam:zhangsan";

     //把Str转成NSData
     NSData *data = [loginStr dataUsingEncoding:NSUTF8StringEncoding];

     //[_outputStream write:data.bytes maxLength:data.length];
     // 发送登录指令给服务
     [_socket writeData:data withTimeout:- tag:];
 }

五:发送数据

 -(BOOL)textFieldShouldReturn:(UITextField *)textField{

     NSString *text = textField.text;

     NSLog(@"%@",text);
     // 聊天信息
     NSString *msgStr = [NSString stringWithFormat:@"msg:%@",text];

     //把Str转成NSData
     NSData *data = [msgStr dataUsingEncoding:NSUTF8StringEncoding];

     // 刷新表格
     [self reloadDataWithText:msgStr];

     // 发送数据
     [_socket writeData:data withTimeout:- tag:];

     // 发送完数据,清空textField
     textField.text = nil;

     return YES;
 }

 #pragma mark 数据成功发送到服务器
 -(void)socket:(GCDAsyncSocket *)sock didWriteDataWithTag:(long)tag{
     NSLog(@"数据成功发送到服务器");
     //数据发送成功后,自己调用一下读取数据的方法,接着_socket才会调用下面的代理方法
     [_socket readDataWithTimeout:- tag:tag];
 }

 #pragma mark 服务器有数据,会调用这个方法
 -(void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag{
     // 从服务器接收到的数据
     NSString *recStr =  [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];

     NSLog(@"%@ %ld %@",[NSThread currentThread],tag, recStr);

     ) {//聊天返回的数据
         // 刷新表格
         [self reloadDataWithText:recStr];
     }
 //    }else if(tag == 101 ){//登录返回数据,不应该把数据添加到表格里
 //
 //
 //    }

 }

六:加载聊天数据到界面,并且实现滚动到对应的位置,键盘的键盘

 -(void)reloadDataWithText:(NSString *)text{
     [self.chatMsgs addObject:text];

     // UI刷新要主线程
     dispatch_async(dispatch_get_main_queue(), ^{
         [self.tableView reloadData];

         // 数据多,应该往上滚动
         NSIndexPath *lastPath = [NSIndexPath indexPathForRow:self.chatMsgs.count -  inSection:];
         [self.tableView scrollToRowAtIndexPath:lastPath atScrollPosition:UITableViewScrollPositionBottom animated:YES];
     });

 }

 #pragma mark 表格的数据源

 -(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];

     cell.textLabel.text = self.chatMsgs[indexPath.row];

     return cell;
 }

 -(void)scrollViewWillBeginDragging:(UIScrollView *)scrollView{
     [self.view endEditing:YES];
 }

键盘处理

     // 监听键盘
     [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(kbFrmWillChange:) name:UIKeyboardWillChangeFrameNotification object:nil];
 }

 -(void)kbFrmWillChange:(NSNotification *)noti{
     NSLog(@"%@",noti.userInfo);

     // 获取窗口的高度

     CGFloat windowH = [UIScreen mainScreen].bounds.size.height;

     // 键盘结束的Frm
     CGRect kbEndFrm = [noti.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
      // 获取键盘结束的y值
     CGFloat kbEndY = kbEndFrm.origin.y;

     self.inputViewConstraint.constant = windowH - kbEndY;
 }
 

iOS开发——网络编程OC篇&GCDAsyncSocket编程的更多相关文章

  1. iOS开发——网络实用技术OC篇&网络爬虫-使用青花瓷抓取网络数据

    网络爬虫-使用青花瓷抓取网络数据 由于最近在研究网络爬虫相关技术,刚好看到一篇的的搬了过来! 望谅解..... 写本文的契机主要是前段时间有次用青花瓷抓包有一步忘了,在网上查了半天也没找到写的完整的教 ...

  2. iOS开发——网络实用技术OC篇&网络爬虫-使用java语言抓取网络数据

    网络爬虫-使用java语言抓取网络数据 前提:熟悉java语法(能看懂就行) 准备阶段:从网页中获取html代码 实战阶段:将对应的html代码使用java语言解析出来,最后保存到plist文件 上一 ...

  3. ios开发——实用技术篇OC篇&iOS的主要框架

    iOS的主要框架         阅读目录 Foundation框架为所有的应用程序提供基本系统服务 UIKit框架提供创建基于触摸用户界面的类 Core Data框架管着理应用程序数据模型 Core ...

  4. iOS开发——高级技术OC篇&运行时(Runtime)机制

    运行时(Runtime)机制 本文将会以笔者个人的小小研究为例总结一下关于iOS开发中运行时的使用和常用方法的介绍,关于跟多运行时相关技术请查看笔者之前写的运行时高级用法及相关语法或者查看响应官方文档 ...

  5. iOS开发——UI精选OC篇&UIApplication,UIWindow,UIViewController,UIView(layer)简单介绍

    UIApplication,UIWindow,UIViewController,UIView(layer)简单介绍 一:UIApplication:单例(关于单例后面的文章中会详细介绍,你现在只要知道 ...

  6. iOS开发——运行时OC篇&使用运行时获取系统的属性:使用自己的手势修改系统自带的手势

    使用运行时获取系统的属性:使用自己的手势修改系统自带的手势 有的时候我需要实现一个功能,但是没有想到很好的方法或者想到了方法只是那个方法实现起来太麻烦,一或者确实为了装逼,我们就会想到iOS开发中最牛 ...

  7. iOS开发——高级UI—OC篇&退出键盘

    退出键盘 iOS开发中键盘的退出方法用很多中我们应该在合适的地方使用合适的方法才能更好的提高开发的效率和应用的性能 下面给大家介绍几种最常用的键盘退出方法,基本上iOS开发中的键盘退出方法都是这几种中 ...

  8. iOS开发——网络编程OC篇&Socket编程

    Socket编程 一.网络各个协议:TCP/IP.SOCKET.HTTP等 网络七层由下往上分别为物理层.数据链路层.网络层.传输层.会话层.表示层和应用层. 其中物理层.数据链路层和网络层通常被称作 ...

  9. iOS开发——新特性OC篇&Swift 2.0新特性

    Swift 2.0新特性     转眼间,Swift已经一岁多了,这门新鲜.语法时尚.类型安全.执行速度更快的语言已经渐渐的深入广大开发者的心.我同样也是非常喜爱这门新的编程语言. 今年6月,一年一度 ...

随机推荐

  1. SCOI2007蜥蜴

    Description 在一个r行c列的网格地图中有一些高度不同的石柱,一些石柱 上站着一些蜥蜴,你的任务是让尽量多的蜥蜴逃到边界外. 每行每列中相邻石柱的距离为1,蜥蜴的跳跃距离是d,即蜥蜴可以跳到 ...

  2. apache开源项目--Camel

    Apache Camel 是一个非常强大的基于规则的路由以及媒介引擎,该引擎提供了一个基于POJO的 企业应用模式(Enterprise Integration Patterns)的实现,你可以采用其 ...

  3. 《深入Java虚拟机学习笔记》- 第4章 网络移动性

    Java虚拟机学习笔记(四)网络移动性

  4. 多线程与网络之NSURLConnection发送请求

    *:first-child { margin-top: 0 !important; } body > *:last-child { margin-bottom: 0 !important; } ...

  5. 【转载】shell中的特殊变量$

    shell中的特殊变量:变量名含义$0shell或shell脚本的名字$*以一对双引号给出参数列表$@将各个参数分别加双引号返回$#参数的个数$_代表上一个命令的最后一个参数$$代表所在命令的PID$ ...

  6. Bzoj-2190 仪仗队 欧拉函数

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2190 简单的欧拉函数题,实际上就是求gcd(x,y)=1, 0<=x,y<=n ...

  7. Codeforces Round #225 (Div. 2)

    比赛时候只做出AB,E题一眼看过去似乎线段树能搞,但是写完过不了样例,才发现看错题了,然后比赛就没啥时间了~~整体状况还是很糟糕,A,B题实在出得太慢,然后持续到现在还没出过C题...不能更弱%> ...

  8. hdoj 5194 DZY Loves Balls【规律&&gcd】

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5194 题意:给你n个黑球,m个白球,每次从中随机抽取一个,如果抽到黑球记为1如果抽出来白球记为0,让你 ...

  9. hdoj 2083 简易版之最短距离

    简易版之最短距离 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Su ...

  10. [OC Foundation框架 - 4] NSString的导出

      void exportString() { NSString *str = @"Hello, 坑爹"; NSString *path = @"/Users/hello ...