蓝懿ios技术交流和心得分享12.15

来源:互联网 发布:软件开发需求调研 编辑:程序博客网 时间:2024/05/17 06:49

 转眼又到了练习日   我们复习一下这段时间学的一些知识:

大量数据通过Socket传输:

1、客户端发送时对文件进行处理:

NSString *filePath = @"/Users/ivan/Documents/第二期/视频/day29/3打地鼠续.mp4";      

        NSData *fileData = [NSData dataWithContentsOfFile:filePath];

        //文件名和文件长度拼接到一个字符串中

        NSString *headerString = [NSString stringWithFormat:@"%@&&%ld",[filePathlastPathComponent],fileData.length];

        NSData *headerData = [headerString dataUsingEncoding:NSUTF8StringEncoding];

        NSLog(@"%ld",headerData.length);

        //创建一个100个字节的data

        NSMutableData *allData = [NSMutableDatadataWithLength:100];

        //替换一部分

        [allData replaceBytesInRange:NSMakeRange(0, headerData.length)withBytes:headerData.bytes];

        //把文件数据追加到后面

        [allData appendData:fileData];

// 往端口写数据

 [self.clientSocketwriteData:allData withTimeout:-1tag:0];​

//创建客户端socket

        self.clientSocket = [[AsyncSocketalloc]initWithDelegate:self];

   //建立链接

        [self.clientSocketconnectToHost:self.hostTF.textonPort:8000error:nil];

2、服务器接收到数据时进行处理:

//已经读取到数据​

-(void)onSocket:(AsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag{

    //取出前100个字节的数据

    NSData *headerData = [data subdataWithRange:NSMakeRange(0, 100)];

    NSString *headerString = [[NSStringalloc]initWithData:headerDataencoding:NSUTF8StringEncoding];

    //判断是不是头数据

    if (headerString&&[headerString componentsSeparatedByString:@"&&"].count==2) {//是头数据

        NSArray *headers = [headerString componentsSeparatedByString:@"&&"];

        self.fileName = headers[0];

        self.length = [headers[1] longLongValue];

        //抛去头剩下的文件数据得到

        NSData *subFileData = [data subdataWithRange:NSMakeRange(100, data.length-100)];

        //每次接收到头的话都初始化data避免多个文件data在同一个data中

        self.allData = [NSMutableData data];

        [self.allData appendData:subFileData];

    }else{//不包含头的数据

        [self.allData appendData:data];   

    }

    //判断文件是否传输完成

    if (self.allData.length==self.length) {

        //把传过来的数据储存

        NSString *newPath = [@"/Users/ivan/Desktop/a"stringByAppendingPathComponent:self.fileName];

        //加载到内存中也是二进制数据

        [self.allData writeToFile:newPath atomically:YES];

        

    }

    //把传输过来的二进制数据转成字符串

    NSLog(@"%ld",data.length);

    //调用读取数据的方法  防止一个文件一次没传完

    [self.myNewSocketreadDataWithTimeout:-1tag:0];

网络请求:

一、直接从网络上加载图片:

导入:​#import "UIImageView+AFNetworking.h"

 

    NSString *path = @"http://pic28.nipic.com/20130419/12299514_180213138000_2.jpg";

    UIImageView *iv = [[UIImageViewalloc]initWithFrame:self.view.bounds];

    [iv setImageWithURL:[NSURL URLWithString:path]];

    [iv setImageWithURL:[NSURLURLWithString:path] placeholderImage:[UIImageimageNamed:@"a.png"]];

    [self.view addSubview:iv];

二、纯代码添加UINavigationController

    self.window = [[UIWindowalloc]initWithFrame:[UIScreenmainScreen].bounds];

    ViewController * vc = [[ViewControlleralloc]init];

    UINavigationController * nv = [[UINavigationControlleralloc]initWithRootViewController:vc];

    self.window.rootViewController =nv;

    [self.windowmakeKeyAndVisible];

三、从网络请求数据:有get 和post两种方法

get方法:​

导入:#import "AFNetworking.h"​

//    使用AFNetworking发出http请求

    NSString *webPath = @"http://apis.juhe.cn/cook/query";

//    key=&menu=黄焖鸡&rn=10&pn=3

    NSDictionary *params =@{@"key":@"80996127f667eac43832103850b3b13a",@"menu":@"黄焖鸡",@"rn":@"10"};

    AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManagermanager];

//   使用manager发出请求的时候需要做一下响应数据的序列化

    [manager setResponseSerializer:[AFHTTPResponseSerializerserializer]];

    //用get请求,若webPath已经包含所有信息,则id后边写nil

    [manager GET:webPath parameters:params success:^(AFHTTPRequestOperation *operation, id responseObject) {

        NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:responseObject options:0error:nil];

        NSLog(@"请求成功:%@",dic);

    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {

        NSLog(@"请求失败");

    }];

Socket连接与HTTP连接 一、Socketsocket是对TCP/IP协议的封装,Socket本身并不是协议,而是一个调用接口(API)。 通过Socket,我们才能使用TCP/IP协议。Socket的出现只是使得程序员更方便地使用TCP/IP协议而已TCP/IP也要提供可供程序员做网络开发所用的接口,这就是Socket编程接口​二、TCP和UDP1、TCP是面向链接的,TCP的三次握手在最低限度上(实际上也很大程度上保证了)保证了连接的可靠性; 而UDP不是面向连接的,UDP传送数据前并不与对方建立连接,对接收到的数据也不发送确认信号,发送端不知道数据是否会正确接收,当然也不用重发,所以说UDP是无连接的、不可靠的一种数据传输协议。2、也正由于1所说的特点,使得UDP的开销更小数据传输速率更高,因为不必进行收发数据的确认,所以UDP的实时性更好。知道了TCP和UDP的区别,就不难理解为何采用TCP传输协议的MSN比采用UDP的QQ传输文件慢了,但并不能说QQ的通信是不安全的,因为程序员可以手动对UDP的数据收发进行验证,比如发送方对每个数据包进行编号然后由接收方进行验证,UDP因为在底层协议的封装上没有采用类似TCP的“三次握手”导致效率更高。三、Socket连接与HTTP连接​由于通常情况下Socket连接就是TCP连接,因此Socket连接一旦建立,通信双方即可开始相互发送数据内容,直到双方连接断开。但在实际网络应用中,客户端到服务器之间的通信往往需要穿越多个中间节点,例如路由器、网关、防火墙等,大部分防火墙默认会关闭长时间处于非活跃状态的连接而导致 Socket 连接断连,因此需要通过轮询告诉网络,该连接处于活跃状态。 而HTTP连接使用的是“请求—响应”的方式,不仅在请求时需要先建立连接,而且需要客户端向服务器发出请求后,服务器端才能回复数据。很多情况下,需要服务器端主动向客户端推送数据,保持客户端与服务器数据的实时与同步。此时若双方建立的是Socket连接,服务器就可以直接将数据传送给客户端;若双方建立的是HTTP连接,则服务器需要等到客户端发送一次请求后才能将数据传回给客户端,因此,客户端定时向服务器端发送连接请求,不仅可以保持在线,同时也是在“询问”服务器是否有新的数据,如果有就将数据传给客户端。Sockt:传输效率高因为可以完全自定义头数据 对程序员要求高 ,可实现即使通讯HTTP:容错性强 开发效率高 http工作中用到更多

简单快速

因为HTTP协议简单,所以HTTP服务器的程序规模小,因而通信速度很快灵活HTTP允许传输任意类型的数据HTTP 0.9和1.0使用非持续连接限制每次连接只处理一个请求,服务器对客户端的请求做出响应后,马上断开连接,这种方式可以节省传输时间

弹出提示框:

1、创建alert 

UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"提示" message:@"发送成功"preferredStyle:UIAlertControllerStyleAlert];

//添加可输入文字的t f

          __block UITextField *tf = nil;

   [alert addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) {

                   tf = textField;

               textField.backgroundColor = [UIColor greenColor];

       }];

2、设置按钮文字和样式

        UIAlertAction *cancel = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:nil];

        

        UIAlertAction *confirm = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefaulthandler:^(UIAlertAction *action){

            //确定时做的事

            [self.navigationController popToRootViewControllerAnimated:YES];

            //NSLog(@"%@",tf.text);

        }];

 3、添加点击时间

        [alert addAction:cancel];

        [alert addAction:confirm];

一、用AFNetwork检测网络

AFNetworkReachabilityManager *manager = [AFNetworkReachabilityManagersharedManager];

    [manager startMonitoring];

    [manager setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {

        NSLog(@"%ld", status);

        switch (status) {

            caseAFNetworkReachabilityStatusReachableViaWiFi:

                NSLog(@"wifi");

                break;

            caseAFNetworkReachabilityStatusNotReachable:

                NSLog(@"没有网络");

                break;

            caseAFNetworkReachabilityStatusUnknown:

                NSLog(@"未知");

                break;

            caseAFNetworkReachabilityStatusReachableViaWWAN:

                NSLog(@"手机网络");

                break;

            default:

                break;

        }

    }];

二、通过operation发请求

 NSString *path = @"http://op.juhe.cn/robot/index

";

  //post请求方式需要把请求参数放到请求体里面

  NSString *params = @"info=北京天气怎么样?&key=ef26597f6f8c4574e14769cf7610ece0";

  NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:path]];

    //设置请求方式,默认为GET请求

   [request setHTTPMethod:@"POST"];

    //设置请求体

    [request setHTTPBody:[params dataUsingEncoding:NSUTF8StringEncoding]];

    AFHTTPRequestOperation *op = [[AFHTTPRequestOperation alloc]initWithRequest:request];

   

    [op setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {

        NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:responseObject options:0 error:nil];       

      NSLog(@"请求成功!%@",dic);

   } failure:^(AFHTTPRequestOperation *operation, NSError *error) {

       NSLog(@"请求失败!");

   }];

  //开始执行任务

    [op start];

    三、通过manager发送请求

    NSString *path = @"http://op.juhe.cn/robot/index";

    AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManagermanager];

    //设置响应序列化

    [manager setResponseSerializer:[AFHTTPResponseSerializerserializer]];

//    @"info=北京天气怎么样?&key=ef26597f6f8c4574e14769cf7610ece0"

    NSDictionary *dic = @{@"info":@"滚犊子",@"key":@"ef26597f6f8c4574e14769cf7610ece0"};

    [manager GET:path parameters:dic success:^(AFHTTPRequestOperation *operation, idresponseObject) {

        NSDictionary *d = [NSJSONSerialization JSONObjectWithData:responseObject options:0error:nil];

        NSLog(@"成功:%@",d[@"result"][@"text"]);

    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {

        NSLog(@"失败");

    }];

/    边框颜色

    iv.layer.borderColor = [UIColorgreenColor].CGColor;

//    设置粗细

    iv.layer.borderWidth = 3;

//    设置圆角

    iv.layer.cornerRadius = 50;

//    把边框外部的内容去掉

    iv.layer.masksToBounds =YES;

    CALayer *layer = [CALayer layer];

    layer.contents = (id)[UIImageimageNamed:@"a.jpg"].CGImage;

    

    layer.frame = CGRectMake(0, 0, 100, 100);

    layer.borderWidth = 5;

//    如果当锚点为.5.5默认值时 position就相当于center

    layer.position = CGPointMake(0,0);

//    参照点 默认是.5.5 中心点 00是左上角 11是又下角

    layer.anchorPoint = CGPointMake(0, 0);

//    阴影颜色

    layer.shadowColor = [UIColoryellowColor].CGColor;

//  阴影偏移位置

    layer.shadowOffset = CGSizeMake(30, 30);

//    浓度 0-1

    layer.shadowOpacity = .5;

//    扩散效果

    layer.shadowRadius = 30;

    [self.view.layer addSublayer:layer];

    

}


MBProgressHUB框架:主要用于网络请求显示加载进度,应用范围广泛。

1、基本显示效果:

  •  [MBProgressHUD showHUDAddedTo:self.viewanimated:YES];

       dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

           [NSThreadsleepForTimeInterval:3];

          dispatch_async(dispatch_get_main_queue(), ^{

              [MBProgressHUDhideHUDForView:self.view animated:YES];

           });

       });

2、显示进度:

  • MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:self.viewanimated:YES];

    hud.mode =MBProgressHUDModeAnnularDeterminate;

    hud.labelText =@"Loading";

    hud.color = [UIColorblueColor];

    hud.labelColor = [UIColorredColor];

   dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0), ^{

       for (int i=0; i<100; i++) {

           [NSThreadsleepForTimeInterval:.01];

          dispatch_async(dispatch_get_main_queue(), ^{

              hud.progress+=0.01;

              if (i==99) {

                 [hud hide:YES];

              }

           });

       }

    });

3、自定义效果:

  • MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:self.viewanimated:YES];

    hud.mode =MBProgressHUDModeCustomView;

    hud.labelText =@"Loading";

    hud.customView =[[UIImageView alloc]initWithImage:[UIImageimageNamed:@"8.jpg"]];

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0), ^{

               [NSThreadsleepForTimeInterval:3];

          dispatch_async(dispatch_get_main_queue(), ^{

                 [hud hide:YES];

           });

    });

 

  • 获取当前时间的秒数:拿到1970年到现在过的总秒数;

NSTimeInterval time = [[NSDate date] timeIntervalSince1970];

long long int date = (long long int)time;

NSLog(@”date\n%lld”, date); //1295322949

//把秒数转化成yyyy-MM-dd hh:mm:ss格式

NSDate *dd = [NSDate dateWithTimeIntervalSince1970:date];

NSLog(@”d:%@”,dd); //2011-01-18 03:55:49 +0000

//微博返回的时间格式​,字母为固定的,大小写不能错;

    NSDateFormatter *fmt = [[NSDateFormatteralloc] init];

//    EEE星期 MMM月 dd日 HH小时 mm分 ss秒 Z时区 yyyy年

    fmt.dateFormat = @"EEE MMM dd HH:mm:ss Z yyyy";

    //英文

  fmt.locale = [[NSLocalealloc] initWithLocaleIdentifier:@"en_US"];

       

//

 获得微博发布的具体时间 (倒推回去)

    NSDate *createDate = [fmt dateFromString:_created_at];

    //获取当前时间对象

    NSDate *nowDate = [NSDate date];

    long createTime = [createDate timeIntervalSince1970];

    long nowTime = [nowDate timeIntervalSince1970];

    long time = nowTime-createTime;

    if (time<<span se-mark="1">60) {

        return @"刚刚";

    }else if (time<<span se-mark="1">3600){

        return [NSString stringWithFormat:@"%ld分钟前",time/60];

    }else if (time<<span se-mark="1">3600*24){

        return [NSString stringWithFormat:@"%ld小时前",time/3600];

    }

//自己重新定义显示格式​

        fmt.

dateFormat

 = @"MM月dd日 HH:mm";

    return [fmt stringFromDate:createDate];

另外在分享一些常见 的错误:

1.[ setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key resultLabel.出错原因:sb控件和代码关联出错解决方案:找到相对应的页面的黄色圆点(ViewController)在此上面右键 删除 黄色叹号2.<__NSArrayM: 0x7c0320b0> was mutated while being enumerated.出错原因:forin循环时修改了数组 但继续循环了解决方案: 修改数组后 加break或return3.-[__NSArrayM objectAtIndex:]: index 3 beyond bounds [0 .. 0]'出错原因:数组角标越界解决方案:角标的取值 要小于数组的count4.-[ViewController addZombX]: unrecognized selector sent to instance 0x79174e00'出错原因:在ViewController中找不到方法

解决方案:在某个类中没有实现这个方法  或者是对象类型错了

5.This application is modifying the autolayout engine from a background thread出错原因:子线程中修改了界面解决方案:回到主线程修改就可以了6.An

instance 0x7fb6dad221e0 of class Mouse was deallocated

while key value observers were still registered with it

原因:监听了一个已经被释放的对象

解决方案:在适当的位置删除监听

    学习ios  重要还是要理清楚思路  在做或者看老师代码的时候 自己多想想为什么  不要自己看着就抄       另外还是要推荐一下 蓝懿IOS这个培训机构  和刘国斌老师刘国斌老师还是很有名气的,听朋友说刘老师成立了蓝懿iOS,,老师讲课方式很独特,能够尽量让每个人都能弄明白,有的比较难懂的地方,如果有的地方还是不懂得话,老师会换个其它方法再讲解,这对于我们这些学习iOS的同学是非常好的,多种方式的讲解会理解得更全面,这个必须得给个赞,嘻嘻,还有就是这里的学习环境很好,很安静,可以很安心的学习,安静的环境是学习的基础,小班讲课,每个班20几个学生,学习氛围非常好,每天都学到9点多才离开教室,练习的时间很充裕,而且如果在练习的过程中有什么困难,随时可以向老师求助,不像其它机构,通过视频教学,有的甚至学完之后都看不到讲师本人,问点问题都不方便,这就是蓝懿与其它机构的区别,相信在刘国斌老师的细心指导下,每个蓝懿学员都能找到满意的工作,加油!

                                                                  写博客第六十六天;

                                                                              QQ:565803433


0 0
原创粉丝点击