iOS 开发之网络编程(二)


第三方网络框架
  • AFNetworking

一款轻量级网络请求开源框架,基于iOSmac OS 网络进行扩展的高性能框架,大大降低了iOS开发工程师处理网络请求的难度,让iOS开发变成一件愉快的事情。

  • AFNetworking优点

1.原有基础urlsesson上封装了一层,在传参方面更灵活,
2.回调更友好,
3.支持返回数据序列化
4.支持文件上传,断点下载,
5.自带多线程,防死锁
6.处理了Https证书流程,节省移动端开发
7.支持网络状态判断

AFN.jpeg
  • AFNetWorking发送POST&GET请求:
#import "ViewController.h"
#import "AFNetworking.h"

@interface ViewController ()

@property (strong, nonatomic)AFHTTPSessionManager *manager;

@end

@implementation ViewController

- (AFHTTPSessionManager *)manager{
    
    if (!_manager) {
        _manager = [AFHTTPSessionManager manager];
    }
    
    return _manager;
}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    
//    [self getData];
    
    
    [self postData];
    
}

- (void)postData{
    
    NSString *path = @"http://120.25.226.186:32812/login";
    NSDictionary *parames=@{
                            @"username":@"520it",
                            @"pwd":@"520it",
                            @"type":@"JSON"
                            };
    [self.manager POST:path parameters:parames headers:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        
        NSLog(@"success:----%@-%@",[responseObject class],responseObject);
        
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        
        NSLog(@"failuer:----%@",error);
    }];
    
}

- (void)getData{
    
//    AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];

    /**
     * 参数说明
     *
     * 第一个参数:请求的路径(NSString)不包含参数
     * 第二个参数:需要传入的参数
     * 第三个参数:附加到此请求的默认头的头
     * 第四个参数:请求数据的进度
     * 第五个参数:请求成功后的回调
     *           task:可以拿到响应头信息
                 responseObject:响应体信息 AFN内部默认对服务器返回数据进行json解析
     *
     * 第六个参数:请求失败后的回调
     *
     */
    NSString *path = @"http://120.25.226.186:32812/login";
    NSDictionary *parames=@{
                            @"username":@"520it",
                            @"pwd":@"520it",
                            @"type":@"JSON"
                            };
    [self.manager GET:path parameters:parames headers:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        
        NSLog(@"success:----%@-%@",[responseObject class],responseObject);
        
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        
        NSLog(@"failuer:----%@",error);
        
    }];
    
}
@end

-AFNetWorking文件下载&上传

#import "ViewController.h"
#import "AFNetworking.h"

@interface ViewController ()

@property (strong, nonatomic)AFHTTPSessionManager *manager;

@end

@implementation ViewController

- (AFHTTPSessionManager *)manager{
    
    if (!_manager) {
        
        _manager = [AFHTTPSessionManager manager];
        
    }
    
    return _manager;
    
}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    
//    [self downLoad];
    
    [self upLoad];
    
}

//上传
- (void)upLoad{
    
    NSString *urlPath = @"http://120.25.226.186:32812/upload";
    NSDictionary *params = @{
                            @"username":@"aaaaa"
                            };
    /**
     * 参数说明
     *
     * 第一个参数:请求路径
     * 第二个参数:非文件参数:oc的字典(NSDictionary)
     * 第三个参数:constructingBodyWithBlock 处理要上传的文件参数的
     * 第四个参数:progress进度的回调
     * 第五个参数:success上传成功的回调
     *           task
     *           responseObject响应体信息(内部已经完成了JSON解析)
     * 第六个参数:failure上传失败的回调
     *
     */
    
    [self.manager POST:urlPath parameters:params headers:nil constructingBodyWithBlock:^(id<AFMultipartFormData>  _Nonnull formData) {
        //id<AFMultipartFormData>协议:遵守这个协议就可以该协议中的方法
        
        //处理要上传的文件

        NSString *path = @"/Users/nana/Desktop/timg.jpeg";
        NSURL *url = [NSURL fileURLWithPath:path];
    
        //第一种方法
        
        /**
         * 参数说明
         *
         * 第一个参数:FileData:要上传文件的二进制数据
         * 第二个参数:name:具体的数值 file
         * 第三个参数:fileName:文件的名称
         * 第四个参数:mimeType:文件的二进制数据类型
         *
         */
        
//        NSData *imageData = [NSData dataWithContentsOfFile:path];
//        [formData appendPartWithFileData:imageData name:@"file" fileName:url.lastPathComponent mimeType:@"image/jpeg"];
        
        //第二种方法
        
        /**
         * 参数说明
         *
         * 第一个参数:FileURL:本地文件的URL路径
         * 第二个参数:name:具体的数值 file
         * 第三个参数:mimeType:文件的二进制数据类型
         *
         */
//        [formData appendPartWithFileURL:url name:@"file" fileName:url.lastPathComponent mimeType:@"image/jpeg" error:nil];
        
        //第三种方法
        
        /**
         * 参数说明
         *
         * 第一个参数:FileURL:本地文件的URL路径
         * 第二个参数:name:具体的数值 file
         *
         */
        [formData appendPartWithFileURL:url name:@"file" error:nil];
        
    } progress:^(NSProgress * _Nonnull uploadProgress) {
        
        //计算进度信息
    NSLog(@"进度信息:%f",1.0*uploadProgress.completedUnitCount/uploadProgress.totalUnitCount);
        
    } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        
        NSLog(@"success:%@",responseObject);
        
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        
        NSLog(@"failure:%@",error);
        
    }];
    
    
}


//下载
- (void)downLoad{
    
     NSURL *url = [NSURL URLWithString:@"https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1591442074704&di=760001ecc8d2d0df7d98a8d6cc083bce&imgtype=0&src=http%3A%2F%2Fa3.att.hudong.com%2F68%2F61%2F300000839764127060614318218_950.jpg"];

     NSURLRequest *request = [NSURLRequest requestWithURL:url];

    /**
     * 参数说明
     *
     * 第一个参数:Request:请求对象
     * 第二个参数:progress:进度回调
     * 第三个参数:destination回调:需要在该回调中告诉方法应该把下载的文件保存到哪里
     *           targetPath:默认返回的临时存储路径(tmp)
     *           response:响应头信息
     *           返回值:文件应该的存储路径
     * 第四个参数:completionHandler:完成后的回调
     *
     */
     NSURLSessionDownloadTask *downLoadTask = [self.manager downloadTaskWithRequest:request progress:^(NSProgress * _Nonnull downloadProgress) {

        NSLog(@"下载进度:%f",1.0*downloadProgress.completedUnitCount/downloadProgress.totalUnitCount);
        
     }destination:^NSURL * _Nonnull(NSURL * _Nonnull targetPath, NSURLResponse * _Nonnull response) {

        //拼接文件的存储路径给AFN,内部会自动的完成文件的剪切处理
        NSLog(@"targetPath: %@",targetPath);

        NSString *cachesPath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];
        
        NSString *fileName = response.suggestedFilename;
        
        NSString *fullPath = [cachesPath stringByAppendingPathComponent:fileName];
        
        NSLog(@"fullPath:%@",fullPath);
        
        return [NSURL fileURLWithPath:fullPath];
        
     }completionHandler:^(NSURLResponse * _Nonnull response, NSURL * _Nullable filePath, NSError * _Nullable error) {

        //filePath:文件的路径(即上面回调的返回值)
        NSLog(@"filePath:%@",filePath);
        
     }];

     [downLoadTask resume];
}
@end
  • AFNetworkingJson&Xml解析

manager = [AFHTTPSessionManager manager];

manager:内部默认已经对服务器返回的数据进行了JSON解析操作AFJSONResponseSerializer

manager:如果返回的数据是XML类型:需要调整manager对响应的解析方式:AFXMLParserResponseSerializer
manager.responseSerializer = [AFXMLParserResponseSerializer serializer];

manager:如果返回的数据类型既不是json也不是xml
manager.responseSerializer = [AFHTTPResponseSerializer serializer];

#import "ViewController.h"
#import "AFNetworking.h"

@interface ViewController ()<NSXMLParserDelegate>

@property (strong, nonatomic)AFHTTPSessionManager *manager;
/**
 * <#注释#>
 */
@property (strong, nonatomic)NSMutableArray *dataArray;
@end

@implementation ViewController

- (NSMutableArray *)dataArray{
    
    if (!_dataArray) {
        _dataArray = [NSMutableArray array];
    }
    
    return _dataArray;
}


- (AFHTTPSessionManager *)manager{
    
    if (!_manager) {
        
        _manager = [AFHTTPSessionManager manager];
   
      //_manager:内部默认已经对服务器返回的数据进行了JSON解析操作 AFJSONResponseSerializer
  //_manager:如果返回的数据是XML类型:需要调整manager对响应的解析方式:AFXMLParserResponseSerializer
        
        //        _manager.responseSerializer = [AFXMLParserResponseSerializer serializer];
        
        //_manager:如果返回的数据类型既不是json也不是xml

        _manager.responseSerializer = [AFHTTPResponseSerializer serializer];
    }
    
    return _manager;
}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    
    
//    [self getJson];
    
//    [self getXML];
    
//    [self httpData];
    
}

- (void)httpData{
    
    NSString *path = @"http://www.baidu.com";
    NSDictionary *parames=nil;
    
    [self.manager GET:path parameters:parames headers:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        
        NSLog(@"success:----%@",responseObject);
        
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        
        NSLog(@"failuer:----%@",error);
        
    }];
    
}

- (void)getXML{
    
    NSString *path = @"http://120.25.226.186:32812/video";
    
    NSDictionary *parames=@{
                            @"type":@"XML"
                            };
    
    [self.manager GET:path parameters:parames headers:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        
        NSLog(@"success:----%@-%@",[responseObject class],responseObject);
        
        //使用NSXMLParser解析数据
        
        //01 创建解析器
        NSXMLParser *parser = (NSXMLParser *)responseObject;
        
        //02 设置代理
        parser.delegate = self;
        //03 开始解析
        [parser parse];
        
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        
        NSLog(@"failuer:----%@",error);
        
    }];
    
}

- (void)getJson{
    
    
    NSString *path = @"http://120.25.226.186:32812/video";
    NSDictionary *parames=@{
                            @"type":@"JSON"
                            };
    
    //内部默认已经对服务器返回的数据进行了JSON解析操作 AFJSONResponseSerializer
    [self.manager GET:path parameters:parames headers:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        
        NSLog(@"success:----%@-%@",[responseObject class],responseObject);
        
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        
        NSLog(@"failuer:----%@",error);
        
    }];
    
}

#pragma---------------------------------------
#pragma MARK - NSXMLParserDelegate

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary<NSString *,NSString *> *)attributeDict{
    
    NSLog(@"%@ - \n -%@",elementName,attributeDict);
    
    [self.dataArray addObject:attributeDict];
    
}

@end
  • AFNetworking 网络状态监听
- (void)netStateType{
    
    //01 创建网络监听管理者对象
    AFNetworkReachabilityManager *netManager = [AFNetworkReachabilityManager manager];
    //02 监听
    [netManager setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {
        
        //当监听网络装调改变的时候,就会调用block,并且把当前的网络状态作为参数传递给block
        /**
         typedef NS_ENUM(NSInteger, AFNetworkReachabilityStatus) {
             AFNetworkReachabilityStatusUnknown          = -1,
             AFNetworkReachabilityStatusNotReachable     = 0,
             AFNetworkReachabilityStatusReachableViaWWAN = 1,
             AFNetworkReachabilityStatusReachableViaWiFi = 2,
         };
         */
        switch (status) {
                
            case AFNetworkReachabilityStatusUnknown:
                NSLog(@"未知的网络状态");
                break;
                
            case AFNetworkReachabilityStatusNotReachable:
                NSLog(@"没有网络");
                break;
                
            case AFNetworkReachabilityStatusReachableViaWWAN:
                NSLog(@"蜂窝网络");
                break;
                
            case AFNetworkReachabilityStatusReachableViaWiFi:
                NSLog(@"WiFi网络");
                break;
                
            default:
                break;
        }
    }];
    
    //03 开始监听
    [netManager startMonitoring];
    
}
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,324评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,303评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,192评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,555评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,569评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,566评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,927评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,583评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,827评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,590评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,669评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,365评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,941评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,928评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,159评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,880评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,399评论 2 342