iOS之网络请求初解-AFNetworking(包含图片上传)

2016也即将过去,距iPhone4发布已经六年有余,期间iOS也有了很大的更新,在学习iOS的过程中,我们应该也收获了很多,也付出了许多。今天在这儿,我就简单的为大家解析一下关于iOS网络请求的一些事。


对于大部分APP来说,网络请求都是相当重要的,因为在大多数情况下,我们的产品都需要一定程度的网络交互,并以此获取到用户的响应信息,引导用户完成一些网络操作,如最简单的登录注册,以及后续的聊天支付等等。网络请求也有很多种,如http,Https,TCP,UDP协议等等,当然现阶段我使用的最多的还是http与https。


关于http请求,在iOS开发中,使用得较多的是AFNetworking,经过对NSURLRquest高度封装,使得网络请求变的相对简单清晰。通常我们对于处理过后的网络数据会选择建模取值,使数据逻辑变得更清晰,减少页面内的数据判断,提高程序的容错率。建模的话使用的较多的是MJExtension和JSONModel、Mantle等框架,对于框架复杂度的话,大致为MJExtension>JSONModel>Mantle,当然这三者也都有自己的优缺点,就需要大家在实践中去。当然如果网络请求不太复杂,后端逻辑教为严谨的话,我们也可以暂时性的通过对AF简单整理完成此次网络请求,下面我就将POST,GET以及图片上传简单整理如下:

+(void)POSTWithCompleteURL:(NSString *)URLString

                parameters:(id)parameters

                   success:(void (^)(NSURLSessionDataTask *,id))success

                   failure:(void (^)(NSURLSessionDataTask *,NSError *))failure{

    AFHTTPSessionManager * session = [AFHTTPSessionManagermanager];

    session.requestSerializer.timeoutInterval =15.f;

    session.responseSerializer.acceptableContentTypes = [NSSetsetWithObjects:@"application/json",@"application/xml",@"text/json",@"text/javascript",@"text/html",@"text/plain",nil];

    [session POST:URLStringparameters:parameters progress:^(NSProgress *_Nonnull uploadProgress) {

            

        } success:^(NSURLSessionDataTask *_Nonnull task, id _Nullable responseObject) {

            success (task,responseObject);

        } failure:^(NSURLSessionDataTask *_Nullable task, NSError *_Nonnull error) {

            SHOWERROR

            failure (task,error);

        }];


}

+(void)GETWithCompleteURL:(NSString *)URLString

               parameters:(id)parameters

                  success:(void (^)(NSURLSessionDataTask *operation,id responseObject))success

                  failure:(void (^)(NSURLSessionDataTask *operation,NSError *error))failure{

    AFHTTPSessionManager * session = [AFHTTPSessionManagermanager];

    session.responseSerializer.acceptableContentTypes = [NSSetsetWithObjects:@"application/json",@"application/xml",@"text/json",@"text/javascript",@"text/html",@"text/plain",nil];

    [session GET:URLStringparameters:parameters progress:^(NSProgress *_Nonnull downloadProgress) {

        

    } success:^(NSURLSessionDataTask *_Nonnull task, id _Nullable responseObject) {

        success (task,responseObject);


    } failure:^(NSURLSessionDataTask *_Nullable task, NSError *_Nonnull error) {

        failure (task,error);

    }];

}

+(void)NOJSONPOSTWithCompleteURL:(NSString *)URLString

                      parameters:(id)parameters

                         success:(void (^)(NSURLSessionDataTask *operation,id responseObject))success

                         failure:(void (^)(NSURLSessionDataTask *operation,NSError *error))failure{

    AFHTTPSessionManager * session = [AFHTTPSessionManagermanager];

    session.responseSerializer.acceptableContentTypes = [NSSetsetWithObjects:@"application/json",@"application/xml",@"text/json",@"text/javascript",@"text/html",@"text/plain",nil];

    session.responseSerializer = [AFHTTPResponseSerializerserializer];

    [session POST:URLStringparameters:parameters progress:^(NSProgress *_Nonnull uploadProgress) {

        

    } success:^(NSURLSessionDataTask *_Nonnull task, id _Nullable responseObject) {

        success (task,responseObject);

    } failure:^(NSURLSessionDataTask *_Nullable task, NSError *_Nonnull error) {

        SHOWERROR

        failure (task,error);

    }];

    

}


+(void)XXXXPOSTWithCompleteURL:(NSString *)URLString

                    parameters:(id)parameters

                       success:(void (^)(NSURLSessionDataTask *operation,id responseObject))success

                       failure:(void (^)(NSURLSessionDataTask *operation,NSError *error))failure{

    

    

    AFHTTPSessionManager * session = [AFHTTPSessionManagermanager];

    session.responseSerializer.acceptableContentTypes = [NSSetsetWithObjects:@"application/json",@"application/xml",@"text/json",@"text/javascript",@"text/html",@"text/plain",nil];

    session.responseSerializer=[AFHTTPResponseSerializerserializer];

    [session POST:URLStringparameters:parameters progress:^(NSProgress *_Nonnull uploadProgress) {

        

    } success:^(NSURLSessionDataTask *_Nonnull task, id _Nullable responseObject) {

        success (task,responseObject);

    } failure:^(NSURLSessionDataTask *_Nullable task, NSError *_Nonnull error) {

        SHOWERROR

        failure (task,error);

    }];


}


/**

 *  上传图片数组

 *

 *  @param imgArr     图片image数组

 *  @param URLString  接口方法

 *  @param parameters 参数

 *  @param success

 *  @param failure

 */

+(void)POSTImagesWithImgUrlArr:(NSArray *)imgArr

                   CompleteURL:(NSString *)URLString

                    parameters:(id)parameters

                       success:(void (^)(NSURLSessionDataTask *operation,id responseObject))success

                       failure:(void (^)(NSURLSessionDataTask *operation,NSError *error))failure {

    AFHTTPSessionManager *manager = [AFHTTPSessionManagermanager];

    manager.responseSerializer.acceptableContentTypes = [NSSetsetWithObjects:@"application/json",@"application/xml",@"text/json",@"text/javascript",@"text/html",@"text/plain",nil];

    manager.responseSerializer = [AFHTTPResponseSerializerserializer];

    [manager POST:URLStringparameters:parameters constructingBodyWithBlock:^(id<AFMultipartFormData_Nonnull formData) {

        for (int i =0; i < imgArr.count; i ++) {

            UIImage * img = imgArr[i];

            NSURL * urlPath = [UserNetworkingsaveImage:img withName:@"file.jpg"];

            [formData appendPartWithFileURL:urlPathname:@"file"error:nil];

        }

    } progress:^(NSProgress *_Nonnull uploadProgress) {

    } success:^(NSURLSessionDataTask *_Nonnull task, id _Nullable responseObject) {

        if ([responseObjectisKindOfClass:[NSDataclass]]) {

            NSData *doubi = responseObject;

            NSDictionary * dataDic = [NSJSONSerializationJSONObjectWithData:doubioptions:NSJSONReadingAllowFragmentserror:nil];

            success (task,dataDic);

        }else{

            SHOWERROR

        }

        

    } failure:^(NSURLSessionDataTask *_Nullable task, NSError *_Nonnull error) {

        SHOWERROR

        failure (task,error);

    }];

}


我们可以将网络请求整理好放入新建的一个NSObject类中,接下来,就在类里面调用所需要的POST,GET请求等,传入相应的值,也放入一个简单的事例如下:

+ (void)loginWithMobile:(NSString *)mobile

               password:(NSString *)password

              fromlocal:(NSString *)fromlocal

                address:(NSString *)address

                  block:(void (^)(id objc,BOOL success))block;

{


    NSMutableDictionary *dic = [[NSMutableDictionary alloc] init];

    [dic setValue:mobile forKey:@"mobile"];

    [dic setValue:@2 forKey:@"fromlocal"];

    [dic setValue:password forKey:@"password"];

    [dic setValue:address forKey:@"address"];

    [dic setValue:nowVersion forKey:@"version"];

    [dic setValue:@2 forKey:@"type"];


    [UserNetworking POSTWithCompleteURL:BASE_URLWith(@"app/login") parameters:dic success:^(NSURLSessionDataTask *operation,id responseObject) {

        block (responseObject,YES);

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

        block (error.localizedDescription,NO);

    }];



+ (void)uploadImagesWithImgArr:(NSArray *)imgArr

                         block:(void (^)(id objc,BOOL success))block{


    if (imgArr.count ==0) {

        block(nil,NO);

        return;

    }

    NSMutableDictionary *dic = [[NSMutableDictionaryalloc] init];

    [dic setValue:USERIDforKey:@"userid"];

    [dic setValue:nowVersionforKey:@"version"];

    [dic setValue:@2forKey:@"type"];


    [UserNetworkingPOSTImagesWithImgUrlArr:imgArrCompleteURL:BASE_URLWith(@"app/ajaxFileUpload")parameters:dic success:^(NSURLSessionDataTask *operation,id responseObject) {

        block (responseObject,YES);

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

        block (error.localizedDescription,NO);

    }];

}

其实图片上传与普通网络请求相差不多,只是对于图片要做小细节的处理,然后传入相应的参数就可以获取到所需要的数据值,成功与失败都会获得不同的返回,我们再去对返回值进行处理,展示等。

在这简单描述一下部分参数的意义,type通常是为了后台判定数据来源,如安卓,iOS,网页端等,如果服务器出现了问题,也可以第一时间定位到错误来源,便于修改与调整。version则是判断软件版本号,大家知道我们打包产品的时候都会选择不同的版本号,如1.0,1.0.0,1等等,版本号命名也没有强制性的要求,看公司需求以及软件发布频率自己动态的去做调整,版本号主要是为了针对于安装了不同版本用户发提示信息,如提示更新,规避审核,以及区分不同版本,发送不同的提示信息等,这通常需要我们在软件中预留接口与界面,在特定情况下,才选择展示出来,比如活动界面,版本提示升级界面都是这个原理。userid的话,则是后台为了判定是否是该用户进行的本次网络请求,达到一个session的效果,保持本次请求依旧有效。其余参数均为一些常见参数,如手机号,用户名等,则是看该次请求需要哪些参数,一一传进去即可。

在获取到数值过后,我们则需要在页面对数据进行一个简单的处理:

 [UserNetworkinggetReadTaskListAndVersion:nowVersionPage:1block:^(id objc,BOOL success)

    {

        NSLog(@"%@",objc);

        if (success && objc) {

            if ([objc[@"result"]integerValue] && ![objc[@"data"]isKindOfClass:[NSNullclass]] )

            {

                if ( ![objc[@"data1"]isKindOfClass:[NSNullclass]]) {

                    _helpArray = [NSMutableArrayarray];

                    [_helpArrayaddObjectsFromArray:objc[@"data1"]];

                }

                [weakSelf dataProcess:objc];

            } else

            {

                [BaseMethodshowError:objc[@"errmsg"]];

            }

            // 刷新轮播图

            [weakSelf getScrollViewData];

        }

    }];


在这里,我们还是需要简单判断一下请求是否成功,并且是否获取到后台数据,如果成功,且后台数据不为空,我们就可以将数据放入数组,然后一一对应取出来。当然,这种方法在大型项目里并不推荐,因为部分数据处理放在页面中,导致界面繁琐不说,而且缺乏足够的容错率,如果后台空字段传入太多,会导致赋值失败等等。当然,如果是情急之下,或者说请求较为简单,后台设计逻辑严谨的话,也可以适当使用,毕竟省事嘛。

网络请求中,还有诸多方面的问题,如简单的上拉加载,下拉刷新,建模,还有数据安全,数据容错等各个方面,只有在今后的日子与大家慢慢探讨,如果写的不好的地方也欢迎指正,如果喜欢,也可以点个赞支持一下。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值