AFNetworking 2.5.x 网络请求的封装
源码地址
https://github.com/YouXianMing/Networking
说明
1. 将block形式的请求转换成用代理来处理
2. 你可以通过继承父类,改写父类的某些方法来达到转换请求字典(加密或者其他事宜等),转换获取结果的目的(加密或者其他事宜等)
3. 支持下载进度
常规请求源码
// // Networking.h // NetworkingCraft // // Created by YouXianMing on 15/6/11. // Copyright (c) 2015年 YouXianMing. All rights reserved. // #import <Foundation/Foundation.h> @class Networking; typedef enum : NSUInteger { GET_METHOD, // GET请求 POST_METHOD, // POST请求 } AFNetworkingRequestMethod; typedef enum : NSUInteger { HTTPRequestType = 0x11, // 二进制格式 (不设置的话为默认格式) JSONRequestType, // JSON方式 PlistRequestType, // 集合文件方式 } AFNetworkingRequestType; typedef enum : NSUInteger { HTTPResponseType = 0x22, // 二进制格式 (不设置的话为默认格式) JSONResponseType, // JSON方式 PlistResponseType, // 集合文件方式 ImageResponseType, // 图片方式 CompoundResponseType, // 组合方式 } AFNetworkingResponseType; @protocol NetworkingDelegate <NSObject> @optional /** * 请求成功 * * @param networking Networking实例对象 * @param data 数据 */ - (void)requestSucess:(Networking *)networking data:(id)data; /** * 请求失败 * * @param networking Networking实例对象 * @param error 错误信息 */ - (void)requestFailed:(Networking *)networking error:(NSError *)error; /** * 用户取消请求 * * @param networking Networking实例对象 * @param error 错误信息 */ - (void)userCanceledFailed:(Networking *)networking error:(NSError *)error; @end @interface Networking : NSObject /** * 代理 */ @property (nonatomic, weak) id <NetworkingDelegate> delegate; /** * 标识符 */ @property (nonatomic, strong) NSString *flag; /** * 超时时间间隔(设置了才能生效,不设置,使用的是AFNetworking自身的超时时间间隔) */ @property (nonatomic, strong) NSNumber *timeoutInterval; /** * 请求的类型 */ @property (nonatomic) AFNetworkingRequestType requestType; /** * 回复的类型 */ @property (nonatomic) AFNetworkingResponseType responseType; /** * 请求的方法类型 */ @property (nonatomic) AFNetworkingRequestMethod RequestMethod; /** * 网络请求地址 */ @property (nonatomic, strong) NSString *urlString; /** * 作为请求用字典 */ @property (nonatomic, strong) NSDictionary *requestDictionary; /** * * -====== 此方法由继承的子类来重载实现 ======- * * 转换请求字典 * * @return 转换后的字典 */ - (NSDictionary *)transformRequestDictionary; /** * * -====== 此方法由继承的子类来重载实现 ======- * * 对返回的结果进行转换 * * @return 转换后的结果 */ - (id)transformRequestData:(id)data; /** * 开始请求 */ - (void)startRequest; /** * 取消请求 */ - (void)cancelRequest; #pragma mark - 便利构造器方法 /** * 便利构造器方法 * * @param urlString 请求地址 * @param requestDictionary 请求参数 * @param delegate 代理 * @param timeoutInterval 超时时间 * @param flag 标签 * @param requestMethod 请求方法 * @param requestType 请求类型 * @param responseType 回复数据类型 * * @return 实例对象 */ + (instancetype)networkingWithUrlString:(NSString *)urlString requestDictionary:(NSDictionary *)requestDictionary delegate:(id)delegate timeoutInterval:(NSNumber *)timeoutInterval flag:(NSString *)flag requestMethod:(AFNetworkingRequestMethod)requestMethod requestType:(AFNetworkingRequestType)requestType responseType:(AFNetworkingResponseType)responseType; @end
// // Networking.m // NetworkingCraft // // Created by YouXianMing on 15/6/11. // Copyright (c) 2015年 YouXianMing. All rights reserved. // #import "Networking.h" #import "AFNetworking.h" typedef enum : NSUInteger { DEALLOC_CANCEL, // dealloc取消 USER_CANCEL, // 用户取消 } ECancelType; @interface Networking () #pragma mark - Private Instance @property (nonatomic, strong) AFHTTPRequestOperationManager *manager; @property (nonatomic, strong) AFHTTPRequestOperation *httpOperation; @property (nonatomic) ECancelType cancelType; #pragma mark - Private Method /** * 默认设置 */ - (void)defaultConfig; /** * 根据序列化枚举值返回对应的请求策略 * * @param serializerType 序列化枚举值 * * @return 序列化策略 */ + (AFHTTPRequestSerializer *)requestSerializerWith:(AFNetworkingRequestType)serializerType; /** * 根据序列化枚举值返回对应的回复策略 * * @param serializerType 序列化枚举值 * * @return 序列化策略 */ + (AFHTTPResponseSerializer *)responseSerializerWith:(AFNetworkingResponseType)serializerType; @end @implementation Networking /** * 初始化方法 * * @return 实例对象 */ - (instancetype)init { self = [super init]; if (self) { // 默认设置 [self defaultConfig]; } return self; } - (void)defaultConfig { self.manager = [AFHTTPRequestOperationManager manager]; // 设置回复内容信息 self.manager.responseSerializer.acceptableContentTypes = [self.manager.responseSerializer.acceptableContentTypes setByAddingObject:@"text/html"]; } - (void)startRequest { if (self.urlString.length <= 0) { return; } // 设置请求类型 if (self.requestType) { self.manager.requestSerializer = [Networking requestSerializerWith:self.requestType]; } else { self.manager.requestSerializer = [Networking requestSerializerWith:HTTPRequestType]; } // 设置回复类型 if (self.responseType) { self.manager.responseSerializer = [Networking responseSerializerWith:self.responseType]; } else { self.manager.responseSerializer = [Networking responseSerializerWith:HTTPResponseType]; } // 设置超时时间 if (self.timeoutInterval && self.timeoutInterval.floatValue > 0) { [self.manager.requestSerializer willChangeValueForKey:@"timeoutInterval"]; self.manager.requestSerializer.timeoutInterval = self.timeoutInterval.floatValue; [self.manager.requestSerializer didChangeValueForKey:@"timeoutInterval"]; } // 开始执行请求 if (self.RequestMethod == GET_METHOD) { __weak Networking *weakSelf = self; self.httpOperation = [self.manager GET:self.urlString parameters:[weakSelf transformRequestDictionary] success:^(AFHTTPRequestOperation *operation, id responseObject) { if (weakSelf.delegate && [weakSelf.delegate respondsToSelector:@selector(requestSucess:data:)]) { [weakSelf.delegate requestSucess:weakSelf data:[weakSelf transformRequestData:responseObject]]; } } failure:^(AFHTTPRequestOperation *operation, NSError *error) { if (self.cancelType == USER_CANCEL) { if (weakSelf.delegate && [weakSelf.delegate respondsToSelector:@selector(userCanceledFailed:error:)]) { [weakSelf.delegate userCanceledFailed:weakSelf error:error]; weakSelf.cancelType = DEALLOC_CANCEL; } } else { if (weakSelf.delegate && [weakSelf.delegate respondsToSelector:@selector(requestFailed:error:)]) { [weakSelf.delegate requestFailed:weakSelf error:error]; } } }]; } else if (self.RequestMethod == POST_METHOD) { __weak Networking *weakSelf = self; self.httpOperation = [self.manager POST:self.urlString parameters:[weakSelf transformRequestDictionary] success:^(AFHTTPRequestOperation *operation, id responseObject) { if (weakSelf.delegate && [weakSelf.delegate respondsToSelector:@selector(requestSucess:data:)]) { [weakSelf.delegate requestSucess:weakSelf data:[weakSelf transformRequestData:responseObject]]; } } failure:^(AFHTTPRequestOperation *operation, NSError *error) { if (self.cancelType == USER_CANCEL) { if (weakSelf.delegate && [weakSelf.delegate respondsToSelector:@selector(userCanceledFailed:error:)]) { [weakSelf.delegate userCanceledFailed:weakSelf error:error]; weakSelf.cancelType = DEALLOC_CANCEL; } } else { if (weakSelf.delegate && [weakSelf.delegate respondsToSelector:@selector(requestFailed:error:)]) { [weakSelf.delegate requestFailed:weakSelf error:error]; } } }]; } else { } } - (void)cancelRequest { self.cancelType = USER_CANCEL; [self.httpOperation cancel]; } - (void)dealloc { self.cancelType = DEALLOC_CANCEL; [self.httpOperation cancel]; } + (AFHTTPRequestSerializer *)requestSerializerWith:(AFNetworkingRequestType)serializerType { if (serializerType == JSONRequestType) { return [AFJSONRequestSerializer serializer]; } else if (serializerType == HTTPRequestType) { return [AFHTTPRequestSerializer serializer]; } else if (serializerType == PlistRequestType) { return [AFPropertyListRequestSerializer serializer]; } else { return nil; } } + (AFHTTPResponseSerializer *)responseSerializerWith:(AFNetworkingResponseType)serializerType { if (serializerType == JSONResponseType) { return [AFJSONResponseSerializer serializer]; } else if (serializerType == HTTPResponseType) { return [AFHTTPResponseSerializer serializer]; } else if (serializerType == PlistResponseType) { return [AFPropertyListResponseSerializer serializer]; } else if (serializerType == ImageResponseType) { return [AFImageResponseSerializer serializer]; } else if (serializerType == CompoundResponseType) { return [AFCompoundResponseSerializer serializer]; } else { return nil; } } - (NSDictionary *)transformRequestDictionary { return self.requestDictionary; } - (id)transformRequestData:(id)data { return data; } + (instancetype)networkingWithUrlString:(NSString *)urlString requestDictionary:(NSDictionary *)requestDictionary delegate:(id)delegate timeoutInterval:(NSNumber *)timeoutInterval flag:(NSString *)flag requestMethod:(AFNetworkingRequestMethod)requestMethod requestType:(AFNetworkingRequestType)requestType responseType:(AFNetworkingResponseType)responseType { Networking *networking = [[[self class] alloc] init]; networking.urlString = urlString; networking.requestDictionary = requestDictionary; networking.delegate = delegate; networking.timeoutInterval = timeoutInterval; networking.flag = flag; networking.RequestMethod = requestMethod; networking.requestType = requestType; networking.responseType = responseType; return networking; } @end
下载请求源码
// // DownloadTask.h // NetworkingCraft // // Created by YouXianMing on 15/6/11. // Copyright (c) 2015年 YouXianMing. All rights reserved. // #import <Foundation/Foundation.h> #import <UIKit/UIKit.h> @class DownloadTask; @protocol DownloadTaskDelegate <NSObject> @optional /** * 下载任务 * * @param downloadTask 实例对象 * @param progress 进度显示 */ - (void)downloadTask:(DownloadTask *)downloadTask withProgress:(CGFloat)progress; /** * 下载失败 * * @param downloadTask 实例对象 * @param error 错误信息 */ - (void)downloadTask:(DownloadTask *)downloadTask failedWithError:(NSError *)error; /** * 下载成功 * * @param downloadTask 实例对象 */ - (void)downloadTaskSucess:(DownloadTask *)downloadTask; @end @interface DownloadTask : NSObject /** * 代理 */ @property (nonatomic, weak) id <DownloadTaskDelegate> delegate; /** * 下载地址 */ @property (nonatomic, strong) NSString *urlString; /** * 存储的文件路径(不包括文件名字,如果不设置,则默认在/Library/Caches文件夹下) * * -------------------- * /Documents * /Library/Caches * /Library/Preferences * /tmp * -------------------- * */ @property (nonatomic, strong) NSString *filePath; /** * 文件名(如果不给文件名,则使用默认的文件名) */ @property (nonatomic, strong) NSString *fileName; /** * 绝对文件路径 */ @property (nonatomic, strong, readonly) NSString *file; /** * 开始下载 */ - (void)startDownload; /** * 停止下载 */ - (void)stopDownload; #pragma mark - 便利构造器 /** * 便利构造器 * * @param urlString 下载地址 * @param filePath 文件相对目录(可以不设置) * @param fileName 文件名字(可以不设置) * @param delegate 代理对象 * * @return 实例对象 */ + (instancetype)downloadTaskWithUrlString:(NSString *)urlString fileDirectory:(NSString *)filePath fileName:(NSString *)fileName delegate:(id)delegate; @end
// // DownloadTask.m // NetworkingCraft // // Created by YouXianMing on 15/6/11. // Copyright (c) 2015年 YouXianMing. All rights reserved. // #import "DownloadTask.h" #import "AFNetworking.h" @interface DownloadTask () @property (nonatomic, strong) AFHTTPSessionManager *session; @property (nonatomic, strong) NSURLSessionDownloadTask *downloadTask; @property (nonatomic, strong) NSString *file; @end @implementation DownloadTask - (instancetype)init { self = [super init]; if (self) { [self defaultConfig]; } return self; } - (void)defaultConfig { self.session = [AFHTTPSessionManager manager]; } - (void)startDownload { if (self.urlString.length <= 0) { return; } // 定义一个progress指针 NSProgress *progress; // 创建一个URL链接 NSURL *url = [NSURL URLWithString:self.urlString]; // 初始化一个请求 NSURLRequest *request = [NSURLRequest requestWithURL:url]; // 开始下载任务 __weak DownloadTask *weakSelf = self; self.downloadTask = [self.session downloadTaskWithRequest:request progress:&progress destination:^NSURL *(NSURL *targetPath, NSURLResponse *response) { // 获取基本路径 NSString *filePath = nil; // 文件路径 if (weakSelf.filePath) { filePath = [weakSelf pathWithSting:self.filePath]; } else { filePath = [weakSelf pathWithSting:@"/Library/Caches"]; } // 文件名字 if (weakSelf.fileName) { filePath = [filePath stringByAppendingPathComponent:weakSelf.fileName]; } else { filePath = [filePath stringByAppendingPathComponent:[response suggestedFilename]]; } // 获取文件绝对路径 weakSelf.file = filePath; NSURL *documentsDirectoryURL = [NSURL fileURLWithPath:filePath]; return documentsDirectoryURL; } completionHandler:^(NSURLResponse *response, NSURL *filePath, NSError *error) { if (weakSelf.delegate) { // 结束后移除掉这个progress [progress removeObserver:self forKeyPath:@"fractionCompleted" context:nil]; if (error == nil) { // 成功 if ([weakSelf.delegate respondsToSelector:@selector(downloadTaskSucess:)]) { [weakSelf.delegate downloadTaskSucess:weakSelf]; } } else { // 出错 if ([weakSelf.delegate respondsToSelector:@selector(downloadTask:failedWithError:)]) { [weakSelf.delegate downloadTask:weakSelf failedWithError:error]; } } } }]; // 开始下载 [self.downloadTask resume]; if (self.delegate) { // 给这个progress添加监听任务 [progress addObserver:self forKeyPath:@"fractionCompleted" options:NSKeyValueObservingOptionNew context:nil]; } } - (void)stopDownload { [self.downloadTask cancel]; } /** * 获取路径 * * @param string 相对路径 * * @return 绝对路径 */ - (NSString *)pathWithSting:(NSString *)string { return [NSHomeDirectory() stringByAppendingPathComponent:string]; } - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { if ([keyPath isEqualToString:@"fractionCompleted"] && [object isKindOfClass:[NSProgress class]]) { NSProgress *progress = (NSProgress *)object; [_delegate downloadTask:self withProgress:progress.fractionCompleted]; } } + (instancetype)downloadTaskWithUrlString:(NSString *)urlString fileDirectory:(NSString *)filePath fileName:(NSString *)fileName delegate:(id)delegate { DownloadTask *downloadTask = [[[self class] alloc] init]; downloadTask.urlString = urlString; downloadTask.filePath = filePath; downloadTask.fileName = fileName; downloadTask.delegate = delegate; return downloadTask; } @end
使用