项目对YTKNetwork的使用和封装

2,221 阅读3分钟

项目对YTKNetwork的使用和封装

1.配置YTKNetwork的请求

/**
 配置YTKNetwork的请求
 */
- (void)ytkConfig {
  	YTKNetworkConfig *config = [YTKNetworkConfig sharedConfig];
    NSString *httpIpAddress = nil;
    
#if DEBUG
  	// 根据开发测试人员选择的环境配置ip地址
    httpIpAddress = [[NSUserDefaults standardUserDefaults] valueForKey:@"GTHttpIPAddress"];
    if (httpIpAddress.length == 0) {
        httpIpAddress = kHttpIpAddressTest;
        [[NSUserDefaults standardUserDefaults] setObject:kHttpIpAddressTest forKey:@"GTHttpIPAddress"];
    }
#else
  	// 生产包使用生产环境
    httpIpAddress = kHttpIpAddressProduction;
#endif
    
    NSArray *hostArray = @[kHttpIpAddressDevelop1,kHttpIpAddressDevelop2,kHttpIpAddressTest,kHttpIpAddressProduction,kHttpIpAddressPre];
    for (NSString *host in hostArray) {
        if ([host containsString:[httpIpAddress substringToIndex:httpIpAddress.length-2]]) {
            httpIpAddress = host;
            break;
        }
    }
    config.baseUrl = httpIpAddress;
}

2.继承YTKRequest,重写部分接口GTRequest.h和GTRequest.m文件,用于所有请求错误的统一处理,如token失效

#import "YTKRequest.h"
#import "YTKNetwork.h"
#import "GTHttpDefine.h"

NS_ASSUME_NONNULL_BEGIN
  
@class GTRequest;

typedef void(^httpSuccess)(id result);
typedef void(^httpFailure)(id error);

// 回调
typedef void(^GTRequestSuccessCompletionBlock)(__kindof GTRequest *request);
typedef void(^GTRequestFailureCompletionBlock)(__kindof GTRequest *request);

@interface GTRequest : YTKRequest

/**
 urlString    与baseUrl拼接的url
 method       请求方式:get/post
 argument     请求体:如@{@"name" : name, @"password" : password}
 */
- (instancetype)initWithUrlString:(NSString *)urlString
                         method:(YTKRequestMethod)method
                       argument:(id)argument;

- (instancetype)initWithMethod:(YTKRequestMethod)method;

- (void)startWithDataCompletionBlockWithSuccess:(nullable GTRequestSuccessCompletionBlock)success
                                        failure:(nullable GTRequestFailureCompletionBlock)failure;

@property (copy, nonatomic) httpSuccess success;
@property (copy, nonatomic) httpFailure failure;

@property (nonatomic, copy, nullable) GTRequestSuccessCompletionBlock successDataCompletionBlock;
@property (nonatomic, copy, nullable) GTRequestFailureCompletionBlock failureDataCompletionBlock;
@property (nonatomic, copy, nullable) NSString *jsonModelName;
/// data包含code、data、msg
@property (nonatomic, strong, readonly, nullable) id gtResponseData;
/// 只包含data的内容
@property (nonatomic, strong, readonly, nullable) id gtResponseDic;
/// 转成jsonmodel
@property (nonatomic, strong, nullable) id gtResponseModel;

+ (void)setToken:(NSString *)token;

+ (NSString *)token;

@end

NS_ASSUME_NONNULL_END
#import "GTRequest.h"
#import "GTModel.h"
#import "GTSystemConfig.h"

NSString *GTLoginPageNotification = @"GTLoginPageNotification";
NSString *apiRefreshJWT = @"datacenter/auth/refreshJwt";

@interface GTRequest()

/// 是否需要json->model
@property (nonatomic, assign) BOOL needTransformModel;
@property (nonatomic, strong, readwrite, nullable) NSDictionary *gtResponseData;
@property (nonatomic, assign) BOOL refreshAlready;

@end

@implementation GTRequest {
    NSString *_urlString;
    YTKRequestMethod _method;
    id _argument;
}

#pragma mark - init
- (instancetype)initWithUrlString:(NSString *)urlString method:(YTKRequestMethod)method argument:(id)argument {
    if (self = [super init]) {
        _urlString = urlString;
        _method = method;
        _argument = argument;
    }
    return self;
}

- (instancetype)initWithMethod:(YTKRequestMethod)method {
    if (self = [super init]) {
        _method = method;
    }
    return self;
}

#pragma mark - request
- (void)startWithDataCompletionBlockWithSuccess:(GTRequestSuccessCompletionBlock)success
                                        failure:(GTRequestSuccessCompletionBlock)failure {
    [self setDataCompletionBlockWithSuccess:success failure:failure];
    [self startRequest];
}

- (void)setDataCompletionBlockWithSuccess:(GTRequestSuccessCompletionBlock)success
                                  failure:(GTRequestSuccessCompletionBlock)failure {
    self.successDataCompletionBlock = success;
    self.failureDataCompletionBlock = failure;
}

- (void)startRequest {
    [self startWithCompletionBlockWithSuccess:^(__kindof YTKBaseRequest * _Nonnull request) {
        NSDictionary *dict = nil;
        if ([request.responseJSONObject isKindOfClass:[NSDictionary class]]) {
            dict = request.responseJSONObject;
            self.gtResponseData = dict;
        }
        
        if (self.refreshAlready) {
            self.refreshAlready = NO;
        }
        
        if (self.successDataCompletionBlock) {
            GTRequest *gtRequest = request;
            self.successDataCompletionBlock(gtRequest);
        }
    } failure:^(__kindof YTKBaseRequest * _Nonnull request) {
        NSInteger statusCode = request.response.statusCode;
        
        if (statusCode==401) {
            // go login page
            [[NSNotificationCenter defaultCenter] postNotificationName:GTLoginPageNotification object:@{@"kickoff":@(YES)}];
            [GTRequest setToken:@""];
            //[self refreshJWT];
        }else {
            if (self.failureDataCompletionBlock) {
                GTRequest *gtRequest = request;
                self.failureDataCompletionBlock(gtRequest);
                NSString *message = @"";
#if DEBUG
                NSString *httpIpAddress = [[NSUserDefaults standardUserDefaults] valueForKey:@"GTHttpIPAddress"];
                if (![httpIpAddress isEqualToString:kHttpIpAddressProduction]) {
                    message = [NSString stringWithFormat:@"错误接口:%@\n错误代码%ld",request.requestUrl,(long)request.response.statusCode];
                }

#else
                //message = @"服务器繁忙,请稍后重试!";
#endif
                if (message.length > 0) {
                    [[UIApplication sharedApplication].keyWindow makeToast:message];
                }
            }
        }
    }];
}

#pragma mark - refreshJWT

- (void)refreshJWT {
    GTRequest *api = [[GTRequest alloc] initWithUrlString:apiRefreshJWT method:YTKRequestMethodPOST argument:@{}];
    [api startWithCompletionBlockWithSuccess:^(__kindof YTKBaseRequest * _Nonnull request) {
        NSLog(@"");
    } failure:^(__kindof YTKBaseRequest * _Nonnull request) {
    }];
}

#pragma mark - private data
- (id)gtResponseDic {
    NSDictionary *dic;
    if ([_gtResponseData objectForKey:@"result"]) {
        dic = [_gtResponseData objectForKey:@"result"];
    }
    if (dic) {
        if ([dic isKindOfClass:[NSString class]] && ((NSString *)dic).length == 0) {
            dic = [NSDictionary dictionary];
        }
        return dic;
    }else {
        return _gtResponseData;
    }
}

- (id)gtResponseModel {
    if (_needTransformModel && _jsonModelName.length > 0) {
        id object = nil;
        if ([self.gtResponseDic isKindOfClass:[NSDictionary class]]) {
            object = [NSClassFromString(_jsonModelName) JSONModelWithKeyValues:self.gtResponseDic];
        }
        else if ([self.gtResponseData isKindOfClass:[NSDictionary class]]) {
            object = [NSClassFromString(_jsonModelName) JSONModelWithKeyValues:self.gtResponseData];
        }
        return object;
    }
    return nil;
}

- (void)setJsonModelName:(NSString *)jsonModelName {
    if (jsonModelName && jsonModelName.length > 0) {
        _jsonModelName = jsonModelName;
        _needTransformModel = YES;
    }
    else {
        _needTransformModel = NO;
    }
}

#pragma mark - overwrite

// 需要与baseUrl拼接的地址
- (NSString *)requestUrl {
    return _urlString;
}

// 请求方法
- (YTKRequestMethod)requestMethod {
    return _method;
}

// 请求体
- (id)requestArgument {
    return _argument;
}

// 请求头配置
- (NSDictionary<NSString *,NSString *> *)requestHeaderFieldValueDictionary {
    // 设置请求头相关数据
    NSDictionary *headerFieldDic = [NSMutableDictionary dictionary];
    NSString *userPhoneNameStr = [[UIDevice currentDevice] name];// 手机名称
    NSString *systemVersionStr = [[UIDevice currentDevice] systemVersion];// 手机系统版本号
    NSString *deviceNameStr = [[UIDevice currentDevice] systemName];// 手机系统名称
    if ([GTRequest token].length > 0) {
        [headerFieldDic setValue:[GTRequest token] forKey:@"authorization"];
    }
    if ([GTSystemConfig userLanguage].length == 0) {
        [GTSystemConfig setUserLanguage:@"zh-Hans"];
    }

    switch (_method) {
        case YTKRequestMethodGET:
            [headerFieldDic setValue:@"application/x-www-form-urlencoded;charset=UTF-8" forKey:@"content-type"];
            break;
        case YTKRequestMethodPOST:
        case YTKRequestMethodPUT:
            [headerFieldDic setValue:@"application/json;charset=UTF-8" forKey:@"content-type"];
            break;
        default:
            break;
    }
    return headerFieldDic;
}

- (YTKRequestSerializerType)requestSerializerType {
    return YTKRequestSerializerTypeJSON;
}

- (YTKResponseSerializerType)responseSerializerType {
    return YTKResponseSerializerTypeJSON;
}

+ (void)setToken:(NSString *)token {
    [[NSUserDefaults standardUserDefaults] setValue:token forKey:kJWTTokenKey];
}

+ (NSString *)token {
    return [[NSUserDefaults standardUserDefaults] valueForKey:kJWTTokenKey];
}

3.各个模块单独继承GTRequest,用于模块调用。GTTestApi

#import "GTRequest.h"

NS_ASSUME_NONNULL_BEGIN

typedef NS_ENUM(NSInteger, GTTestAPIType) {
  	GTTestAPITypeTest,
		...
};

// 登录
static NSString *apiTest = @"...";


@interface GTLoginAPI : GTRequest

/**
 init

 @param dictionary 参数
 @param type GTLoginAPIType
 @param method requsetMethod
 @return instance
 */
- (instancetype)initWithDict:(NSDictionary *)dictionary andType:(GTTestAPIType)type andMethod:(YTKRequestMethod)method;

@end

NS_ASSUME_NONNULL_END

#import "GTTestAPI.h"
#import "GTHttpDefine.h"


@interface GTTestAPI() {
    NSDictionary *_dict;
    NSInteger _type;
}
@end

@implementation GTTestAPI

- (instancetype)initWithDict:(NSDictionary *)dictionary andType:(GTTestAPIType)type andMethod:(YTKRequestMethod)method {
    if (self = [super initWithMethod:method]) {
        _dict = dictionary;
        _type = type;
    }
    return self;
}


- (NSString *)requestUrl {
    NSString *url = nil;
    switch (_type) {
        case GTTestAPITypeTest:
            url = apiTest;
            break;
        ...
    }
    return url;
}

- (id)requestArgument {
    return _dict;
}

@end

4.调用实例

- (void)requestWithParam1:(NSString *)param1 param2:(NSString *)param2 {
    NSMutableDictionary *params = [NSMutableDictionary dictionary];
    [params setValue:param1 forKey:@"param1"];
    [params setValue:param2 forKey:@"param2"];
    
    GTTestApi *testApi = [[GTTestApi alloc] initWithDict:params andType:GTTestAPITypeTest andMethod:YTKRequestMethodPOST];
    testApi.jsonModelName = NSStringFromClass([GTTestModel class]);
    
    GTProgressHUD *hud = [GTProgressHUD HUDWithParentView:self.view];
    [testApi startWithDataCompletionBlockWithSuccess:^(__kindof GTRequest *request) {
        [hud hideProcessHUD];
        NSString *codeString = request.gtResponseData[@"code"];
        // TODO:请求成功处理
    } failure:^(__kindof GTRequest *request) {
        [hud hideProcessHUD];
        NSLog(@"%@", request.error);
    }];
}