190
技術社區[雲棲]
網絡請求封裝
//
// ASIHTTPRequest+Request.h
// CloudShopping
//
// Created by sixiaobo on 14-7-9.
// Copyright (c) 2014年 com.Uni2uni. All rights reserved.
//
#import "ASIFormDataRequest.h"
#import "ASIDownloadCache.h"
// downloadData是返回的數據,如果出錯,會把錯誤放到error中,否則error為nil,可通過error參數
// 判斷是否出錯
typedef void(^HYBResultBlock)(NSData *downloadData, NSError *error);
//
// HYBRequestType枚舉用於指定請求類型
typedef NS_ENUM(NSUInteger, HYBRequestType) {
kTypePost = 1 << 1, // POST請求
kTypeGet = 1 << 2 // GET請求
};
@interface HYBHttpRequest : ASIFormDataRequest
// 請求回調block,成功或者失敗都會回調此block,通過error參數判斷是否成功
@property (nonatomic, copy) HYBResultBlock resultBlock;
@property (nonatomic, strong) NSMutableData *downloadData; // 下載完成後的數據
@property (nonatomic, assign) HYBRequestType requestType;
////////////////////////
// 異步請求方式
////////////////////////
/*!
* @brief 默認使用POST請求方式
* @param path 網絡請求前綴參數
* @param params 使用字典存儲,會在內部拚接到請求網址中
* @param completion 完成時的回調block
* @return 返回HYBHttpRequest對象
*/
- (id)initWithPath:(NSString *)path
params:(NSDictionary *)params
completion:(HYBResultBlock)completion;
- (id)initWithPath:(NSString *)path
params:(NSDictionary *)params
completion:(HYBResultBlock)completion
isCache:(BOOL)isCache // 是否緩存,POST請求默認是NO
isRefresh:(BOOL)isRefresh; // 是否刷新緩存
- (id)initWithPath:(NSString *)path
params:(NSDictionary *)params
requestType:(HYBRequestType)requestType
completion:(HYBResultBlock)completion;
- (id)initWithPath:(NSString *)path
params:(NSDictionary *)params
requestType:(HYBRequestType)requestType
completion:(HYBResultBlock)completion
isCache:(BOOL)isCache // 是否緩存,POST請求默認是NO;
isRefresh:(BOOL)isRefresh; // 是否刷新緩存
- (id)initWithPath:(NSString *)path
requestType:(HYBRequestType)requestType
completion:(HYBResultBlock)completion;
- (id)initWithPath:(NSString *)path
requestType:(HYBRequestType)requestType
completion:(HYBResultBlock)completion
isCache:(BOOL)isCache // 是否緩存,POST請求默認是NO;
isRefresh:(BOOL)isRefresh; // 是否刷新緩存
// 必須是POST請求,請求參數要轉換成JSON格式數據
- (id)initWithPath:(NSString *)path
postBody:(NSMutableData *)postBodyJSONData
completion:(HYBResultBlock)completion;
// 必須是POST請求,請求參數要轉換成JSON格式數據
- (id)initWithPath:(NSString *)path
postBody:(NSMutableData *)postBodyJSONData
completion:(HYBResultBlock)completion
isCache:(BOOL)isCache // 是否緩存,POST請求默認是NO;
isRefresh:(BOOL)isRefresh; // 是否刷新緩存
// 取消請求
- (void)cancelRequest;
@end
//
// ASIHTTPRequest+Request.m
// CloudShopping
//
// Created by sixiaobo on 14-7-9.
// Copyright (c) 2014年 com.Uni2uni. All rights reserved.
//
#import "HYBHTTPRequest.h"
#import "ASIFormDataRequest.h"
#import "NSString+Common.h"
#import "HYBHttpRequestManager.h"
#import "NSString+Encrypt.h"
#import "NSFileManager+File.h"
@interface HYBHttpRequest ()
@property (nonatomic, assign) BOOL isCache;
@property (nonatomic, assign) BOOL isRefresh;
@property (nonatomic, copy) NSString *fileName;
@end
@implementation HYBHttpRequest
- (id)initWithPath:(NSString *)path
params:(NSDictionary *)params
requestType:(HYBRequestType)requestType
completion:(HYBResultBlock)completion {
return [self initWithPath:path
params:params
requestType:requestType
completion:completion
isCache:requestType == kTypeGet
isRefresh:NO];
}
- (id)initWithPath:(NSString *)path
params:(NSDictionary *)params
completion:(HYBResultBlock)completion
isCache:(BOOL)isCache // 是否緩存,POST請求默認是NO
isRefresh:(BOOL)isRefresh { // 是否刷新緩存
return [self initWithPath:path
params:params
requestType:kTypePost
completion:completion
isCache:isCache
isRefresh:isRefresh];
}
- (id)initWithPath:(NSString *)path
params:(NSDictionary *)params
requestType:(HYBRequestType)requestType
completion:(HYBResultBlock)completion
isCache:(BOOL)isCache
isRefresh:(BOOL)isRefresh {
if (self = [super initWithURL:[NSURL URLWithString:path]]) {
self.isCache = isCache;
self.delegate = self;
self.resultBlock = [completion copy];
self.downloadData = [[NSMutableData alloc] init];
self.requestType = requestType;
self.fileName = path;
self.isRefresh = isRefresh;
if (self.requestType == kTypeGet) {
[self setRequestMethod:@"GET"];
// 設置永久存儲在本地
} else if (self.requestType == kTypePost) {
[self setRequestMethod:@"POST"];
[self addRequestHeader:@"Content-Type" value:@"application/json"];
if (params) {
self.fileName = [NSString stringWithFormat:@"%@?", self.fileName];
for (NSString *key in params.allKeys) {
[self addPostValue:[params objectForKey:key] forKey:key];
self.fileName = [NSString stringWithFormat:@"%@%@=%@",
self.fileName, key, [params objectForKey:key]];
}
}
}
// 如果是緩存
// 且不刷新緩存
if (self.isRefresh == NO && self.isCache && [[NSFileManager defaultManager] isFileExists:[self cachePath]]) {
if (![[NSFileManager defaultManager] isFile:[self cachePath] timeout:12 * 60 * 60]) {
NSData *data = [[NSData alloc] initWithContentsOfFile:[self cachePath]];
self.downloadData = [data mutableCopy];
if (data.length != 0) {
self.resultBlock(data, nil);
return self;
}
}
}
[[HYBHttpRequestManager sharedRequestManager] addRequest:self
withKey:self.fileName.md5];
[self startAsynchronous];
}
return self;
}
- (id)initWithPath:(NSString *)path params:(NSDictionary *)params completion:(HYBResultBlock)completion {
return [self initWithPath:path params:params requestType:kTypePost completion:completion];
}
- (id)initWithPath:(NSString *)path
completion:(HYBResultBlock)completion {
return [self initWithPath:path params:nil completion:completion];
}
- (id)initWithPath:(NSString *)path
requestType:(HYBRequestType)requestType
completion:(HYBResultBlock)completion {
return [self initWithPath:path
params:nil
requestType:requestType
completion:completion
isCache:requestType == kTypeGet
isRefresh:NO];
}
- (id)initWithPath:(NSString *)path
requestType:(HYBRequestType)requestType
completion:(HYBResultBlock)completion
isCache:(BOOL)isCache // 是否緩存,POST請求默認是NO;
isRefresh:(BOOL)isRefresh { // 是否刷新緩存
return [self initWithPath:path
params:nil
requestType:requestType
completion:completion
isCache:isCache
isRefresh:isRefresh];
}
// 必須是POST請求,請求參數要轉換成JSON格式數據
- (id)initWithPath:(NSString *)path
postBody:(NSMutableData *)postBodyJSONData
completion:(HYBResultBlock)completion {
return [self initWithPath:path
postBody:postBodyJSONData
completion:completion
isCache:NO
isRefresh:YES];
}
- (id)initWithPath:(NSString *)path
postBody:(NSMutableData *)postBodyJSONData
completion:(HYBResultBlock)completion
isCache:(BOOL)isCache // 是否緩存,POST請求默認是NO;
isRefresh:(BOOL)isRefresh { // 是否刷新緩存
if (self = [super initWithURL:[NSURL URLWithString:path]]) {
self.delegate = self;
self.resultBlock = [completion copy];
self.downloadData = [[NSMutableData alloc] init];
self.requestType = kTypePost;
self.isCache = isCache;
self.isRefresh = isRefresh;
self.fileName = path;
if (postBodyJSONData.length != 0) {
NSString *str = [[NSString alloc] initWithData:postBodyJSONData
encoding:NSUTF8StringEncoding];
self.fileName = [NSString stringWithFormat:@"%@%@", self.fileName, str];
}
if (self.requestType == kTypePost) {
[self setRequestMethod:@"POST"];
[self addRequestHeader:@"Content-Type" value:@"application/json"];
[self addRequestHeader:@"Accept" value:@"application/json"];
[self setPostBody:postBodyJSONData];
}
// 如果是緩存
// 且不刷新緩存
if (self.isRefresh == NO && self.isCache && [[NSFileManager defaultManager] isFileExists:[self cachePath]]) {
if (![[NSFileManager defaultManager] isFile:[self cachePath] timeout:12 * 60 * 60]) {
NSData *data = [[NSData alloc] initWithContentsOfFile:[self cachePath]];
self.downloadData = [data mutableCopy];
if (data.length != 0) {
self.resultBlock(data, nil);
return self;
}
}
}
[[HYBHttpRequestManager sharedRequestManager] addRequest:self
withKey:self.fileName.md5];
[self startAsynchronous];
}
return self;
}
- (void)cancelRequest {
[self clearDelegatesAndCancel];
return;
}
#pragma mark - ASIHttpRequestDelegate
- (void)request:(ASIHTTPRequest *)request didReceiveResponseHeaders:(NSDictionary *)responseHeaders {
[self.downloadData setLength:0];
return;
}
- (void)requestFinished:(ASIHTTPRequest *)request {
[[HYBHttpRequestManager sharedRequestManager] removeRequestWithKey:self.fileName.md5];
if (self.resultBlock) {
[self.downloadData writeToFile:[self cachePath] atomically:YES];
self.resultBlock(self.downloadData, nil);
}
return;
}
- (void)requestFailed:(ASIHTTPRequest *)request {
[[HYBHttpRequestManager sharedRequestManager] removeRequestWithKey:self.fileName.md5];
if (self.resultBlock) {
[self clearDelegatesAndCancel];
self.resultBlock(self.downloadData, self.error);
}
return;
}
- (void)request:(ASIHTTPRequest *)request didReceiveData:(NSData *)data {
[self.downloadData appendData:data];
return;
}
#pragma mark - 獲取緩存路徑
- (NSString *)cachePath {
return [NSString stringWithFormat:@"%@/%@", [NSString cachePath], self.fileName.md5];
}
@end
// // HYBHttpRequestManager.h // CloudShopping // // Created by sixiaobo on 14-7-9. // Copyright (c) 2014年 com.Uni2uni. All rights reserved. // #import <Foundation/Foundation.h> #import "ASIHTTPRequest.h" #import "ASIDownloadCache.h" /*! * @brief 管理ASIHttpRequest對象的生命周期 * @author huangyibiao */ @interface HYBHttpRequestManager : NSObject @property (nonatomic, strong) ASIDownloadCache *downloadCache; + (HYBHttpRequestManager *)sharedRequestManager; /*! * @brief 添加ASIHttpRequest對象,用過管理其生命周期 * @param request 需要交由HYBHttpRequestManager來管理的請求對象 * @param urlStringKey 使用絕對網址作為key */ - (void)addRequest:(id)request withKey:(NSString *)urlStringKey; /*! * @brief 根據指定的key清除請求對象的代理、取消請求並移除掉HYBHttpReuest對象 * @param urlStringKey 絕對網址 */ - (void)removeRequestWithKey:(NSString *)urlStringKey; /*! * @brief 這裏需要慎重,一旦調用,就會把所有的請求對象都移除掉 */ - (void)removeAllRequest; /*! * @brief 取消所有請求,並且移除 */ - (void)cancelAllRequestAndRemove; @end
//
// HYBHttpRequestManager.m
// CloudShopping
//
// Created by sixiaobo on 14-7-9.
// Copyright (c) 2014年 com.Uni2uni. All rights reserved.
//
#import "HYBHttpRequestManager.h"
#import "HYBHTTPRequest.h"
@interface HYBHttpRequestManager ()
@property (nonatomic, strong) NSMutableDictionary *requestDict;
@end
@implementation HYBHttpRequestManager
+ (HYBHttpRequestManager *)sharedRequestManager {
static HYBHttpRequestManager *sharedManager = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
if (!sharedManager) {
sharedManager = [[[self class] alloc] init];
}
});
return sharedManager;
}
- (id)init {
if (self = [super init]) {
self.requestDict = [[NSMutableDictionary alloc] init];
}
return self;
}
- (void)addRequest:(id)request withKey:(NSString *)urlStringKey {
NSString *error = [NSString stringWithFormat:@"error in %s, key is nil", __FUNCTION__];
NSAssert(urlStringKey != nil, error);
[self.requestDict setObject:request forKey:urlStringKey];
return;
}
- (void)removeRequestWithKey:(NSString *)urlStringKey {
NSString *error = [NSString stringWithFormat:@"error in %s, key is nil", __FUNCTION__];
NSAssert(urlStringKey != nil, error);
id request = [self.requestDict objectForKey:urlStringKey];
if ([request isKindOfClass:[ASIHTTPRequest class]]) {
[request clearDelegatesAndCancel];
} else {
NSURLConnection *connection = (NSURLConnection *)request;
[connection cancel];
}
[self.requestDict removeObjectForKey:urlStringKey];
return;
}
- (void)removeAllRequest {
[self.requestDict removeAllObjects];
return;
}
- (void)cancelAllRequestAndRemove {
for (ASIHTTPRequest *request in self.requestDict.allValues) {
[request clearDelegatesAndCancel];
}
[self.requestDict removeAllObjects];
return;
}
@end
最後更新:2017-04-03 05:39:54