閱讀190 返回首頁    go 阿裏雲 go 技術社區[雲棲]


網絡請求封裝

//
//  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

  上一篇:go 【行人檢測】opencv自帶
  下一篇:go RAID10與RAID01比較,RAID10與RAID5比較