网络请求封装

//
//  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
时间: 2024-09-16 23:15:06

网络请求封装的相关文章

Android 网络请求详解

我们知道大多数的 Android 应用程序都是通过和服务器进行交互来获取数据的.如果使用 HTTP 协议来发送和接收网络数据,就免不了使用 HttpURLConnection 和 HttpClient,而 Android 中主要提供了上述两种方式来进行 HTTP 操作.并且这两种方式都支持 HTTPS 协议.以流的形式进行上传和下载.配置超时时间.IPv6.以及连接池等功能. 但是 Googl e发布 6.0 版本的时候声明原生剔除 HttpClient,但是笔者认为 HttpClient 会提

iOS开发中不合法的网络请求地址如何解决_IOS

NSString *const kWebsite = @http://image.baidu.com/search/index?tn=baiduimage&ipn=r&ct=201326592&cl=2&lm=-1&st=-1&fr=&sf=1&fmq=1459502303089_R&pv=&ic=0&nc=1&z=&se=1&showtab=0&fb=0&width=&

iOS - AFNetworking 网络请求

前言 在 iOS 开发中,一般情况下,简单的向某个 Web 站点简单的页面提交请求并获取服务器的响应,用 Xcode 自带的 NSURLConnection 是能胜任的.但是,在绝大部分下我们所需要访问的 Web 页面则是属于那种受到权限保护的页面,并不是有一个简单的 URL 可以访问的.这就涉及到了 Session 和 Cookie 的处理了,在此时使用 NSURLConnection 也是能够达到要求的,只是其中处理起来的复杂度和难度就提升了.为了更好的处理向 Web 站点的请求,包括处理

关于ajax网络请求的封装实例_AJAX相关

实例代码: // 封装的ajax网络请求函数 // obj 是一个对象 function AJAX(obj){ //跨域请求 if (obj.dataType == "jsonp") { //在这里 callback 必须是全局变量 保证函数消失的时候 这个变量不可以被销毁 //处理一下函数名(防止多个网络请求 函数名字相同 出现紊乱的情况) var hehe = "callBack" + "_" + new Date().getTime() +

Android 中Volley二次封装并实现网络请求缓存

Android 中Volley二次封装并实现网络请求缓存 Android目前很多同学使用Volley请求网络数据,但是Volley没有对请求过得数据进行缓存,因此需要我们自己手动缓存. 一下就是我的一种思路,仅供参考 具体使用方法为: HashMap<String,String> params = new HashMap<>(); params.put("id", "1"); params.put("user", &quo

关于ajax网络请求的封装实例

实例代码: // 封装的ajax网络请求函数 // obj 是一个对象 function AJAX(obj){ //跨域请求 if (obj.dataType == "jsonp") { //在这里 callback 必须是全局变量 保证函数消失的时候 这个变量不可以被销毁 //处理一下函数名(防止多个网络请求 函数名字相同 出现紊乱的情况) var hehe = "callBack" + "_" + new Date().getTime() +

封装网络请求类来理解闭包

import UIKit import Alamofire enum MethodType { case get case post } class NetworkTools { class func requestData(_ type : MethodType, URLString : String, parameters : [String : Any]? = nil, finishedCallback : @escaping (_ result : Any) -> ()) { // 1.

Android基于OkHttpUtils网络请求的二次封装

OkHttpUtils网络请求为什么进行二次封装? 1.减少代码量 2.后期换网络处理框架方便 二次封装的实现原理 1.将网络请求提取在一个方法中 2.对里面的可变参数,可以通过参数传递过去,也可以提供一个set方法传递过去 3.对于请求失败和成功,我们可以使用接口回调,让调用该方法的对象处理 封装后的网络处理类的功能 1.网络请求 2.xml数据转换成javaBean 每一个处理网络请求的ListView都要处理的3数据方法 1.初始化数据 2.下拉刷新数据 3.上拉加载数据 封装前的代码 /

React Native网络请求

很多移动应用都需要从远程地址中获取数据或资源.你可能需要给某个REST API发起POST请求以提交用户数据,又或者可能仅仅需要从某个服务器上获取一些静态内容--以下就是你会用到的东西.新手可以对照这个简短的视频教程加深理解. 使用Fetch React Native提供了和web标准一致的Fetch API,用于满足开发者访问网络的需求.如果你之前使用过XMLHttpRequest(即俗称的ajax)或是其他的网络API,那么Fetch用起来将会相当容易上手.这篇文档只会列出Fetch的基本用