一聚教程网:一个值得你收藏的教程网站

最新下载

热门教程

iOS常用网络请求方法详解

时间:2022-06-25 23:37:33 编辑:袖梨 来源:一聚教程网

这个常用的网络请求方法优势有:

1.get和post都可调用此方法
2.在UIViewController类里直接用self指针即可调用(因为这个方法是写在UIViewController分类里的),在其他类只需用[UIViewController new]生成个指针即可进行网络请求
3.只需要传入三个参数
4.代码逻辑简单易于理解
5.基于AFNetworking3.1.0

相关代码:

创建一个继承于AFHTTPSessionManager,名为AFAppDotNetAPIClient的类

 代码如下 复制代码

//AFAppDotNetAPIClient.h
 
#import
#import
@interface AFAppDotNetAPIClient : AFHTTPSessionManager
 
//创建单例类的方法声明
+ (instancetype)sharedClient;
 
@end
 
//AFAppDotNetAPIClient.m
 
#import "AFAppDotNetAPIClient.h"
 
@implementation AFAppDotNetAPIClient
 
//创建单例类的方法实现
+ (instancetype)sharedClient{
    //初始化一个静态的类指针
    static AFAppDotNetAPIClient *sharedClient;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        sharedClient = [AFAppDotNetAPIClient new];
        
        //AFNetworking请求头信息相关设置
        sharedClient.requestSerializer = [AFJSONRequestSerializer serializer];
        [sharedClient.requestSerializer setValue:@"application/json;charset=utf-8" forHTTPHeaderField:@"Content-Type"];
        
        //AFNetworking获取到的参数相关设置
        sharedClient.responseSerializer = [AFJSONResponseSerializer serializer];
        sharedClient.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json", @"text/json", @"text/html", @"text/javascript", nil];
        //SSL相关设置
        sharedClient.securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeNone];
    });
    
    return sharedClient;
}
@end

写在UIViewController分类里的网络请求方法:

 代码如下 复制代码

- (NSURLSessionDataTask *)defaultRequestwithURL: (NSString *)URL withParameters: (NSDictionary *)parameters withMethod: (NSString *)method withBlock:(void (^)(NSDictionary *dict, NSError *error))block
{
    //默认打印传入的实参
#ifdef DEBUG
    NSLog(@"common method = %@", method);//get 或 post
    NSLog(@"common URL = %@", URL);//所请求的网址
    NSLog(@"common parameters = %@", parameters);//传入的参数
#endif
    
    //根据method字符串判断调用AFNetworking里的get方法还是post方法
    if ( [method isEqualToString:@"GET"] ) {//所用到的是AFNetworking3.1.0里的方法,其新加了progress进度block
        return [[AFAppDotNetAPIClient sharedClient] GET:URL parameters:parameters progress:^(NSProgress * _Nonnull downloadProgress) {
 
        } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable JSON) {
    #ifdef DEBUG
            NSLog(@"common get json = %@", JSON);//打印获取到的json
    #endif
            
            NSDictionary *dict = JSON;//直接返回字典,方便使用
            
            if (block) {
                block(dict, nil);
            }
        } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
            //如果请求出错返回空字典和NSError指针
            if (block) {
                block([NSDictionary dictionary], error);//这一点算是比较坑的地方了,因为比如我要根据一个字段来判断是否请求成功,我对一个空字典@{},
//根据一个key取value:[@{} objectForKey:@"errorCode"],
//然后判断字符串的intValue是否等于0:[[@{} objectForKey:@"errorCode"] intValue] == 0是返回1的。
//我想的解决办法就是从服务器端来改,返回的字段key用isSuccess,value是字符串True或False即可解决,
//但是这样又只能知道成功或失败并不能根据errorCode码进行其他操作,因为errorCode可以为0、1、2、3等等。
            }
            
            //从指针级判断error是否为空,如果不为空就打印error
            if (error) {
                NSLog(@"%@",error);
            }
        }];
    }
 
    //post相关代码
    return [[AFAppDotNetAPIClient sharedClient]POST:URL parameters:parameters progress:^(NSProgress * _Nonnull uploadProgress) {
        
    } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable JSON) {
    #ifdef DEBUG
        NSLog(@"common post json = %@", JSON);//打印获取到的json
    #endif
        
        NSDictionary *dict = JSON;//直接返回字典,方便使用
        
        if (block) {
            block(dict, nil);
        }
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        //如果请求出错返回空字典和NSError指针
        if (block) {
            block([NSDictionary dictionary], error);
        }
        
        //从指针级判断error是否为空,如果不为空就打印error
        if (error) {
            NSLog(@"%@",error);
        }
    }];
    
    //返回值暂时用不到,不需要创建变量接收;传进的self指针也没有用到所以这个方法可移植性很强
}

-(void)request
{
    //测试网络请求方法
    //1.所用到的网址是本人以前抓到的,API是用php写的,服务器很稳定,我常用来测试,也仅供测试
    //2.get参数 start和end传无符号整数
    NSDictionary *parameters = @{
                                 @"type":@"list",
                                 @"city":@"2",
                                 @"lid":@"31",
                                 @"sortby":@"1",
                                 @"start":@"0",
                                 @"end":@"3"
                                 };
  
    [self defaultRequestwithURL:@"/api.php" withParameters:parameters withMethod:@"GET" withBlock:^(NSDictionary *dict, NSError *error) {
 
    }];
}

额外附送多图上传方法,同样基于AFNetworking3.1.0,和以上方法类似所以不加详解注释了:

 代码如下 复制代码

-(void)startMultiPartUploadTaskWithURL:(NSString *)url
                           imagesArray:(NSArray *)images
                     parameterOfimages:(NSString *)parameter
                        parametersDict:(NSDictionary *)parameters
                      compressionRatio:(float)ratio
                          succeedBlock:(void (^)(NSDictionary *dict))succeedBlock
                           failedBlock:(void (^)(NSError *error))failedBlock{
    if (images.count == 0) {
        NSLog(@"图片数组计数为零");
        return;
    }
    for (int i = 0; i < images.count; i++) {
        if (![images[i] isKindOfClass:[UIImage class]]) {
            NSLog(@"images中第%d个元素不是UIImage对象",i+1);
        }
    }
    
    AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
    
    [manager POST:url parameters:parameters constructingBodyWithBlock:^(id  _Nonnull formData) {
        int i = 0;
        //根据当前系统时间生成图片名称
        NSDate *date = [NSDate date];
        NSDateFormatter *formatter = [[NSDateFormatter alloc]init];
        [formatter setDateFormat:@"yyyy年MM月dd日"];
        NSString *dateString = [formatter stringFromDate:date];
        
        for (UIImage *image in images) {
            NSString *fileName = [NSString stringWithFormat:@"%@%d.png",dateString,i];
            NSData *imageData;
            if (ratio > 0.0f && ratio < 1.0f) {
                imageData = UIImageJPEGRepresentation(image, ratio);
            }else{
                imageData = UIImageJPEGRepresentation(image, 1.0f);
            }
            [formData appendPartWithFileData:imageData name:parameter fileName:fileName mimeType:@"image/jpg/png/jpeg"];
        }
    } progress:^(NSProgress * _Nonnull uploadProgress) {
        
    } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:responseObject options:NSJSONReadingMutableContainers error:nil];
        
        NSLog(@"common post json = %@", dict);
        
        succeedBlock(dict);
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        if (error) {
            failedBlock(error);
            
            NSLog(@"%@",error);
        }
    }];
}

热门栏目