iOS 原生NSURLSession 简单的 GET、POST 请求

//  WsqflyNetWorking.h

//  WSQNetWorkingSystem

//

//  Created by webapps on 16/12/28.

//  Copyright © 2016 webapps. All rights reserved.


#import <Foundation/Foundation.h>

#import <UIKit/UIKit.h>


typedef void(^SuccessBlock)(id response);                                 // 成功返回的数据

typedef void(^RequestHeadBlock)(id response);                            // 请求头返回的数据

typedef void(^FaileBlock)(NSError * error);                             // 请求错误返回的数据




typedef NS_ENUM(NSUInteger,WsqflyNetSessionMaskState) {

    

    WsqflyNetSessionMaskStateNone       =  0,                      // 没有菊花

    WsqflyNetSessionMaskStateCanTouch   =  1,                     // 有菊花并点击屏幕有效

    WsqflyNetSessionMaskStateNotTouch   =  2                     // 有菊花单点击屏幕没有效果

  

};


typedef NS_ENUM(NSUInteger,WsqflyNetSessionResponseType){

    WsqflyNetSessionResponseTypeDATA    =  0,                // 返回后台是什么就是什么DATA

    WsqflyNetSessionResponseTypeJSON    =  1                // 返会序列化后的JSON数据

};




@interface WsqflyNetSession : NSObject


//单利

+ (instancetype) wsqflyNetWorkingShare;


//判断是否有网络

//+ (NSString *)connectedToNetwork;



/**GET短数据请求

 * urlString          网址

 * param              参数

 * state              显示菊花的类型

 * backData           返回的数据是NSDATA还是JSON

 * successBlock       成功数据的block

 * faileBlock         失败的block

 * requestHeadBlock   请求头的数据的block

 */

- (void)get1:(NSString *)urlString param:(NSDictionary *)param maskState:(WsqflyNetSessionMaskState)state backData:(WsqflyNetSessionResponseType)backData success:(SuccessBlock)successBlock requestHead:(RequestHeadBlock)requestHeadBlock faile:(FaileBlock)faileBlock;



/**POST短数据请求

 * urlString           网址

 * param               参数

 * state               显示菊花的类型

 * backData            返回的数据是NSDATA还是JSON

 * successBlock        成功数据的block

 * faileBlock          失败的block

 * requestHeadBlock    请求头的数据的block

 */


-(void)post:(NSString *)urlString bodyparam:(NSDictionary *)param maskState:(WsqflyNetSessionMaskState)state backData:(WsqflyNetSessionResponseType)backData success:(SuccessBlock)successBlock requestHead:(RequestHeadBlock)requestHeadBlock faile:(FaileBlock)faileBlock;




//

//  WsqflyNetWorking.m

//  WSQNetWorkingSystem

//

//  Created by webapps on 16/12/28.

//  Copyright © 2016 webapps. All rights reserved.

//


#import "WsqflyNetSession.h"

#import "RealReachability.h"


#define CONTECTTIME  30  // 联网时间


@interface WsqflyNetSession ()


@property (nonatomic,strong)UIActivityIndicatorView * wsqAView;

@property (nonatomic,assign)int maskCount;


@end




@implementation WsqflyNetSession



static id _instance;

+ (instancetype)allocWithZone:(struct_NSZone *)zone

{

    staticdispatch_once_t onceToken;

    dispatch_once(&onceToken, ^{

        _instance = [superallocWithZone:zone];

    });

    return_instance;

}


+ (instancetype)wsqflyNetWorkingShare

{

    staticdispatch_once_t onceToken;

    dispatch_once(&onceToken, ^{

        _instance = [[selfalloc] init];

    });

    return_instance;

}


- (instancetype)init{

    

    if (self = [superinit]) {

        _wsqAView = [[UIActivityIndicatorViewalloc] initWithFrame:[UIScreenmainScreen].bounds];

        _wsqAView.color = [UIColorblackColor];

    }

    returnself;

}



#pragma mrak 判断是否联网

//+ (NSString *)connectedToNetwork

//{

//    NSString *netString;

//    ReachabilityStatus status = [GLobalRealReachability currentReachabilityStatus];

//    

//    switch (status) {

//        case -1:

//            netString = @"网络异常!";

//            break;

//        case 0:

//            netString = @"连接不到网络!";

//            break;

//        case 1:

//            netString = @"正在使用流量上网!";

//            break;

//        case 2:

//            netString = @"正在使用wifi上网!";

//            break;

//            

//        default:

//            break;

//    }

//    return netString;

//}



#pragma MARK-- GET


- (void)get1:(NSString *)urlString param:(NSDictionary *)param maskState:(WsqflyNetSessionMaskState)state backData:(WsqflyNetSessionResponseType)backData success:(SuccessBlock)successBlock requestHead:(RequestHeadBlock)requestHeadBlock faile:(FaileBlock)faileBlock{

    

    NSURL *url;

    

 

    NSString *string = [NSStringstring];

    if (param) {//带字典参数

        string = [selfnsdictionaryToNSStting:param];

        

           //1. GET 请求,直接把请求参数跟在URL的后面以?(问号前是域名与/接口名)隔开,多个参数之间以&符号拼接

         url = [NSURLURLWithString:[selfurlConversionFromOriginalURL:[NSStringstringWithFormat:@"%@&%@",urlString,string]]];

    }else{

           //1. GET 请求,直接把请求参数跟在URL的后面以?(问号前是域名与/接口名)隔开,多个参数之间以&符号拼接

        url = [NSURLURLWithString:[selfurlConversionFromOriginalURL:urlString]];

    }


    //2. 创建请求对象内部默认了已经包含了请求头和请求方法(GET)的对象

      NSMutableURLRequest *request = [[NSMutableURLRequestalloc] initWithURL:urlcachePolicy:NSURLRequestUseProtocolCachePolicytimeoutInterval:CONTECTTIME];

    

    /*   设置请求头  */

//    [request setValue:@"92b5787ecd17417b718a2aaedc7e6ce8" forHTTPHeaderField:@"apix-key"];

    

    //4. 根据会话对象创建一个task任务(发送请求)

    

    [selfstartNSURLSessionDataTask:requestmaskState:state responType:backDatasuccess:successBlock headfiles:requestHeadBlock fail:faileBlock];

    

}





#pragma MARK-- POST


-(void)post:(NSString *)urlString bodyparam:(NSDictionary *)param maskState:(WsqflyNetSessionMaskState)state backData:(WsqflyNetSessionResponseType)backData success:(SuccessBlock)successBlock requestHead:(RequestHeadBlock)requestHeadBlock faile:(FaileBlock)faileBlock{

    

    //POST请求需要修改请求方法为POST,并把参数转换为二进制数据设置为请求体

    

  

    

    //1.url

    NSURL *url = [NSURLURLWithString:[selfurlConversionFromOriginalURL:urlString]];

    

    //2.创建可变的请求对象

    NSMutableURLRequest *request = [[NSMutableURLRequestalloc] initWithURL:urlcachePolicy:NSURLRequestUseProtocolCachePolicytimeoutInterval:CONTECTTIME];


    /*   设置请求头  */

    //    [request setValue:@"92b5787ecd17417b718a2aaedc7e6ce8" forHTTPHeaderField:@"apix-key"];

    

    

    

    //4.修改请求方法为POST

    request.HTTPMethod =@"POST";

    

    

    //有参数请求题

    if (param) {

        

        //5.设置请求体

        NSString *string = [selfnsdictionaryToNSStting:param];

        request.HTTPBody = [stringdataUsingEncoding:NSUTF8StringEncoding];

    }

    

    

    //6.根据会话对象创建一个Task(发送请求)

    [selfstartNSURLSessionDataTask:requestmaskState:state responType:backDatasuccess:successBlock headfiles:requestHeadBlock fail:faileBlock];

}





#pragma MARK-- 根据会话对象创建一个Task(发送请求)


- (void)startNSURLSessionDataTask:(NSMutableURLRequest *)request  maskState:(WsqflyNetSessionMaskState)state responType:(WsqflyNetSessionResponseType)responType success:(SuccessBlock)respone headfiles:(RequestHeadBlock)headfiles fail:(FaileBlock)fail{

    

    

    

    //3.创建会话对象

    NSURLSession *session = [NSURLSessionsharedSession];

    

    /*

     第一个参数:请求对象

     第二个参数:completionHandler回调(请求完成【成功|失败】的回调)

     data:响应体信息(期望的数据)

     response:响应头信息,主要是对服务器端的描述

     error:错误信息,如果请求失败,则error有值

     */

    NSURLSessionDataTask *dataTask = [sessiondataTaskWithRequest:requestcompletionHandler:^(NSData *_Nullable data, NSURLResponse *_Nullable response, NSError * _Nullable error) {

        

        [selfstopAnimation:state];

        

        NSString *result = [[NSStringalloc] initWithData:data encoding:NSUTF8StringEncoding];

        NSLog(@"result:%@",result);

        

        // 解析服务器返回的数据(返回的数据为JSON格式,因此使用NSJNOSerialization进行反序列化)

        id dict = [NSJSONSerializationJSONObjectWithData:data options:NSJSONReadingMutableLeaveserror:nil];

        

        NSLog(@"response%@",response);

        NSHTTPURLResponse * da =(NSHTTPURLResponse *)response;

        NSDictionary *allheadsFiles = da.allHeaderFields;

        NSLog(@"allheadsFiles:%@",allheadsFiles[@"Content-Type"]);

        

        //8.解析数据

        if (!error) {

            if (responType ==WsqflyNetSessionResponseTypeJSON) {//返回JSON

                respone(dict);

            }else{

                   respone(data);//返回二进制

            }

            

            

        }else{

            fail(error);

            NSLog(@"网络请求失败");

        }

        

        if (response) {

            headfiles(allheadsFiles);

        }

        

    }];

    

    //7.执行任务

    [selfshowAnimation:state];

    [dataTask resume];

}





#pragma MARK -- 菊花

// 添加菊花

- (void)showAnimation:(WsqflyNetSessionMaskState)maskType {

    if (maskType !=WsqflyNetSessionMaskStateNone) {  // 有菊花动画

        dispatch_async(dispatch_get_main_queue(), ^{

            [UIApplicationsharedApplication].networkActivityIndicatorVisible =true;

            [[UIApplicationsharedApplication].keyWindowaddSubview:_wsqAView];

            _wsqAView.hidden =NO;

            [_wsqAViewstartAnimating];

            _wsqAView.userInteractionEnabled = (maskType ==WsqflyNetSessionMaskStateNotTouch ?YES : NO);

            _maskCount++;

        });

    }

}

// 移除菊花

- (void)stopAnimation:(WsqflyNetSessionMaskState)maskType {

    if (maskType !=WsqflyNetSessionMaskStateNone) {

        dispatch_async(dispatch_get_main_queue(), ^{

            _maskCount--;

            if (_maskCount <=0) {

                [UIApplicationsharedApplication].networkActivityIndicatorVisible =false;

                [_wsqAViewstopAnimating];

                _wsqAView.hidden =YES;

                [_wsqAViewremoveFromSuperview];

            }

        });

    }

}




#pragma MARK -- 把字典拼成字符串


- (NSString *) nsdictionaryToNSStting:(NSDictionary *)param{

    

    NSMutableString *string = [NSMutableStringstring];

    

    //便利字典把键值平起来

    [param enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull obj, BOOL *_Nonnull stop) {

        [string appendFormat:@"%@:",key];

        [string appendFormat:@"%@",obj];

        [string appendFormat:@"%@",@"&"];

    }];

    // 去掉最后一个&

    NSRange rangeLast = [stringrangeOfString:@"&"options:NSBackwardsSearch];

    if (rangeLast.length !=0) {

        [string deleteCharactersInRange:rangeLast];

    }

    NSLog(@"string:%@",string);

    NSRange range =NSMakeRange(0, [stringlength]);

    [string replaceOccurrencesOfString:@":"withString:@"="options:NSCaseInsensitiveSearchrange:range];

    NSLog(@"string:%@",string);

    

    return string;

}



// 如果URL有中文,转换成百分号

- (NSString *)urlConversionFromOriginalURL:(NSString *)originalURL {

    

    if ([[UIDevicecurrentDevice].systemVersionfloatValue] < 9.0) {

        return [originalURLstringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];// iOS 9.0以下

    }

    return [originalURLstringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSetURLQueryAllowedCharacterSet]];

}




#pragma mark NSURLSession Delegate

/* 收到身份验证 ssl */

- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition,NSURLCredential * _Nullable))completionHandler {

    

    NSLog(@"didReceiveChallenge %@", challenge.protectionSpace);

    NSLog(@"调用了最外层");

    // 1.判断服务器返回的证书类型,是否是服务器信任

    if ([challenge.protectionSpace.authenticationMethodisEqualToString:NSURLAuthenticationMethodServerTrust]) {       NSLog(@"调用了里面这一层是服务器信任的证书");

        /*  NSURLSessionAuthChallengeUseCredential = 0,                    使用证书         NSURLSessionAuthChallengePerformDefaultHandling = 1,           忽略证书(默认的处理方式)         NSURLSessionAuthChallengeCancelAuthenticationChallenge = 2,     忽略书证,并取消这次请求         NSURLSessionAuthChallengeRejectProtectionSpace = 3,           拒绝当前这一次,下一次再询问   

         */

        

        NSURLCredential *card = [[NSURLCredentialalloc]initWithTrust:challenge.protectionSpace.serverTrust];

        completionHandler(NSURLSessionAuthChallengeUseCredential , card);

        

    }

   

}





@end



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章