@interface BJAppClient : AFHTTPSessionManager
+ (instancetype)sharedClient;
@end
static NSString * const APIBaseURLString = @"xxxxx";
@implementation BJAppClient
+ (instancetype)sharedClient
{
static BJAppClient *_sharedClient = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_sharedClient = [[BJAppClient alloc] initWithBaseURL:[NSURL URLWithString:APIBaseURLString]];
});
return _sharedClient;
}
#pragma mark - 重写initWithBaseURL
/**
*
*
* @param url baseUrl
*
* @return 通过重写夫类的initWithBaseURL方法,返回网络请求类的实例
*/
-(instancetype)initWithBaseURL:(NSURL *)url
{
if (self = [super initWithBaseURL:url]) {
/**设置请求超时时间*/
self.requestSerializer.timeoutInterval = 3;
/**设置相应的缓存策略*/
self.requestSerializer.cachePolicy = NSURLRequestReloadIgnoringLocalCacheData;
/**分别设置请求以及相应的序列化器*/
self.requestSerializer = [AFHTTPRequestSerializer serializer];
AFJSONResponseSerializer * response = [AFJSONResponseSerializer serializer];
response.removesKeysWithNullValues = YES;
self.responseSerializer = response;
/**复杂的参数类型 需要使用json传值-设置请求内容的类型*/
[self.requestSerializer setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
/**设置接受的类型*/
[self.responseSerializer setAcceptableContentTypes:[NSSet setWithObjects:@"text/plain",@"application/json",@"text/json",@"text/javascript",@"text/html", nil]];
}
return self;
}
typedef NS_ENUM(NSUInteger,HTTPSRequestType)
{
HTTPSRequestTypeGet = 0,
HTTPSRequestTypePost
};
typedef void(^completeBlock)( NSDictionary *_Nullable object,NSError * _Nullable error);
@interface BJHTTPSession : NSObject
+ (nullable NSURLSessionDataTask *)GET:(nonnull NSString *)urlString
paraments:(nullable id)paraments
completeBlock:(nullable completeBlock)completeBlock;
+ (nullable NSURLSessionDataTask *)POST:(nonnull NSString *)urlString
paraments:(nullable id)paraments
completeBlock:(nullable completeBlock)completeBlock;
+ (nullable NSURLSessionDataTask *)requestWithRequestType:(HTTPSRequestType)type
urlString:(nonnull NSString *)urlString
paraments:(nullable id)paraments
completeBlock:(nullable completeBlock)completeBlock;
- (void)AFNetworkStatus;
@end
//
// BJHTTPSession.m
// VRMax
//
// Created by VRGATE on 16/5/12.
// Copyright © 2016年 AngieMita. All rights reserved.
//
#import "BJHTTPSession.h"
#import "BJAppClient.h"
#import <AVFoundation/AVAsset.h>
#import <AVFoundation/AVAssetExportSession.h>
#import <AVFoundation/AVMediaFormat.h>
#import "UIImage+compressIMG.h"
@implementation BJHTTPSession
+ (nullable NSURLSessionDataTask *)GET:(nonnull NSString *)urlString
paraments:(nullable id)paraments
completeBlock:(nullable completeBlock)completeBlock
{
return [[BJAppClient sharedClient] GET:urlString
parameters:paraments
progress:^(NSProgress * _Nonnull downloadProgress) {
} success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
completeBlock(responseObject,nil);
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
completeBlock(nil,error);
}];
}
+ (nullable NSURLSessionDataTask *)POST:(nonnull NSString *)urlString
paraments:(nullable id)paraments
completeBlock:(nullable completeBlock)completeBlock
{
// 不加上这句话,会报“Request failed: unacceptable content-type: text/plain”错误
[BJAppClient sharedClient].requestSerializer = [AFJSONRequestSerializer serializer];//请求
[BJAppClient sharedClient].responseSerializer = [AFHTTPResponseSerializer serializer];//响应
// post请求
return [[BJAppClient sharedClient] POST:urlString
parameters:paraments
constructingBodyWithBlock:^(id<AFMultipartFormData> _Nonnull formData) {
// 拼接data到请求体,这个block的参数是遵守AFMultipartFormData协议的。
} progress:^(NSProgress * _Nonnull uploadProgress){
} success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
NSLog(@"%@", responseObject);
NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:responseObject options:NSJSONReadingMutableContainers error:nil];
NSLog(@"dict start ----\n%@ \n ---- end -- ", dict);
// 请求成功,解析数据
completeBlock(responseObject,nil);
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
NSLog(@"%@", [error localizedDescription]);
// 请求失败
completeBlock(nil,error);
}];
}
#pragma mark - 简化
+ (nullable NSURLSessionDataTask *)requestWithRequestType:(HTTPSRequestType)type
urlString:(nonnull NSString *)urlString
paraments:(nullable id)paraments
completeBlock:(nullable completeBlock)completeBlock
{
switch (type) {
case HTTPSRequestTypeGet:
{
return [BJHTTPSession GET:urlString
paraments:paraments
completeBlock:^(NSDictionary * _Nullable object, NSError * _Nullable error) {
completeBlock(object,error);
}];
}
case HTTPSRequestTypePost:
return [BJHTTPSession POST:urlString
paraments:paraments
completeBlock:^(NSDictionary * _Nullable object, NSError * _Nullable error) {
completeBlock(object,error);
}];
}
}
#pragma mark - 取消所有的网络请求
/**
* 取消所有的网络请求
* a finished (or canceled) operation is still given a chance to execute its completion block before it iremoved from the queue.
*/
+(void)cancelAllRequest
{
[[BJAppClient sharedClient].operationQueue cancelAllOperations];
}
#pragma mark - 取消指定的url请求/
/**
* 取消指定的url请求
*
* @param requestType 该请求的请求类型
* @param string 该请求的完整url
*/
+(void)cancelHttpRequestWithRequestType:(NSString *)requestType
requestUrlString:(NSString *)string
{
NSError * error;
/**根据请求的类型 以及 请求的url创建一个NSMutableURLRequest---通过该url去匹配请求队列中是否有该url,如果有的话 那么就取消该请求*/
NSString * urlToPeCanced = [[[[BJAppClient sharedClient].requestSerializer
requestWithMethod:requestType URLString:string parameters:nil error:&error] URL] path];
for (NSOperation * operation in [BJAppClient sharedClient].operationQueue.operations) {
//如果是请求队列
if ([operation isKindOfClass:[NSURLSessionTask class]]) {
//请求的类型匹配
BOOL hasMatchRequestType = [requestType isEqualToString:[[(NSURLSessionTask *)operation currentRequest] HTTPMethod]];
//请求的url匹配
BOOL hasMatchRequestUrlString = [urlToPeCanced isEqualToString:[[[(NSURLSessionTask *)operation currentRequest] URL] path]];
//两项都匹配的话 取消该请求
if (hasMatchRequestType&&hasMatchRequestUrlString) {
[operation cancel];
}
}
}
}
- (void)AFNetworkStatus
{
//1.创建网络监测者
AFNetworkReachabilityManager *manager = [AFNetworkReachabilityManager sharedManager];
/*枚举里面四个状态 分别对应 未知 无网络 数据 WiFi
typedef NS_ENUM(NSInteger, AFNetworkReachabilityStatus) {
AFNetworkReachabilityStatusUnknown = -1, 未知
AFNetworkReachabilityStatusNotReachable = 0, 无网络
AFNetworkReachabilityStatusReachableViaWWAN = 1, 蜂窝数据网络
AFNetworkReachabilityStatusReachableViaWiFi = 2, WiFi
};
*/
[manager setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {
//这里是监测到网络改变的block 可以写成switch方便
//在里面可以随便写事件
switch (status) {
case AFNetworkReachabilityStatusUnknown:
NSLog(@"未知网络状态");
break;
case AFNetworkReachabilityStatusNotReachable:
NSLog(@"无网络");
networkReachabilityStatusUnknown();
break;
case AFNetworkReachabilityStatusReachableViaWWAN:
NSLog(@"蜂窝数据网");
networkReachabilityStatusReachableViaWWAN();
break;
case AFNetworkReachabilityStatusReachableViaWiFi:
NSLog(@"WiFi网络");
break;
default:
break;
}
}] ;
}
void networkReachabilityStatusUnknown()
{
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"已为”VRMAX“关闭蜂窝移动数据"
message:@"您可以在”设置“中为此应用程序打开蜂窝移动数据。"
preferredStyle:UIAlertControllerStyleAlert];
[alert addAction:[UIAlertAction actionWithTitle:@"设置"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * _Nonnull action) {
canOpenURLString(@"prefs:root=MOBILE_DATA_SETTINGS_ID");
}]];
[alert addAction:[UIAlertAction actionWithTitle:@"好"
style:UIAlertActionStyleCancel handler:nil]];
}
void networkReachabilityStatusReachableViaWWAN()
{
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"“VRMAX”正在使用流量,确定要如此土豪吗?"
message:@"建议开启WIFI后观看视频。"
preferredStyle:UIAlertControllerStyleAlert];
[alert addAction:[UIAlertAction actionWithTitle:@"设置"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * _Nonnull action) {
canOpenURLString(@"prefs:root=MOBILE_DATA_SETTINGS_ID");
}]];
[alert addAction:[UIAlertAction actionWithTitle:@"好"
style:UIAlertActionStyleCancel handler:nil]];
}
@end