AFNetworking二次封装

使用AFNetworking实现网络请求,同时集成YYCache实现缓存策略。

网络请求类WMNetwork.h

#import 

typedef NS_ENUM(NSUInteger, WMClientRequestCachePolicy){
	WMClientReturnCacheDataThenLoad = 0,///< 有缓存就先返回缓存,同步请求数据
	WMClientReloadIgnoringLocalCacheData, ///< 忽略缓存,重新请求
	WMClientReturnCacheDataElseLoad,///< 有缓存就用缓存,没有缓存就重新请求(用于数据不变时)
	WMClientReturnCacheDataDontLoad,///< 有缓存就用缓存,没有缓存就不发请求,当做请求出错处理(用于离线模式)
};

typedef NS_ENUM(NSInteger,NetworkRequestType) {
	NetworkGetType,
	NetworkPostType
};

/* 请求数据Block */
typedef void (^WMBlock)(id responseObject,NSError *error);

/*刷新token*/
typedef void (^WMTokenBool)(BOOL ors);
@interface WMNetwork : NSObject

@property (nonatomic, assign) BOOL result;//是否需要重新请求数据
@property(nonatomic,copy)NSString *videoUploadProgress;//上传进度

###1.普通请求
- (void)requsetWithUrl:(NSString *)url withParams:(NSDictionary *)params withCacheType:(WMClientRequestCachePolicy)cacheType withRequestType:(NetworkRequestType)type withResult:(WMBlock)resultBlock;

###2.带访问权限的http请求 (Authorization)
- (void)requsetWithUrl:(NSString *)url withToken:(NSString *)headerstr withParams:(NSDictionary *)params withCacheType:(WMClientRequestCachePolicy)cacheType withRequestType:(NetworkRequestType)type withResult:(WMBlock)resultBlock;

//获取网络缓存的总大小 bytes(字节)
+ (NSInteger)getAllHttpCacheSize;

//刷新token
-(void)refreshTokens:(WMTokenBool)tokenbool;

//删除所有网络缓存
+ (void)removeAllHttpCache;

//上传头像
-(void)uploadPicturesWithUrl:(NSString*)url withToken:(NSString *)token withImage:(UIImage*)image withResult:(WMBlock)resultBlock;

//上传视频
- (void)uploadVideoWithUrl:(NSString *)url withToken:(NSString *)token withVideoData:(NSData *)videoData withVideoName:(NSString *)videoName withResult:(WMBlock)resultBlock;

@end

网络请求类WMNetwork.m

#import "WMNetwork.h"
#import "JSONKit.h"
#import "WMNetWorkCache.h"
@interface WMNetwork ()

@end

@implementation WMNetwork
#pragma mark- AFHTTPSessionManager单利
- (AFHTTPSessionManager *)managers{
	static AFHTTPSessionManager *rmanager = nil;
	static dispatch_once_t onceToken;
	dispatch_once(&onceToken, ^{
    	rmanager = [AFHTTPSessionManager manager];
    	NSString *userAgent = nil;
    	userAgent = [NSString stringWithFormat:@"XXXX/%@ (%@; %@; Apple; %@)",[[NSBundle mainBundle] infoDictionary][@"CFBundleShortVersionString"] ?: [[NSBundle mainBundle] infoDictionary][(__bridge NSString *)kCFBundleVersionKey], [[UIDevice currentDevice] model], [[UIDevice currentDevice] systemVersion],[Platform iphoneType]];//[Platform iphoneType]判断手机类型

    	//设置自定义代理参数
    	NSString *language = [self getPreferredLanguage];
    	[rmanager.requestSerializer setValue:language forHTTPHeaderField:@"XXXXLanguage"];
       	[rmanager.requestSerializer setValue:userAgent forHTTPHeaderField:@"User-Agent"];
    	rmanager.responseSerializer = [AFJSONResponseSerializer serializer];
    	rmanager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json", @"text/json", @"text/javascript",@"text/html",@"text/plain",@"image/jpg",nil];

    	// https  参数配置
    	AFSecurityPolicy *securityPolicy = [AFSecurityPolicy defaultPolicy];
    	securityPolicy.allowInvalidCertificates = YES;
    	securityPolicy.validatesDomainName = NO;
    	rmanager.securityPolicy = securityPolicy;

    	// 设置超时时间
    	[rmanager.requestSerializer willChangeValueForKey:@"timeoutInterval"];
    	rmanager.requestSerializer.timeoutInterval = 60.f;
    	[rmanager.requestSerializer didChangeValueForKey:@"timeoutInterval"];
    	//AF自动处理返回null对象的异常
    	AFJSONResponseSerializer *response = (AFJSONResponseSerializer *)rmanager.responseSerializer;
    	response.removesKeysWithNullValues = YES;       
	});
	return rmanager;
}

- (NSString*)getPreferredLanguage {
	NSUserDefaults * defaults = [NSUserDefaults standardUserDefaults];
	NSArray * allLanguages = [defaults objectForKey:@"AppleLanguages"];
	NSString * preferredLang = [allLanguages objectAtIndex:0];
	return preferredLang;
}

###2.带访问权限的http请求 (Authorization)
- (void)requsetWithUrl:(NSString *)url withToken:(NSString *)headerstr withParams:(NSDictionary *)params withCacheType:(WMClientRequestCachePolicy)cacheType withRequestType:(NetworkRequestType)type withResult:(WMBlock)resultBlock{
	[[self managers].requestSerializer setValue:headerstr forHTTPHeaderField:@"Authorization"];
	[self requsetWithUrl:url withParams:params withCacheType:cacheType withRequestType:type withResult:resultBlock];
}

###1.普通请求
- (void)requsetWithUrl:(NSString *)url withParams:(NSDictionary *)params withCacheType:(WMClientRequestCachePolicy)cacheType withRequestType:(NetworkRequestType)type withResult:(WMBlock)resultBlock {
	switch (type) {
    	case NetworkGetType:
    	{
        	// 响应缓存数据
        	[self getCache:cacheType url:url params:params withResult:resultBlock];
        	if (self.result) {
            	return;
        	}
        	[[self managers] GET:url parameters:nil progress:^(NSProgress * _Nonnull downloadProgress) {
            
        	} success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
            	if (responseObject) {
                [WMNetWorkCache setHttpCache:responseObject URL:url parameters:params];
            	}
            	[self handleRequestResultWithDataTask:task responseObject:responseObject error:nil resultBlock:resultBlock];
        	} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
            [self handleRequestResultWithDataTask:task responseObject:nil error:error resultBlock:resultBlock];
        	}];  
    	}
        	break;
    	case NetworkPostType:
    	{
        	// 响应缓存数据
         	[self getCache:cacheType url:url params:params withResult:resultBlock];
        	if (self.result) {
            	return;
        	}
        	[[self managers] POST:url parameters:params progress:^(NSProgress * _Nonnull uploadProgress) {
            
        	} success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
            	if (responseObject) {
                	//对数据进行异步缓存
                	[WMNetWorkCache setHttpCache:responseObject URL:url parameters:params];
            	}
            	[self handleRequestResultWithDataTask:task responseObject:responseObject error:nil resultBlock:resultBlock];
        	} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
            	[self handleRequestResultWithDataTask:task responseObject:nil error:error resultBlock:resultBlock];
        	}];
    	}
        	break;
    	default:
        	break;
	} 
}

// 响应缓存
- (void)getCache:(WMClientRequestCachePolicy)cacheType url:(NSString *)url params:(NSDictionary *)params withResult:(WMBlock)resultBlock {
	id object = [WMNetWorkCache httpCacheForURL:url parameters:params];
	if (object) {
    	if (cacheType == WMClientReloadIgnoringLocalCacheData) {//忽略缓存,重新请求
        	self.result = NO;
    	} else if (cacheType == WMClientReturnCacheDataDontLoad) {//有缓存就用缓存,没有缓存就不发请求,当做请求出错处理(用于离线模式)
        	if (object) {
            	resultBlock(object,nil);
        	}
        	self.result = YES;
    	} else if (cacheType == WMClientReturnCacheDataElseLoad) {//有缓存就用缓存,没有缓存就重新请求(用于数据不变时)
        	if (object) {
            	resultBlock(object,nil);
        	}
        	self.result = YES;
        
    	} else if (cacheType == WMClientReturnCacheDataThenLoad) {///有缓存就先返回缓存,同步请求数据
        	if (object) {
            	resultBlock(object,nil);
        	}
        	self.result = NO;
    	}
	}    
}

// 数据回调
- (void)handleRequestResultWithDataTask:(NSURLSessionDataTask *)task responseObject:(id)responseObject error:(NSError *)error resultBlock:(WMBlock)resultBlock {
	if(resultBlock) {
    	resultBlock(responseObject,error);
	}
}

//获取网络缓存的总大小 bytes(字节)
+ (NSInteger)getAllHttpCacheSize{
	return [WMNetWorkCache getAllHttpCacheSize];
}

//删除所有网络缓存,
+ (void)removeAllHttpCache{
	[WMNetWorkCache removeAllHttpCache];
}

//上传视屏
- (void)uploadVideoWithUrl:(NSString *)url withToken:(NSString *)token withVideoData:(NSData *)videoData withVideoName:(NSString *)videoName withResult:(WMBlock)resultBlock {
	[[self managers].requestSerializer setValue:token forHTTPHeaderField:@"Authorization"];
	[[self managers] POST:url parameters:nil constructingBodyWithBlock:^(id  _Nonnull formData) {
    	[formData appendPartWithFileData:videoData name:@"file" fileName:videoName mimeType:@"video/mp4"];
	} progress:^(NSProgress * _Nonnull uploadProgress) {
    	self.videoUploadProgress = [NSString stringWithFormat:@"%.2f",1.0*uploadProgress.completedUnitCount/uploadProgress.totalUnitCount];
	} success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
    	[self handleRequestResultWithDataTask:task responseObject:responseObject error:nil resultBlock:resultBlock];
	} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
    	[self handleRequestResultWithDataTask:task responseObject:nil error:error resultBlock:resultBlock];
	}];
}
//上传图片
-(void)uploadPicturesWithUrl:(NSString*)url withToken:(NSString *)token withImage:(UIImage*)image withResult:(WMBlock)resultBlock{
	[[self managers].requestSerializer setValue:token forHTTPHeaderField:@"Authorization"];
	[[self managers] POST:url parameters:nil constructingBodyWithBlock:^(id  _Nonnull formData) {        
    	NSData *imageData = [self imageWithImage:image];
    	NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    	formatter.dateFormat = @"yyyy-MM-dd HH:mm:ss";
    	NSString *fileName = [NSString stringWithFormat:@"%@.png",[formatter stringFromDate:[NSDate date]]];
    	[formData appendPartWithFileData:imageData name:@"file" fileName:fileName mimeType:@"image/png"];
	} progress:^(NSProgress * _Nonnull uploadProgress) {

	} success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
      	[self handleRequestResultWithDataTask:task responseObject:responseObject error:nil resultBlock:resultBlock];
	} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        [self handleRequestResultWithDataTask:task responseObject:nil error:error resultBlock:resultBlock];
	}];
}

//图片压缩
- (NSData *)imageWithImage:(UIImage*)newImage{
	NSData *data=UIImageJPEGRepresentation(newImage, 1.0);
	if (data.length>100*1024) {
    	if (data.length>1024*1024) {//1M以及以上
        	data=UIImageJPEGRepresentation(newImage, 0.1);
    	} else if (data.length>512*1024) {//0.5M-1M
        	data=UIImageJPEGRepresentation(newImage, 0.5);
    	} else if (data.length>200*1024) {//0.25M-0.5M
        	data=UIImageJPEGRepresentation(newImage, 0.9);
    	}
	}
	return data;
}

//刷新token
- (void)refreshTokens:(WMTokenBool)tokenbool {
	NSString *tokens = [[NSUserDefaults standardUserDefaults] objectForKey:saveCompleteToken];
	NSString *idfv = [[UIDevice currentDevice].identifierForVendor UUIDString];
	NSString *islogin= [[[NSUserDefaults standardUserDefaults] objectForKey:saveUserData] objectForKey:@"id"];
	NSString *urls = [NSString stringWithFormat:@"刷新token的url请求?device_uuid=%@&is_login=%@",idfv,islogin];
	[self requsetWithUrl:urls withToken:tokens withParams:nil withCacheType:WMClientReloadIgnoringLocalCacheData withRequestType:NetworkGetType withResult:^(id responseObject, NSError *error) {
    	if (!error) { 
        	if ([[responseObject objectForKey:@"code"] integerValue]==0) {
            	[[NSUserDefaults standardUserDefaults] setObject:OCSTR(@"Bearer %@",[[responseObject objectForKey:@"data"] objectForKey:@"refreshToken"]) forKey:saveCompleteToken];
            	tokenbool(YES);
        	} else {
        	tokenbool(NO);
        	}
    	} else {
        	tokenbool(NO);   
    	}   
	}];   
}
@end

缓存处理类(WMNetWorkCache.h)

#import 

@interface WMNetWorkCache : NSObject

/**
*  缓存网络数据,根据请求的 URL与parameters
*  做KEY存储数据, 这样就能缓存多级页面的数据
*
*  @param httpData   服务器返回的数据
*  @param URL        请求URL地址
*  @param parameters 请求参数
*/
+ (void)setHttpCache:(id)httpData URL:(NSString *)URL parameters:(NSDictionary *)parameters;

/**
*  根据请求的 URL与parameters 取出缓存数据
*
*  @param URL        请求的URL
*  @param parameters 请求的参数
*
*  @return 缓存的服务器数据
*/
+ (id)httpCacheForURL:(NSString *)URL parameters:(NSDictionary *)parameters;


/**
*  获取网络缓存的总大小 bytes(字节)
*/
+ (NSInteger)getAllHttpCacheSize;


/**
*  删除所有网络缓存,
*/
+ (void)removeAllHttpCache;

@end

缓存处理类(WMNetWorkCache.m)

#import "WMNetWorkCache.h"
#import "YYCache.h"

@implementation WMNetWorkCache

static NSString *const NetworkResponseCache = @"NetworkResponseCache";
static YYCache *_dataCache;

+ (void)initialize {
	_dataCache = [YYCache cacheWithName:NetworkResponseCache];
}

+ (void)setHttpCache:(id)httpData URL:(NSString *)URL parameters:(NSDictionary *)parameters {
	NSString *cacheKey = [self cacheKeyWithURL:URL parameters:parameters];
	//异步缓存,不会阻塞主线程
	[_dataCache setObject:httpData forKey:cacheKey withBlock:nil];
}

+ (id)httpCacheForURL:(NSString *)URL parameters:(NSDictionary *)parameters {
	NSString *cacheKey = [self cacheKeyWithURL:URL parameters:parameters];
	return [_dataCache objectForKey:cacheKey];
}

+ (NSInteger)getAllHttpCacheSize {
	return [_dataCache.diskCache totalCost];
}

+ (void)removeAllHttpCache {
	[_dataCache.diskCache removeAllObjects];
}

+ (NSString *)cacheKeyWithURL:(NSString *)URL parameters:(NSDictionary *)parameters {
	if(!parameters) {
   		return URL;
	};
	// 将参数字典转换成字符串
	NSData *stringData = [NSJSONSerialization dataWithJSONObject:parameters options:0 error:nil];
	NSString *paraString = [[NSString alloc] initWithData:stringData encoding:NSUTF8StringEncoding];
	// 将URL与转换好的参数字符串拼接在一起,成为最终存储的KEY值
	NSString *cacheKey = [NSString stringWithFormat:@"%@%@",URL,paraString];
	return cacheKey;
}
@end

你可能感兴趣的:(iOS开发)