《印记(官方版)》iOS源码分享--网络层封装篇
2017-03-27 本文已影响202人
_子墨
笔者前不久终于发布了自己的APP《印记(官方版)》,在此分享一些iOS源码,如果读者学到了有用的东西,希望能前往App Store下载《印记(官方版)》支持一下笔者,谢谢!🙂
《印记(官方版)》iOS源码分享--极光推送实践篇
《印记(官方版)》iOS源码分享--自定义弹框篇
《印记(官方版)》iOS源码分享--HTTPS配置篇
《印记(官方版)》源码分享--极光推送服务器篇
笔者在做《印记(官方版)》APP时,使用的是 AFNetworking 3.1 ,通过对AFNetworking的进一步封装,配合YYCache,实现网络数据请求。
主要文件如下图:

附上源码,仅供参考,读者可自行对其进行需求改造。
JKHttpHelper.h
#import <Foundation/Foundation.h>
@interface JKHttpHelper : NSObject
// 获取单例
+ (AFHTTPSessionManager * _Nullable)manager;
/**
* 发送GET请求
*
* @param URLString 请求的基本URL
* @param parameters 请求的参数字典
* @param success 请求成功的回调
* @param failure 请求失败的回调
*/
+ (nullable NSURLSessionDataTask *)GET:(NSString * _Nonnull)URLString
parameters:(nullable id)parameters
progress:(nullable void (^)(NSProgress * _Nonnull downloadProgress))downloadProgress
success:(nullable void (^)(NSURLSessionDataTask * _Nullable task, id _Nullable responseObject))success
failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error))failure;
/**
* 发送POST请求
*
* @param URLString 请求的基本URL
* @param parameters 请求的参数字典
* @param success 请求成功的回调
* @param failure 请求失败的回调
*/
+ (nullable NSURLSessionDataTask *)POST:(NSString * _Nonnull)URLString
parameters:(nullable id)parameters
progress:(nullable void (^)(NSProgress * _Nonnull uploadProgress))uploadProgress
success:(nullable void (^)(NSURLSessionDataTask * _Nullable task, id _Nullable responseObject))success
failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error))failure;
/**
* 发送POST请求(数据包含图片)
*
* @param URLString 请求的基本URL
* @param parameters 请求的参数字典
* @param success 请求成功的回调
* @param failure 请求失败的回调
*/
+ (nullable NSURLSessionDataTask *)POST:(NSString * _Nonnull)URLString
parameters:(nullable id)parameters
constructingBodyWithBlock:(nullable void (^)(id <AFMultipartFormData> _Nullable formData))block
progress:(nullable void (^)(NSProgress * _Nonnull uploadProgress))uploadProgress
success:(nullable void (^)(NSURLSessionDataTask * _Nullable task, id _Nullable responseObject))success
failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error))failure;
@end
JKHttpHelper.m
#import "JKHttpHelper.h"
@implementation JKHttpHelper
// 创建单例
+ (AFHTTPSessionManager *)manager;
{
static AFHTTPSessionManager *shareInstance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
shareInstance = [[AFHTTPSessionManager alloc] initWithBaseURL:[NSURL URLWithString:BaseHttpURLString] sessionConfiguration:configuration];
//设置请求参数的类型:JSON
shareInstance.requestSerializer = [AFJSONRequestSerializer serializer];
//设置服务器返回结果的类型:JSON (AFJSONResponseSerializer,AFHTTPResponseSerializer)
shareInstance.responseSerializer = [AFJSONResponseSerializer serializer];
//设置请求的超时时间
shareInstance.requestSerializer.timeoutInterval = 20.0f;
//设置ContentType
shareInstance.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json", @"text/html", @"text/json", @"text/plain", @"text/javascript", @"text/xml", @"image/jpeg",@"image/png", nil];
// https配置
NSString *cerPath;
NSString *cerPathMode = [[NSUserDefaults standardUserDefaults] objectForKey:@"certificate_path"];
if ([cerPathMode isEqualToString:@"bundle"]) {
cerPath = [[NSBundle mainBundle] pathForResource:@"wecharactery" ofType:@"cer"];
JKLog(@"--bundle--cerPath:%@", cerPath);
}
else {
cerPath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:@"wecharactery.cer"];
JKLog(@"--document--cerPath:%@", cerPath);
}
NSData *certData = [NSData dataWithContentsOfFile:cerPath];
AFSecurityPolicy *securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeCertificate withPinnedCertificates:[[NSSet alloc] initWithObjects:certData, nil]];
NSSet *dataSet = [[NSSet alloc] initWithObjects:certData, nil];
// setPinnedCertificates 设置证书文件(可能不止一个证书)
[securityPolicy setPinnedCertificates:dataSet];
// allowInvalidCertificates 是否允许无效证书
[securityPolicy setAllowInvalidCertificates:NO];
// validatesDomainName 是否需要验证域名
[securityPolicy setValidatesDomainName:YES];
shareInstance.securityPolicy = securityPolicy;
});
return shareInstance;
}
/**
* @author 贾则栋, 16-09-14 14:09:38
*
* @brief 发送GET请求
*
* @param URLString
* @param parameters
* @param success
* @param failure
*/
+ (NSURLSessionDataTask *)GET:(NSString *)URLString
parameters:(id)parameters
progress:(void (^)(NSProgress * _Nonnull))downloadProgress
success:(void (^)(NSURLSessionDataTask * _Nullable, id _Nullable))success
failure:(void (^)(NSURLSessionDataTask * _Nullable, NSError * _Nonnull))failure
{
return [[JKHttpHelper manager] GET:URLString parameters:parameters progress:downloadProgress success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
success(task, responseObject);
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
failure(task, error);
}];
}
/**
* @author 贾则栋, 16-09-14 14:09:10
*
* @brief 发送POST请求
*
* @param URLString
* @param parameters
* @param success
* @param failure
*/
+ (NSURLSessionDataTask *)POST:(NSString *)URLString
parameters:(id)parameters
progress:(void (^)(NSProgress * _Nonnull))uploadProgress
success:(void (^)(NSURLSessionDataTask * _Nullable, id _Nullable))success
failure:(void (^)(NSURLSessionDataTask * _Nullable, NSError * _Nonnull))failure
{
return [[JKHttpHelper manager] POST:URLString parameters:parameters progress:uploadProgress success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
success(task, responseObject);
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
failure(task, error);
}];
}
/**
* 发送POST请求(数据包含图片)
*
* @param URLString 请求的基本URL
* @param parameters 请求的参数字典
* @param success 请求成功的回调
* @param failure 请求失败的回调
*/
+ (nullable NSURLSessionDataTask *)POST:(NSString * _Nonnull)URLString
parameters:(nullable id)parameters
constructingBodyWithBlock:(nullable void (^)(id <AFMultipartFormData> formData))block
progress:(nullable void (^)(NSProgress * _Nonnull uploadProgress))uploadProgress
success:(nullable void (^)(NSURLSessionDataTask * _Nullable task, id _Nullable responseObject))success
failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error))failure
{
return [[JKHttpHelper manager] POST:URLString parameters:parameters constructingBodyWithBlock:block progress:uploadProgress success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
success(task, responseObject);
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
failure(task, error);
}];
}
JKCheckNetworkHelper.h
#import <Foundation/Foundation.h>
@interface JKCheckNetworkHelper : NSObject
+ (void)startMonitoring;
+ (NSInteger)getNetWorkStatus;
@end
JKCheckNetworkHelper.m
#import "JKCheckNetworkHelper.h"
@implementation JKCheckNetworkHelper
+ (void)startMonitoring
{
[[AFNetworkReachabilityManager sharedManager] setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {
// 监测到不同网络的情况
switch (status)
{
case AFNetworkReachabilityStatusUnknown:
JKLog(@"current network status: Unknown");
break;
case AFNetworkReachabilityStatusNotReachable:
JKLog(@"current network status: NotReachable");
break;
case AFNetworkReachabilityStatusReachableViaWWAN:
JKLog(@"current network status: WWAN");
break;
case AFNetworkReachabilityStatusReachableViaWiFi:
JKLog(@"current network status: WiFi");
break;
default:
break;
}
}];
// 开始监听网络状况
[[AFNetworkReachabilityManager sharedManager] startMonitoring];
}
// 获取网络状态标识
+ (NSInteger)getNetWorkStatus
{
return [AFNetworkReachabilityManager sharedManager].networkReachabilityStatus;
}
- (void)dealloc
{
[[AFNetworkReachabilityManager sharedManager] stopMonitoring];
}
@end
JKWeCharacteryDataHelper.h
#import <Foundation/Foundation.h>
typedef NS_ENUM(NSInteger, RequestMode) {
RequestModeGet = 0, // Get请求
RequestModePost // Post请求
};
typedef NS_ENUM(NSInteger, RefreshMode) {
RefreshModeFromHeader = 0, // 下拉刷新请求
RefreshModeFromFooter, // 上拉刷新请求
RefreshModeCacheElseNew, // 从缓存加载,没有则请求
RefreshModeOnlyCache, // 仅从缓存加载
RefreshModeNew // 界面将要显示时请求
};
@interface JKWeCharacteryDataHelper : NSObject
// 获取、上传微言数据(不包含图片)
+ (nullable NSURLSessionDataTask *)dealWeCharacteryDataWithURL:(NSString * _Nonnull)urlStr
Param:(nullable NSMutableDictionary *)param
RefreshMode:(RefreshMode)refreshMode
RequestMode:(RequestMode)requestMode
Success:(nullable void(^)(NSURLSessionDataTask * _Nullable task, id _Nullable responseObject))success
Failure:(nullable void(^)(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error))failure;
// 上传微言数据(包含图片)
+ (nullable NSURLSessionDataTask *)uploadWeCharacteryDataWithURL:(NSString * _Nonnull)urlStr
Param:(nullable NSMutableDictionary *)param
constructingBodyWithBlock:(nullable void (^)(id <AFMultipartFormData> _Nullable formData))block
progress:(nullable void (^)(NSProgress * _Nonnull uploadProgress))uploadProgress
Success:(nullable void(^)(NSURLSessionDataTask * _Nullable task, id _Nullable responseObject))success
Failure:(nullable void(^)(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error))failure;
// 微言数据请求
+ (nullable NSURLSessionDataTask *)requestWeCharacteryDataWithURL:(NSString * _Nonnull)urlStr
Param:(nullable NSMutableDictionary *)param
RefreshMode:(RefreshMode)refreshMode
RequestMode:(RequestMode)requestMode
Success:(nullable void(^)(NSURLSessionDataTask * _Nullable task, id _Nullable responseObject))success
Failure:(nullable void(^)(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error))failure;
// 下载文件
+ (nullable NSURLSessionDownloadTask *)downloadFileWithUrl:(NSString * _Nonnull)url
progress:(nullable void (^)(NSProgress * _Nonnull downloadProgress))progress
destination:(nullable NSURL * _Nonnull (^)(NSURL * _Nullable targetPath, NSURLResponse * _Nullable response))destination
completionHandler:(nullable void (^)(NSURLResponse * _Nullable response, NSURL * _Nullable filePath, NSError * _Nonnull error))completionHandler;
@end
JKWeCharacteryDataHelper.m
#import "JKWeCharacteryDataHelper.h"
#import "JKHttpHelper.h"
#import "JKCacheHelper.h"
#import "JKCheckNetworkHelper.h"
@implementation JKWeCharacteryDataHelper
// 获取、上传微言数据
+ (nullable NSURLSessionDataTask *)dealWeCharacteryDataWithURL:(NSString * _Nonnull)urlStr
Param:(nullable NSMutableDictionary *)param
RefreshMode:(RefreshMode)refreshMode
RequestMode:(RequestMode)requestMode
Success:(nullable void(^)(NSURLSessionDataTask * _Nullable task, id _Nullable responseObject))success
Failure:(nullable void(^)(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error))failure
{
// 获取网络状态
NSInteger networkStatus = [JKCheckNetworkHelper getNetWorkStatus];
if (networkStatus == 0) {
refreshMode = RefreshModeCacheElseNew;
NSDictionary *userInfo = [NSDictionary dictionaryWithObject:@"NetWorkStatus" forKey:NSLocalizedDescriptionKey];
NSError *aError = [NSError errorWithDomain:@"NetWorkError" code:-101 userInfo:userInfo];
failure(nil, aError);
}
// 获取缓存数据
id cache = [JKCacheHelper getMemoryCacheWithKey:urlStr];
NSDictionary *object = [[NSDictionary alloc] init];
if (cache) {
object = [NSDictionary dictionaryWithObject:cache forKey:@"result"];
}
else {
object = nil;
}
switch (refreshMode) {
case RefreshModeCacheElseNew: // 从缓存加载,没有则请求
if (object) {
success(nil,object);
return nil;
}
else {
break;
}
case RefreshModeOnlyCache: // 仅从缓存加载
if (object) {
success(nil,object);
}
return nil;
case RefreshModeNew: // 界面将要显示时请求
break;
case RefreshModeFromHeader: // 下拉刷新请求
break;
case RefreshModeFromFooter: // 上拉刷新请求
break;
default:
break;
}
return [self requestWeCharacteryDataWithURL:urlStr Param:param RefreshMode:refreshMode RequestMode:requestMode Success:success Failure:failure];
}
// 上传微言数据(数据包含图片)
+ (nullable NSURLSessionDataTask *)uploadWeCharacteryDataWithURL:(NSString * _Nonnull)urlStr
Param:(nullable NSMutableDictionary *)param
constructingBodyWithBlock:(nullable void (^)(id <AFMultipartFormData> _Nullable formData))block
progress:(nullable void (^)(NSProgress * _Nonnull uploadProgress))uploadProgress
Success:(nullable void(^)(NSURLSessionDataTask * _Nullable task, id _Nullable responseObject))success
Failure:(nullable void(^)(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error))failure
{
return [JKHttpHelper POST:urlStr parameters:param constructingBodyWithBlock:block progress:uploadProgress success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
success(task, responseObject);
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
failure(task, error);
}];
}
// 微言数据请求
+ (nullable NSURLSessionDataTask *)requestWeCharacteryDataWithURL:(NSString * _Nonnull)urlStr
Param:(nullable NSMutableDictionary *)param
RefreshMode:(RefreshMode)refreshMode
RequestMode:(RequestMode)requestMode
Success:(nullable void(^)(NSURLSessionDataTask * _Nullable task, id _Nullable responseObject))success
Failure:(nullable void(^)(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error))failure
{
switch (requestMode) {
case RequestModeGet: {
switch (refreshMode) {
case RefreshModeFromFooter:
return [JKHttpHelper GET:urlStr parameters:param progress:^(NSProgress * _Nonnull downloadProgress) {
} success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
success(task, responseObject);
// // 更新缓存
// NSArray *addArr = [NSArray arrayWithArray:responseObject[@"result"]];
// if (addArr.count != 0) {
// NSMutableArray *array = [NSMutableArray arrayWithArray:(NSArray *)[JKCacheHelper getMemoryCacheWithKey:urlStr]];
// // 追加到尾部
// [array addObjectsFromArray:addArr];
//
// [JKCacheHelper setMemoryCache:array forKey:urlStr withBlock:nil];
// }
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
failure(task, error);
}];
break;
case RefreshModeFromHeader:
return [JKHttpHelper GET:urlStr parameters:param progress:^(NSProgress * _Nonnull downloadProgress) {
} success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
success(task, responseObject);
// // 更新缓存
// NSMutableArray *array = [NSMutableArray arrayWithArray:responseObject[@"result"]];
// id cache = [JKCacheHelper getMemoryCacheWithKey:urlStr];
// if (cache) {
// // 添加到头部
// [array addObjectsFromArray:(NSArray *)cache];
// [JKCacheHelper setMemoryCache:array forKey:urlStr withBlock:nil];
// }
// else {
// [JKCacheHelper setMemoryCache:array forKey:urlStr withBlock:nil];
// }
// // 刷新缓存
// NSArray *array = [NSArray arrayWithArray:responseObject[@"result"]];
// [JKCacheHelper setMemoryCache:array forKey:urlStr withBlock:nil];
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
failure(task, error);
}];
break;
case RefreshModeNew:
case RefreshModeCacheElseNew:
return [JKHttpHelper GET:urlStr parameters:param progress:^(NSProgress * _Nonnull downloadProgress) {
} success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
success(task, responseObject);
// // 刷新缓存
// NSArray *array = [NSArray arrayWithArray:responseObject[@"result"]];
// [JKCacheHelper setMemoryCache:array forKey:urlStr withBlock:nil];
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
failure(task, error);
}];
break;
default:
break;
}
}
break;
case RequestModePost: {
return [JKHttpHelper POST:urlStr parameters:param progress:^(NSProgress * _Nonnull uploadProgress) {
} success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
success(task, responseObject);
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
failure(task, error);
}];
}
break;
default:
break;
}
return nil;
}
+ (nullable NSURLSessionDownloadTask *)downloadFileWithUrl:(NSString * _Nonnull)url
progress:(nullable void (^)(NSProgress * _Nonnull downloadProgress))progress
destination:(NSURL * (^)(NSURL *targetPath, NSURLResponse *response))destination
completionHandler:(void (^)(NSURLResponse *response, NSURL *filePath, NSError *error))completionHandler {
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:configuration];
NSURL *URL = [NSURL URLWithString:url];
NSURLRequest *request = [NSURLRequest requestWithURL:URL];
NSURLSessionDownloadTask *downloadTask = [manager downloadTaskWithRequest:request progress:^(NSProgress * _Nonnull downloadProgress) {
progress(downloadProgress);
} destination:^NSURL *(NSURL *targetPath, NSURLResponse *response) {
return destination(targetPath, response);
} completionHandler:^(NSURLResponse *response, NSURL *filePath, NSError *error) {
completionHandler(response, filePath, error);
}];
// 调用resume开始工作
[downloadTask resume];
return downloadTask;
}
@end
封装好以后,就可以用一句话来实现数据请求了:
[JKWeCharacteryDataHelper dealWeCharacteryDataWithURL:@"Request URL" Param:param RefreshMode:refreshMode RequestMode:requestMode Success:^(NSURLSessionDataTask *task, id responseObject) {
NSLog(@"do something...");
} Failure:^(NSURLSessionDataTask *task, NSError *error) {
NSLog(@"do something...");
}];
起码笔者在用的时候是很方便的,希望能给读者一些思路上的参考。
最后附上《印记(官方版)》截图,希望读者多多支持! 🙂
