iOS开发——网络编程OC篇&GCDAsyncSocket编程
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编程的更多相关文章
- iOS开发——网络实用技术OC篇&网络爬虫-使用青花瓷抓取网络数据
网络爬虫-使用青花瓷抓取网络数据 由于最近在研究网络爬虫相关技术,刚好看到一篇的的搬了过来! 望谅解..... 写本文的契机主要是前段时间有次用青花瓷抓包有一步忘了,在网上查了半天也没找到写的完整的教 ...
- iOS开发——网络实用技术OC篇&网络爬虫-使用java语言抓取网络数据
网络爬虫-使用java语言抓取网络数据 前提:熟悉java语法(能看懂就行) 准备阶段:从网页中获取html代码 实战阶段:将对应的html代码使用java语言解析出来,最后保存到plist文件 上一 ...
- ios开发——实用技术篇OC篇&iOS的主要框架
iOS的主要框架 阅读目录 Foundation框架为所有的应用程序提供基本系统服务 UIKit框架提供创建基于触摸用户界面的类 Core Data框架管着理应用程序数据模型 Core ...
- iOS开发——高级技术OC篇&运行时(Runtime)机制
运行时(Runtime)机制 本文将会以笔者个人的小小研究为例总结一下关于iOS开发中运行时的使用和常用方法的介绍,关于跟多运行时相关技术请查看笔者之前写的运行时高级用法及相关语法或者查看响应官方文档 ...
- iOS开发——UI精选OC篇&UIApplication,UIWindow,UIViewController,UIView(layer)简单介绍
UIApplication,UIWindow,UIViewController,UIView(layer)简单介绍 一:UIApplication:单例(关于单例后面的文章中会详细介绍,你现在只要知道 ...
- iOS开发——运行时OC篇&使用运行时获取系统的属性:使用自己的手势修改系统自带的手势
使用运行时获取系统的属性:使用自己的手势修改系统自带的手势 有的时候我需要实现一个功能,但是没有想到很好的方法或者想到了方法只是那个方法实现起来太麻烦,一或者确实为了装逼,我们就会想到iOS开发中最牛 ...
- iOS开发——高级UI—OC篇&退出键盘
退出键盘 iOS开发中键盘的退出方法用很多中我们应该在合适的地方使用合适的方法才能更好的提高开发的效率和应用的性能 下面给大家介绍几种最常用的键盘退出方法,基本上iOS开发中的键盘退出方法都是这几种中 ...
- iOS开发——网络编程OC篇&Socket编程
Socket编程 一.网络各个协议:TCP/IP.SOCKET.HTTP等 网络七层由下往上分别为物理层.数据链路层.网络层.传输层.会话层.表示层和应用层. 其中物理层.数据链路层和网络层通常被称作 ...
- iOS开发——新特性OC篇&Swift 2.0新特性
Swift 2.0新特性 转眼间,Swift已经一岁多了,这门新鲜.语法时尚.类型安全.执行速度更快的语言已经渐渐的深入广大开发者的心.我同样也是非常喜爱这门新的编程语言. 今年6月,一年一度 ...
随机推荐
- bzoj1412
比较裸的最小割 注意狼和羊的领地可以通过空地相连 ; dx:..] ,,,-); dy:..] ,,,); type node=record next,point ...
- ArcGIS for Android示例解析之离线地图-----LocalTiledLayer
转自:http://blog.csdn.net/wozaifeiyang0/article/details/7327423 LocalTiledLayer 看到这个标题是否是很激动,如题,该示例就是添 ...
- 结构型:代理模式 Vs 适配器模式 Vs 门面模式(外观模式)
先上UML图 代理模式: 适配器模式: 门面模式(外观模式): 打了例子……呃……举个比方 代理模式: 水浒街,西门庆看上潘金莲,想和她嘿咻嘿咻,但是自己有不能去找潘金莲去说,于是他找到了金牌代理人王 ...
- POJ 3630- Phone List(Trie)
题意:给一组串,是否存在一个串是另一个的前缀. 分析:val[N]保存树节点上是否组成一个串 #include <map> #include <set> #include &l ...
- 黑盒测试用例设计方法&理论结合实际 -> 边界值分析法
一. 概念 边界值分析法就是对输入或输出的边界值进行测试的一种黑盒测试方法.通常边界值分析法是作为对等价类划分法的补充,这种情况下,其测试用例来自等价类的边界. 二. 边界值分析法的应用 根据大量的测 ...
- linux 打开远程samba服务器
sudo mount -t cifs //10.104.*.*data /home/leeyoung/samba/ -o username=123,password=123
- C#给文件重命名
使用的主要方法是: File.Move(oldFileDir,newFileDir);//这个是移动文件的方法 Directory.GetFiles(dir);//获取dir路径下的所有文件的全路径 ...
- Integrating JavaScript into Native Applications
JavaScriptCore 简介 iOS7 中新加入的 JavaScriptCore.framework 可能被大多数开发人员所忽略,但是如果你之前就在项目中用过自己编译JavaScriptCore ...
- 【暑假】[深入动态规划]UVa 1628 Pizza Delivery
UVa 1628 Pizza Delivery 题目: http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=51189 思路: ...
- MapReduce 支持的部分数据挖掘算法
MapReduce 支持的部分数据挖掘算法 MapReduce 能够解决的问题有一个共同特点:任务可以被分解为多个子问题,且这些子问题相对独立,彼此之间不会有牵制,待并行处理完这些子问题后,任务便被解 ...