隨著ipv6的使用,AFNetWoring發(fā)布了3.0版本滤祖,剛剛完成的這個(gè)項(xiàng)目我用的是AF3.0筷狼,這里有這次使用AF3.0的封裝,簡單說一下都是怎么做的匠童。
1.單例形式創(chuàng)建AFHTTPSessionManager的子類埂材。
+ (instancetype)sharedClient {
static AFAppDotNetAPIClient *_sharedClient = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_sharedClient = [[AFAppDotNetAPIClient alloc] initWithBaseURL:[NSURL URLWithString:AFAppDotNetAPIBaseURLString]];
_sharedClient.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json", @"text/json", @"text/javascript",@"text/html",@"text/plain",nil];
_sharedClient.requestSerializer.timeoutInterval = 30; // 設(shè)置超時(shí)時(shí)間30s
//支持https,SSL證書加密
// AFSecurityPolicy *securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeCertificate];
// securityPolicy.allowInvalidCertificates = YES;
// securityPolicy.validatesDomainName = NO;
// _sharedClient.securityPolicy = securityPolicy;
});
return _sharedClient;
}
2.封裝基本通用的請(qǐng)求方法
.h接口文件
/**
* 返回json結(jié)構(gòu)為CommenReturnModel的HTTP請(qǐng)求
*
* @param parameters 參數(shù)集汤求,為#NSDictionary#類型
* @param POST 地址俏险,除BaseUrl之外的部分
* @param block block參數(shù)
*
* @return 返回值
*/
+(NSURLSessionDataTask*)normalHttpRequestWithParameters:(NSDictionary*)parameters POST:(NSString*)POST resultBlock:(void(^)(NSDictionary* commentReturnModel, NSError*error))block;
/*!
* 上傳圖片接口
*
* @param parameters 參數(shù)集,為#NSDictionary#類型
* @param picDic 圖片字典{key為推薦命名扬绪。value為圖片}
* @param POST 地址竖独,除BaseUrl之外的部分
* @param block block參數(shù)
*
* @return 返回值
*/
+(NSURLSessionDataTask*)uploadHttpRequestWithParameters:(NSDictionary*)parameters PictureDic:(NSDictionary *)picDic POST:(NSString*)POST resultBlock:(void(^)(NSDictionary* commentReturnModel, NSError*error))block;
.m實(shí)現(xiàn)文件
//返回json結(jié)構(gòu)為CommenReturnModel的HTTP請(qǐng)求
+(NSURLSessionDataTask*)normalHttpRequestWithParameters:(NSDictionary *)parameters POST:(NSString *)POST resultBlock:(void (^)(NSDictionary *, NSError *))block{
DEBUGLog(@"%@%@?%@",AFAppDotNetAPIBaseURLString, POST, [self getStringWithDictionary:parameters]);
dispatch_async(dispatch_get_main_queue(), ^{
[[MbprogressTool standard] showprogressHUD];
});
NSString * post = [NSString stringWithFormat:@"%@%@",AFAppDotNetAPIBaseURLString,POST];
return [[AFAppDotNetAPIClient sharedClient] POST:post parameters:parameters progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
DEBUGLog(@"%@",responseObject);
NSAssert([responseObject isKindOfClass:[NSDictionary class]], @"JSON結(jié)構(gòu)返回與約定不符");
if (block) {
block(responseObject, nil);
}
[[MbprogressTool standard] hiddenProgressHUD];
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
if (block) {
block(nil, error);
}
[[MbprogressTool standard] hiddenProgressHUD];
}];
}
//圖片上傳
+(NSURLSessionDataTask *)uploadHttpRequestWithParameters:(NSDictionary *)parameters PictureDic:(NSDictionary *)picDic POST:(NSString *)POST resultBlock:(void (^)(NSDictionary *, NSError *))block{
NSString * post = [NSString stringWithFormat:@"%@%@",AFAppDotNetAPIBaseURLString,POST];
dispatch_async(dispatch_get_main_queue(), ^{
[[MbprogressTool standard] showprogressHUD];
});
return [[AFAppDotNetAPIClient sharedClient] POST:post parameters:parameters constructingBodyWithBlock:^(id<AFMultipartFormData> _Nonnull formData) {
for (NSString *keyString in [picDic allKeys]){
NSData *imgData = [picDic objectForKey:keyString];
if (imgData.length > 0) {
[formData appendPartWithFileData:imgData name:keyString fileName:[NSString stringWithFormat:@"%@%u.jpg", keyString,arc4random()%98] mimeType:@"image/jpeg"];
DEBUGLog(@"圖片上傳%@",keyString);
}
}
} progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
DEBUGLog(@"%@",parameters);
NSAssert([responseObject isKindOfClass:[NSDictionary class]], @"JSON結(jié)構(gòu)返回與約定不符");
if (block) {
block(responseObject, nil);
}
[[MbprogressTool standard] hiddenProgressHUD];
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
if (block) {
block(nil, error);
}
[[MbprogressTool standard] hiddenProgressHUD];
}];
}
3.具體接口再次對(duì)通用接口進(jìn)行封裝(嫌麻煩的話直接用通用的也可以)
我這里是用對(duì)上面的通用接口類加不同的擴(kuò)展實(shí)現(xiàn)的(下圖也是我的整個(gè)網(wǎng)絡(luò)部分結(jié)構(gòu))
接口邏輯.png
一個(gè)具體的實(shí)現(xiàn)例子
/*!
* 查詢收藏列表
*
* @param currectPage 當(dāng)前頁面
* @param block block description
*
* @return return value description
*/
+(NSURLSessionDataTask*)getMyCollectListIsCurretPage:(NSInteger)currectPage ResultBlock:(void(^)(NSArray * model, NSString *failMessage))block;
+(NSURLSessionDataTask*) getMyCollectListIsCurretPage:(NSInteger)currectPage ResultBlock:(void(^)(NSArray * model, NSString *failMessage))block{
NSDictionary * parma = @{@"userId":@"",
@"pageSize":@"10",
@"pageIndex":@(currectPage)};
return [self normalHttpRequestWithParameters:parma POST:isBaby?MyCollectBabyListURL:MyCollectShowListURL resultBlock:^(NSDictionary *commentReturnModel, NSError *error) {
if (!error){//成功是操作
if ([[commentReturnModel objectForKey:@"status"] integerValue] == DEF_SUCESS_CODE){
NSMutableArray * dataArr = [[NSMutableArray alloc]init];
[commentReturnModel[@"data"][@"dataList"] enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
if (isBaby) {
MyCollectBabyModel * styleModel = [[MyCollectBabyModel alloc]initWithDictionary:obj];
[dataArr addObject:styleModel];
}else{
MyCollectShowBabyModel * styleModel = [[MyCollectShowBabyModel alloc]initWithDictionary:obj];
[dataArr addObject:styleModel];
}
}];
NSArray * model = [NSArray arrayWithArray:dataArr];
if (block) {
block(model, nil);
}
}
else{//失敗時(shí)的操作
if (block) {
block(nil, [commentReturnModel objectForKey:@"msg"]);
}
}
}else{//錯(cuò)誤時(shí)的操作
if (block) {
block(nil, @"網(wǎng)絡(luò)請(qǐng)求失敗");
}
}
}];
}
上面就是我的AF的封裝其中還有兩個(gè)類說一下
1.NetRequestUrls 這里我是存放了所有的接口地址,這樣方便統(tǒng)一管理挤牛,
2.MbprogressTool則是對(duì)于MB的一個(gè)封裝
在上面通用方法的時(shí)候大家應(yīng)該發(fā)現(xiàn)了我在開始請(qǐng)求的時(shí)候調(diào)用了一下莹痢,在結(jié)束是停止,這樣就可以買一個(gè)請(qǐng)求都有MB了不用在所有地方都寫墓赴。MbprogressTool具體實(shí)現(xiàn)如下:
.h接口文件
#import <Foundation/Foundation.h>
@interface MbprogressTool : NSObject
+(instancetype)standard;
-(void)showprogressHUD;
-(void)hiddenProgressHUD;
-(UIViewController *)getCurrentVC;
@end
.m實(shí)現(xiàn)文件
#import "MbprogressTool.h"
#import <MBProgressHUD.h>
#import <UIImage+GIF.h>
@interface MbprogressTool ()
@property (nonatomic, strong) MBProgressHUD *progressHUD;
@property (nonatomic, assign) NSInteger referenceCount;//引用mb的個(gè)數(shù)
@end
@implementation MbprogressTool
+(instancetype)standard{
static MbprogressTool *mbprogressTool = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
mbprogressTool = [[MbprogressTool alloc] init];
mbprogressTool.progressHUD = [[MBProgressHUD alloc]init];
mbprogressTool.progressHUD.color = [UIColor clearColor];
mbprogressTool.progressHUD.mode = MBProgressHUDModeCustomView;
UIImageView * imageView = [[UIImageView alloc]initWithImage:[UIImage sd_animatedGIFNamed:@"刷新gif"]];
imageView.layer.cornerRadius = 15;
imageView.layer.masksToBounds = YES;
imageView.alpha = 0.7;
imageView.frame = CGRectMake(0, 0, 123/1.5, 123/1.5);
mbprogressTool.progressHUD.customView = imageView;
mbprogressTool.progressHUD.removeFromSuperViewOnHide = YES;
//mbprogressTool.progressHUD.labelText=@"加載中...";
//mbprogressTool.progressHUD.labelFont = DEF_STFont(14.0);
mbprogressTool.referenceCount = 0;
});
return mbprogressTool;
}
-(void)showprogressHUD{
_referenceCount++;
if ([self getCurrentVC].navigationController != nil) {
[[self getCurrentVC].navigationController.view addSubview:_progressHUD];
}else{
[[self getCurrentVC].view addSubview:_progressHUD];
}
[_progressHUD show:YES];
}
-(void)hiddenProgressHUD{
_referenceCount--;
if (_referenceCount == 0) {
[_progressHUD hide:YES];
}
// [_progressHUD removeFromSuperview];
}
//獲取當(dāng)前屏幕顯示的viewcontroller
-(UIViewController *)getCurrentVC
{
UIViewController *result = nil;
UIWindow * window = [[UIApplication sharedApplication] keyWindow];
if (window.windowLevel != UIWindowLevelNormal){
NSArray *windows = [[UIApplication sharedApplication] windows];
for(UIWindow * tmpWin in windows){
if (tmpWin.windowLevel == UIWindowLevelNormal){
window = tmpWin;
break;
}
}
}
UIView *View = [[window subviews] objectAtIndex:0];
UIView *frontView = [[View subviews] lastObject];
id nextResponder = [frontView nextResponder];
if ([nextResponder isKindOfClass:[UIViewController class]]){
result = nextResponder;
}
else{
result = window.rootViewController;
}
return result;
}
@end
寫完了竞膳,因?yàn)楝F(xiàn)在完成的這個(gè)項(xiàng)目就是用的這套東西所以使用起來應(yīng)該沒有問題,有什么問題可以問我诫硕,坦辟,,