笔者前不久终于发布了本身的APP《小印记》,在此分享一些iOS源码,若是读者学到了有用的东西,但愿能前往App Store下载《小印记》支持一下笔者,谢谢!javascript
笔者在作《小印记》APP时,使用的是 AFNetworking 3.1 ,经过对AFNetworking的进一步封装,配合YYCache,实现网络数据请求。服务器
主要文件以下图:网络
附上源码,仅供参考,读者可自行对其进行需求改造。session
JKHttpHelper.happ
#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.murl
#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..."); }];
起码笔者在用的时候是很方便的,但愿能给读者一些思路上的参考。
最后附上《小印记》截图,但愿读者多多支持!