iOS原生网络请求封装

作者: superLee | 来源:发表于2017-03-10 15:08 被阅读2367次

    在iOS开发中, 有很多十分好用的库, 以至于大家达成了共识, 每次在遇到这个功能自然而然的就想到用哪个第三方库. 这是很好的, 毕竟是各种大牛的长时间维护的劳动成果. 但是作为开发者, 只会用别人的第三方库, 就对自身的技术成长有很大的障碍. 我们需要知道他们是怎么实现的, 大家可以抽空看看平时经常用的各种第三方库的源码, 相信你最后会技术大涨!
    在这里, 我们是要介绍一下关于网络请求, 大家都知道AFNetworking, 这是当然的, 因为这是一个相当成熟的库, 几乎绝大多数iOSapp都在用它. 但是我们这里想介绍一下如何利用NSURLSession, 自己写一个请求类, 可以不依赖于其他第三方库.

    LCNetworking.h
    #import <UIKit/UIKit.h>
    #import <Foundation/Foundation.h>
    
    typedef void (^SuccessBlock)(id responseObject);
    typedef void (^FailureBlock)(NSString *error);
    
    
    @interface LCNetworking : NSObject
    //原生GET网络请求
    + (void)getWithURL:(NSString *)url Params:(NSDictionary *)params success:(SuccessBlock)success failure:(FailureBlock)failure;
    
    + (void)PostWithURL:(NSString *)url Params:(NSDictionary *)params success:(SuccessBlock)success failure:(FailureBlock)failure;
    
    @end
    
    LCNetworking.m
    #import "LCNetworking.h"
    
    NSString *const ResponseErrorKey = @"com.alamofire.serialization.response.error.response";
    NSInteger const Interval = 3;
    
    @interface LCNetworking ()
    
    @end
    
    @implementation LCNetworking
    
    
    //原生GET网络请求
    + (void)getWithURL:(NSString *)url Params:(NSDictionary *)params success:(SuccessBlock)success failure:(FailureBlock)failure
    {
        //完整URL
        NSString *urlString = [NSString string];
        if (params) {
            //参数拼接url
            NSString *paramStr = [self dealWithParam:params];
            urlString = [url stringByAppendingString:paramStr];
        }else{
            urlString = url;
        }
        //对URL中的中文进行转码
        NSString *pathStr = [urlString stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
    
        NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:pathStr]];
    
        request.timeoutInterval = Interval;
    
        NSURLSessionDataTask *task = [[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        dispatch_async(dispatch_get_main_queue(), ^{
            if (data) {
                //利用iOS自带原生JSON解析data数据 保存为Dictionary
                NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
                success(dict);    
            }else{
                NSHTTPURLResponse *httpResponse = error.userInfo[ResponseErrorKey];
                
                if (httpResponse.statusCode != 0) {
                    
                    NSString *ResponseStr = [self showErrorInfoWithStatusCode:httpResponse.statusCode];
                    failure(ResponseStr);
                    
                } else {
                    NSString *ErrorCode = [self showErrorInfoWithStatusCode:error.code];
                    failure(ErrorCode);
                }
            }
        });
        [task resume];
    }
    
    //原生POST请求
    + (void)PostWithURL:(NSString *)url Params:(NSDictionary *)params success:(SuccessBlock)success failure:(FailureBlock)failure{
    
        NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url]];
        [request setHTTPMethod:@"POST"];
    
        //把字典中的参数进行拼接
        NSString *body = [self dealWithParam:params];
        NSData *bodyData = [body dataUsingEncoding:NSUTF8StringEncoding];
    
        //设置请求体
        [request setHTTPBody:bodyData];
        //设置本次请求的数据请求格式
        [request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
        // 设置本次请求请求体的长度(因为服务器会根据你这个设定的长度去解析你的请求体中的参数内容)
        [request setValue:[NSString stringWithFormat:@"%ld", bodyData.length] forHTTPHeaderField:@"Content-Length"];
        //设置请求最长时间
        request.timeoutInterval = Interval;
    
        NSURLSessionTask *task = [[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
     
        if (data) {
            //利用iOS自带原生JSON解析data数据 保存为Dictionary
            NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
            success(dict);
            
        }else{
            NSHTTPURLResponse *httpResponse = error.userInfo[ResponseErrorKey];
            
            if (httpResponse.statusCode != 0) {
                
                NSString *ResponseStr = [self showErrorInfoWithStatusCode:httpResponse.statusCode];
                failure(ResponseStr);
                
                } else {
                    NSString *ErrorCode = [self showErrorInfoWithStatusCode:error.code];
                    failure(ErrorCode);
                }
            }
        }];
        [task resume];
    }
    

    使用方法:
    直接把这两个类拖到要使用的项目中, 导入头文件, 然后调取.h文件里面留的接口就可以, 这些东西就不详细的说了.

    这里是使用demo的地址, 不会的可以参照demo使用:
    https://github.com/LeoTnT/LCNetWorking

    注意: 这个网络请求类只是实现了GET, POST的请求, 没有具体配置, 如果要使用还要参照具体情况再改代码, 谢谢~

    相关文章

      网友评论

        本文标题:iOS原生网络请求封装

        本文链接:https://www.haomeiwen.com/subject/finngttx.html