//
// WSQNetWorkingSystem
//
// Created by webapps on 16/12/28.
// Copyright © 2016年 webapps. All rights reserved.
#import <Foundation/>
#import <UIKit/>
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;
//
//
// WSQNetWorkingSystem
//
// Created by webapps on 16/12/28.
// Copyright © 2016年 webapps. All rights reserved.
//
#import ""
#import ""
#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,并把参数转换为二进制数据设置为请求体
//
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