def __generateArray(module, folder): selffolder = folder + "/NSArray" if xxnetos.mkdir(selffolder) == False: return False filename = "NSArray+$MODULE$NetworkingMethods" h_content = """// // NSArray+$MODULE$NetworkingMethods.h // $MODULE$Networking // // Created by JoeXu on 2018/4/24. // Copyright © 2018年 JoeXu. All rights reserved. // #import <Foundation/Foundation.h> @interface NSArray ($MODULE$NetworkingMethods) - (NSString *)$MODULE$_jsonString; @end """ m_content = """// // NSArray+$MODULE$NetworkingMethods.m // $MODULE$Networking // // Created by JoeXu on 2018/4/24. // Copyright © 2018年 JoeXu. All rights reserved. // #import "NSArray+$MODULE$NetworkingMethods.h" @implementation NSArray ($MODULE$NetworkingMethods) /** 数组变json */ - (NSString *)$MODULE$_jsonString { NSData *jsonData = [NSJSONSerialization dataWithJSONObject:self options:NSJSONWritingPrettyPrinted error:NULL]; return [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]; } @end """ xxnetos.mkclass(h_content, m_content, filename, module, "$MODULE$", selffolder)
def __generateFactory(module, folder): filename = "$MODULE$ServiceFactory" h_content = """// // AXServiceFactory.h // RTNetworking // // Created by casa on 14-5-12. // Copyright (c) 2014年 casatwy. All rights reserved. // #import <Foundation/Foundation.h> #import "$MODULE$ServiceProtocol.h" @interface $MODULE$ServiceFactory : NSObject + (instancetype)sharedInstance; - (id <$MODULE$ServiceProtocol>)serviceWithIdentifier:(NSString *)identifier; @end """ m_content = """// // AXServiceFactory.m // RTNetworking // // Created by casa on 14-5-12. // Copyright (c) 2014年 casatwy. All rights reserved. // #import "$MODULE$ServiceFactory.h" #import "$MODULE$DemoService.h" /*************************************************************************/ @interface $MODULE$ServiceFactory () @property (nonatomic, strong) NSMutableDictionary *serviceStorage; @end @implementation $MODULE$ServiceFactory #pragma mark - getters and setters - (NSMutableDictionary *)serviceStorage { if (_serviceStorage == nil) { _serviceStorage = [[NSMutableDictionary alloc] init]; } return _serviceStorage; } #pragma mark - life cycle + (instancetype)sharedInstance { static dispatch_once_t onceToken; static $MODULE$ServiceFactory *sharedInstance; dispatch_once(&onceToken, ^{ sharedInstance = [[$MODULE$ServiceFactory alloc] init]; }); return sharedInstance; } #pragma mark - public methods - (id <$MODULE$ServiceProtocol>)serviceWithIdentifier:(NSString *)identifier { if (self.serviceStorage[identifier] == nil) { self.serviceStorage[identifier] = [self newServiceWithIdentifier:identifier]; } return self.serviceStorage[identifier]; } #pragma mark - private methods - (id <$MODULE$ServiceProtocol>)newServiceWithIdentifier:(NSString *)identifier { //demo service return [[$MODULE$DemoService alloc] init]; } @end """ xxnetos.mkclass(h_content, m_content, filename, module, "$MODULE$", folder)
def __generateURLResponse(module, folder): selffolder = folder + "/URLResponse" if xxnetos.mkdir(selffolder) == False: return False filename = "$MODULE$URLResponse" h_content = """// // AXURLResponse.h // RTNetworking // // Created by casa on 14-5-18. // Copyright (c) 2014年 casatwy. All rights reserved. // #import <Foundation/Foundation.h> typedef NS_ENUM(NSUInteger, $MODULE$URLResponseStatus) { $MODULE$URLResponseStatusSuccess, //作为底层,请求是否成功只考虑是否成功收到服务器反馈。至于签名是否正确,返回的数据是否完整,由上层的$MODULE$APIBaseManager来决定。 $MODULE$URLResponseStatusErrorTimeout, $MODULE$URLResponseStatusErrorCancel, $MODULE$URLResponseStatusErrorNoNetwork // 默认除了超时以外的错误都是无网络错误。 }; @interface $MODULE$URLResponse : NSObject @property (nonatomic, assign, readonly) $MODULE$URLResponseStatus status; @property (nonatomic, copy, readonly) NSString *contentString; @property (nonatomic, copy, readonly) NSDictionary *content; @property (nonatomic, assign, readonly) NSInteger requestId; @property (nonatomic, copy, readonly) NSURLRequest *request; @property (nonatomic, copy, readonly) NSData *responseData; @property (nonatomic, strong, readonly) NSString *errorMessage; @property (nonatomic, copy) NSDictionary *acturlRequestParams; @property (nonatomic, copy) NSDictionary *originRequestParams; @property (nonatomic, strong) NSString *logString; @property (nonatomic, assign, readonly) BOOL isCache; - (instancetype)initWithResponseString:(NSString *)responseString requestId:(NSNumber *)requestId request:(NSURLRequest *)request responseContent:(NSDictionary *)responseContent error:(NSError *)error; // 使用initWithData的response,它的isCache是YES,上面两个函数生成的response的isCache是NO - (instancetype)initWithData:(NSData *)data; @end """ m_content = """// // AXURLResponse.m // RTNetworking // // Created by casa on 14-5-18. // Copyright (c) 2014年 casatwy. All rights reserved. // #import "$MODULE$URLResponse.h" #import "NSObject+$MODULE$NetworkingMethods.h" #import "NSURLRequest+$MODULE$NetworkingMethods.h" @interface $MODULE$URLResponse () @property (nonatomic, assign, readwrite) $MODULE$URLResponseStatus status; @property (nonatomic, copy, readwrite) NSString *contentString; @property (nonatomic, copy, readwrite) id content; @property (nonatomic, copy, readwrite) NSURLRequest *request; @property (nonatomic, assign, readwrite) NSInteger requestId; @property (nonatomic, copy, readwrite) NSData *responseData; @property (nonatomic, assign, readwrite) BOOL isCache; @property (nonatomic, strong, readwrite) NSString *errorMessage; @end @implementation $MODULE$URLResponse #pragma mark - life cycle - (instancetype)initWithResponseString:(NSString *)responseString requestId:(NSNumber *)requestId request:(NSURLRequest *)request responseContent:(NSDictionary *)responseContent error:(NSError *)error { self = [super init]; if (self) { self.contentString = [responseString $MODULE$_defaultValue:@""]; self.requestId = [requestId integerValue]; self.request = request; self.acturlRequestParams = request.actualRequestParams; self.originRequestParams = request.originRequestParams; self.isCache = NO; self.status = [self responseStatusWithError:error]; self.content = responseContent ? responseContent : @{}; self.errorMessage = [NSString stringWithFormat:@"%@", error]; } return self; } - (instancetype)initWithData:(NSData *)data { self = [super init]; if (self) { self.contentString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; self.status = [self responseStatusWithError:nil]; self.requestId = 0; self.request = nil; self.responseData = data; self.content = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:NULL]; self.isCache = YES; } return self; } #pragma mark - private methods - ($MODULE$URLResponseStatus)responseStatusWithError:(NSError *)error { if (error) { $MODULE$URLResponseStatus result = $MODULE$URLResponseStatusErrorNoNetwork; // 除了超时以外,所有错误都当成是无网络 if (error.code == NSURLErrorTimedOut) { result = $MODULE$URLResponseStatusErrorTimeout; } if (error.code == NSURLErrorCancelled) { result = $MODULE$URLResponseStatusErrorCancel; } if (error.code == NSURLErrorNotConnectedToInternet) { result = $MODULE$URLResponseStatusErrorNoNetwork; } return result; } else { return $MODULE$URLResponseStatusSuccess; } } #pragma mark - getters and setters - (NSData *)responseData { if (_responseData == nil) { NSError *error = nil; _responseData = [NSJSONSerialization dataWithJSONObject:self.content options:0 error:&error]; if (error) { _responseData = [@"" dataUsingEncoding:NSUTF8StringEncoding]; } } return _responseData; } @end """ xxnetos.mkclass(h_content, m_content, filename, module, "$MODULE$", selffolder)
def __generateAPIBaseManager(module, folder): selffolder = folder + "/APIBaseManager" if xxnetos.mkdir(selffolder) == False: return False filename = "$MODULE$APIBaseManager" h_content = """// // AJKBaseManager.h // casatwy2 // // Created by casa on 13-12-2. // Copyright (c) 2013年 casatwy inc. All rights reserved. // #import <Foundation/Foundation.h> #import "$MODULE$URLResponse.h" #import "$MODULE$NetworkingDefines.h" @interface $MODULE$APIBaseManager : NSObject <NSCopying> // outter functions @property (nonatomic, weak) id <$MODULE$APIManagerCallBackDelegate> _Nullable delegate; @property (nonatomic, weak) id <$MODULE$APIManagerParamSource> _Nullable paramSource; @property (nonatomic, weak) id <$MODULE$APIManagerValidator> _Nullable validator; @property (nonatomic, weak) NSObject<$MODULE$APIManager> * _Nullable child; //里面会调用到NSObject的方法,所以这里不用id @property (nonatomic, weak) id <$MODULE$APIManagerInterceptor> _Nullable interceptor; // response @property (nonatomic, strong) $MODULE$URLResponse * _Nonnull response; @property (nonatomic, readonly) $MODULE$APIManagerErrorType errorType; @property (nonatomic, copy, readonly) NSString * _Nullable errorMessage; // before loading @property (nonatomic, assign, readonly) BOOL isReachable; @property (nonatomic, assign, readonly) BOOL isLoading; // start - (NSInteger)loadData; + (NSInteger)loadDataWithParams:(NSDictionary * _Nullable)params success:(void (^ _Nullable)($MODULE$APIBaseManager * _Nonnull apiManager))successCallback fail:(void (^ _Nullable)($MODULE$APIBaseManager * _Nonnull apiManager))failCallback; // cancel - (void)cancelAllRequests; - (void)cancelRequestWithRequestId:(NSInteger)requestID; // finish - (id _Nullable )fetchDataWithReformer:(id <$MODULE$APIManagerDataReformer> _Nullable)reformer; - (void)cleanData; @end @interface $MODULE$APIBaseManager (InnerInterceptor) - (BOOL)beforePerformSuccessWithResponse:($MODULE$URLResponse *_Nullable)response; - (void)afterPerformSuccessWithResponse:($MODULE$URLResponse *_Nullable)response; - (BOOL)beforePerformFailWithResponse:($MODULE$URLResponse *_Nullable)response; - (void)afterPerformFailWithResponse:($MODULE$URLResponse *_Nullable)response; - (BOOL)shouldCallAPIWithParams:(NSDictionary *_Nullable)params; - (void)afterCallingAPIWithParams:(NSDictionary *_Nullable)params; @end """ m_content = """// // AJKBaseManager.m // casatwy2 // // Created by casa on 13-12-2. // Copyright (c) 2013年 casatwy inc. All rights reserved. // #import "$MODULE$APIBaseManager.h" #import "NSURLRequest+$MODULE$NetworkingMethods.h" #import "$MODULE$Logger.h" #import "$MODULE$ServiceFactory.h" #import "$MODULE$ApiProxy.h" NSString * const k$MODULE$UserTokenInvalidNotification = @"k$MODULE$UserTokenInvalidNotification"; NSString * const k$MODULE$UserTokenIllegalNotification = @"k$MODULE$UserTokenIllegalNotification"; NSString * const k$MODULE$UserTokenNotificationUserInfoKeyManagerToContinue = @"k$MODULE$UserTokenNotificationUserInfoKeyManagerToContinue"; NSString * const k$MODULE$APIBaseManagerRequestID = @"k$MODULE$APIBaseManagerRequestID"; @interface $MODULE$APIBaseManager () @property (nonatomic, strong, readwrite) id fetchedRawData; @property (nonatomic, assign, readwrite) BOOL isLoading; @property (nonatomic, copy, readwrite) NSString *errorMessage; @property (nonatomic, readwrite) $MODULE$APIManagerErrorType errorType; @property (nonatomic, strong) NSMutableArray *requestIdList; @property (nonatomic, strong, nullable) void (^successBlock)($MODULE$APIBaseManager *apimanager); @property (nonatomic, strong, nullable) void (^failBlock)($MODULE$APIBaseManager *apimanager); @end @implementation $MODULE$APIBaseManager #pragma mark - life cycle - (instancetype)init { self = [super init]; if (self) { _delegate = nil; _validator = nil; _paramSource = nil; _fetchedRawData = nil; _errorMessage = nil; _errorType = $MODULE$APIManagerErrorTypeDefault; if ([self conformsToProtocol:@protocol($MODULE$APIManager)]) { self.child = (id <$MODULE$APIManager>)self; } else { NSException *exception = [[NSException alloc] init]; @throw exception; } } return self; } - (void)dealloc { [self cancelAllRequests]; self.requestIdList = nil; } #pragma mark - NSCopying - (id)copyWithZone:(NSZone *)zone { return self; } #pragma mark - public methods - (void)cancelAllRequests { [[$MODULE$ApiProxy sharedInstance] cancelRequestWithRequestIDList:self.requestIdList]; [self.requestIdList removeAllObjects]; } - (void)cancelRequestWithRequestId:(NSInteger)requestID { [self removeRequestIdWithRequestID:requestID]; [[$MODULE$ApiProxy sharedInstance] cancelRequestWithRequestID:@(requestID)]; } - (id)fetchDataWithReformer:(id<$MODULE$APIManagerDataReformer>)reformer { id resultData = nil; if ([reformer respondsToSelector:@selector(manager:reformData:)]) { resultData = [reformer manager:self reformData:self.fetchedRawData]; } else { resultData = [self.fetchedRawData mutableCopy]; } return resultData; } #pragma mark - calling api - (NSInteger)loadData { NSDictionary *params = [self.paramSource paramsForApi:self]; NSInteger requestId = [self loadDataWithParams:params]; return requestId; } + (NSInteger)loadDataWithParams:(NSDictionary *)params success:(void (^)($MODULE$APIBaseManager *))successCallback fail:(void (^)($MODULE$APIBaseManager *))failCallback { return [[[self alloc] init] loadDataWithParams:params success:successCallback fail:failCallback]; } - (NSInteger)loadDataWithParams:(NSDictionary *)params success:(void (^)($MODULE$APIBaseManager *))successCallback fail:(void (^)($MODULE$APIBaseManager *))failCallback { self.successBlock = successCallback; self.failBlock = failCallback; return [self loadDataWithParams:params]; } - (NSInteger)loadDataWithParams:(NSDictionary *)params { NSInteger requestId = 0; NSDictionary *reformedParams = [self reformParams:params]; if (reformedParams == nil) { reformedParams = @{}; } if ([self shouldCallAPIWithParams:reformedParams]) { $MODULE$APIManagerErrorType errorType = [self.validator manager:self isCorrectWithParamsData:reformedParams]; if (errorType == $MODULE$APIManagerErrorTypeNoError) { $MODULE$URLResponse *response = nil; // 先检查一下是否有内存缓存 // 再检查是否有磁盘缓存 //为什么要缓存??? if (response != nil) { [self successedOnCallingAPI:response]; return 0; } // 实际的网络请求 if ([self isReachable]) { self.isLoading = YES; id <$MODULE$ServiceProtocol> service = [[$MODULE$ServiceFactory sharedInstance] serviceWithIdentifier:self.child.serviceIdentifier]; NSURLRequest *request = [service requestWithParams:reformedParams methodName:self.child.methodName requestType:self.child.requestType]; request.service = service; [$MODULE$Logger logDebugInfoWithRequest:request apiName:self.child.methodName service:service]; NSNumber *requestId = [[$MODULE$ApiProxy sharedInstance] callApiWithRequest:request success:^($MODULE$URLResponse *response) { [self successedOnCallingAPI:response]; } fail:^($MODULE$URLResponse *response) { $MODULE$APIManagerErrorType errorType = $MODULE$APIManagerErrorTypeDefault; if (response.status == $MODULE$URLResponseStatusErrorCancel) { errorType = $MODULE$APIManagerErrorTypeCanceled; } if (response.status == $MODULE$URLResponseStatusErrorTimeout) { errorType = $MODULE$APIManagerErrorTypeTimeout; } if (response.status == $MODULE$URLResponseStatusErrorNoNetwork) { errorType = $MODULE$APIManagerErrorTypeNoNetWork; } [self failedOnCallingAPI:response withErrorType:errorType]; }]; [self.requestIdList addObject:requestId]; NSMutableDictionary *params = [reformedParams mutableCopy]; params[k$MODULE$APIBaseManagerRequestID] = requestId; [self afterCallingAPIWithParams:params]; return [requestId integerValue]; } else { [self failedOnCallingAPI:nil withErrorType:$MODULE$APIManagerErrorTypeNoNetWork]; return requestId; } } else { [self failedOnCallingAPI:nil withErrorType:errorType]; return requestId; } } return requestId; } #pragma mark - api callbacks - (void)successedOnCallingAPI:($MODULE$URLResponse *)response { self.isLoading = NO; self.response = response; if (response.content) { self.fetchedRawData = [response.content copy]; } else { self.fetchedRawData = [response.responseData copy]; } [self removeRequestIdWithRequestID:response.requestId]; $MODULE$APIManagerErrorType errorType = [self.validator manager:self isCorrectWithCallBackData:response.content]; if (errorType == $MODULE$APIManagerErrorTypeNoError) { //先缓存??? if ([self.interceptor respondsToSelector:@selector(manager:didReceiveResponse:)]) { [self.interceptor manager:self didReceiveResponse:response]; } if ([self beforePerformSuccessWithResponse:response]) { dispatch_async(dispatch_get_main_queue(), ^{ if ([self.delegate respondsToSelector:@selector(managerCallAPIDidSuccess:)]) { [self.delegate managerCallAPIDidSuccess:self]; } if (self.successBlock) { self.successBlock(self); } }); } [self afterPerformSuccessWithResponse:response]; } else { [self failedOnCallingAPI:response withErrorType:errorType]; } } - (void)failedOnCallingAPI:($MODULE$URLResponse *)response withErrorType:($MODULE$APIManagerErrorType)errorType { self.isLoading = NO; if (response) { self.response = response; } self.errorType = errorType; [self removeRequestIdWithRequestID:response.requestId]; // user token 无效,重新登录 if (errorType == $MODULE$APIManagerErrorTypeNeedLogin) { [[NSNotificationCenter defaultCenter] postNotificationName:k$MODULE$UserTokenIllegalNotification object:nil userInfo:@{ k$MODULE$UserTokenNotificationUserInfoKeyManagerToContinue:self }]; return; } NSString *resCode = [NSString stringWithFormat:@"%@", response.content[@"resCode"]]; if ([resCode isEqualToString:@"00100009"] || [resCode isEqualToString:@"05111001"] || [resCode isEqualToString:@"05111002"] || [resCode isEqualToString:@"1080002"] ) { [[NSNotificationCenter defaultCenter] postNotificationName:k$MODULE$UserTokenIllegalNotification object:nil userInfo:@{ k$MODULE$UserTokenNotificationUserInfoKeyManagerToContinue:self }]; return; } // 可以自动处理的错误 if (errorType == $MODULE$APIManagerErrorTypeNeedAccessToken) { [[NSNotificationCenter defaultCenter] postNotificationName:k$MODULE$UserTokenInvalidNotification object:nil userInfo:@{ k$MODULE$UserTokenNotificationUserInfoKeyManagerToContinue:self }]; return; } NSString *errorCode = [NSString stringWithFormat:@"%@", response.content[@"errorCode"]]; if ([response.content[@"errorMsg"] isEqualToString:@"invalid token"] || [response.content[@"errorMsg"] isEqualToString:@"access_token is required"] || [errorCode isEqualToString:@"BL10015"] ) { // token 失效 [[NSNotificationCenter defaultCenter] postNotificationName:k$MODULE$UserTokenInvalidNotification object:nil userInfo:@{ k$MODULE$UserTokenNotificationUserInfoKeyManagerToContinue:self }]; return; } // 常规错误 if (errorType == $MODULE$APIManagerErrorTypeNoNetWork) { self.errorMessage = @"无网络连接,请检查网络"; } if (errorType == $MODULE$APIManagerErrorTypeTimeout) { self.errorMessage = @"请求超时"; } if (errorType == $MODULE$APIManagerErrorTypeCanceled) { self.errorMessage = @"您已取消"; } if (errorType == $MODULE$APIManagerErrorTypeDownGrade) { self.errorMessage = @"网络拥塞"; } // 其他错误 dispatch_async(dispatch_get_main_queue(), ^{ if ([self.interceptor respondsToSelector:@selector(manager:didReceiveResponse:)]) { [self.interceptor manager:self didReceiveResponse:response]; } if ([self beforePerformFailWithResponse:response]) { [self.delegate managerCallAPIDidFailed:self]; } if (self.failBlock) { self.failBlock(self); } [self afterPerformFailWithResponse:response]; }); } #pragma mark - method for interceptor /* 拦截器的功能可以由子类通过继承实现,也可以由其它对象实现,两种做法可以共存 当两种情况共存的时候,子类重载的方法一定要调用一下super 然后它们的调用顺序是BaseManager会先调用子类重载的实现,再调用外部interceptor的实现 notes: 正常情况下,拦截器是通过代理的方式实现的,因此可以不需要以下这些代码 但是为了将来拓展方便,如果在调用拦截器之前manager又希望自己能够先做一些事情,所以这些方法还是需要能够被继承重载的 所有重载的方法,都要调用一下super,这样才能保证外部interceptor能够被调到 这就是decorate pattern */ - (BOOL)beforePerformSuccessWithResponse:($MODULE$URLResponse *)response { BOOL result = YES; self.errorType = $MODULE$APIManagerErrorTypeSuccess; if ((NSInteger)self != (NSInteger)self.interceptor && [self.interceptor respondsToSelector:@selector(manager: beforePerformSuccessWithResponse:)]) { result = [self.interceptor manager:self beforePerformSuccessWithResponse:response]; } return result; } - (void)afterPerformSuccessWithResponse:($MODULE$URLResponse *)response { if ((NSInteger)self != (NSInteger)self.interceptor && [self.interceptor respondsToSelector:@selector(manager:afterPerformSuccessWithResponse:)]) { [self.interceptor manager:self afterPerformSuccessWithResponse:response]; } } - (BOOL)beforePerformFailWithResponse:($MODULE$URLResponse *)response { BOOL result = YES; if ((NSInteger)self != (NSInteger)self.interceptor && [self.interceptor respondsToSelector:@selector(manager:beforePerformFailWithResponse:)]) { result = [self.interceptor manager:self beforePerformFailWithResponse:response]; } return result; } - (void)afterPerformFailWithResponse:($MODULE$URLResponse *)response { if ((NSInteger)self != (NSInteger)self.interceptor && [self.interceptor respondsToSelector:@selector(manager:afterPerformFailWithResponse:)]) { [self.interceptor manager:self afterPerformFailWithResponse:response]; } } //只有返回YES才会继续调用API - (BOOL)shouldCallAPIWithParams:(NSDictionary *)params { if ((NSInteger)self != (NSInteger)self.interceptor && [self.interceptor respondsToSelector:@selector(manager:shouldCallAPIWithParams:)]) { return [self.interceptor manager:self shouldCallAPIWithParams:params]; } else { return YES; } } - (void)afterCallingAPIWithParams:(NSDictionary *)params { if ((NSInteger)self != (NSInteger)self.interceptor && [self.interceptor respondsToSelector:@selector(manager:afterCallingAPIWithParams:)]) { [self.interceptor manager:self afterCallingAPIWithParams:params]; } } #pragma mark - method for child - (void)cleanData { self.fetchedRawData = nil; self.errorType = $MODULE$APIManagerErrorTypeDefault; } //如果需要在调用API之前额外添加一些参数,比如pageNumber和pageSize之类的就在这里添加 //子类中覆盖这个函数的时候就不需要调用[super reformParams:params]了 - (NSDictionary *)reformParams:(NSDictionary *)params { IMP childIMP = [self.child methodForSelector:@selector(reformParams:)]; IMP selfIMP = [self methodForSelector:@selector(reformParams:)]; if (childIMP == selfIMP) { return params; } else { // 如果child是继承得来的,那么这里就不会跑到,会直接跑子类中的IMP。 // 如果child是另一个对象,就会跑到这里 NSDictionary *result = nil; result = [self.child reformParams:params]; if (result) { return result; } else { return params; } } } #pragma mark - private methods - (void)removeRequestIdWithRequestID:(NSInteger)requestId { NSNumber *requestIDToRemove = nil; for (NSNumber *storedRequestId in self.requestIdList) { if ([storedRequestId integerValue] == requestId) { requestIDToRemove = storedRequestId; } } if (requestIDToRemove) { [self.requestIdList removeObject:requestIDToRemove]; } } #pragma mark - getters and setters - (NSMutableArray *)requestIdList { if (_requestIdList == nil) { _requestIdList = [[NSMutableArray alloc] init]; } return _requestIdList; } - (BOOL)isReachable { return YES; // BOOL isReachability = [[$MODULE$Mediator sharedInstance] $MODULE$Networking_isReachable]; // if (!isReachability) { // self.errorType = $MODULE$APIManagerErrorTypeNoNetWork; // } // return isReachability; } - (BOOL)isLoading { if (self.requestIdList.count == 0) { _isLoading = NO; } return _isLoading; } @end """ xxnetos.mkclass(h_content, m_content, filename, module, "$MODULE$", selffolder)
def __generateLog(module, folder): selffolder = folder + "/Log" if xxnetos.mkdir(selffolder) == False: return False filename = "$MODULE$Logger" h_content = """// // $MODULE$Logger.h // $MODULE$Networking // // Created by JoeXu on 2018/4/24. // Copyright © 2018年 JoeXu. All rights reserved. // #import <Foundation/Foundation.h> #import "$MODULE$URLResponse.h" #import "$MODULE$ServiceProtocol.h" @interface $MODULE$Logger : NSObject + (NSString *)logDebugInfoWithRequest:(NSURLRequest *)request apiName:(NSString *)apiName service:(id <$MODULE$ServiceProtocol>)service; + (NSString *)logDebugInfoWithResponse:(NSHTTPURLResponse *)response rawResponseData:(NSData *)rawResponseData responseString:(NSString *)responseString request:(NSURLRequest *)request error:(NSError *)error; + (NSString *)logDebugInfoWithCachedResponse:($MODULE$URLResponse *)response methodName:(NSString *)methodName service:(id <$MODULE$ServiceProtocol>)service params:(NSDictionary *)params; @end """ m_content = """// // $MODULE$Logger.m // $MODULE$Networking // // Created by JoeXu on 2018/4/24. // Copyright © 2018年 JoeXu. All rights reserved. // #import "$MODULE$Logger.h" #import "NSObject+$MODULE$NetworkingMethods.h" #import "NSMutableString+$MODULE$NetworkingMethods.h" #import "NSArray+$MODULE$NetworkingMethods.h" #import "NSURLRequest+$MODULE$NetworkingMethods.h" #import "NSDictionary+$MODULE$NetworkingMethods.h" @implementation $MODULE$Logger + (NSString *)logDebugInfoWithRequest:(NSURLRequest *)request apiName:(NSString *)apiName service:(id <$MODULE$ServiceProtocol>)service { NSMutableString *logString = nil; #ifdef DEBUG // if ([$MODULE$Mediator sharedInstance].$MODULE$Networking_shouldPrintNetworkingLog == NO) { // return @""; // } $MODULE$ServiceAPIEnvironment enviroment = request.service.apiEnvironment; NSString *enviromentString = nil; if (enviroment == $MODULE$ServiceAPIEnvironmentDevelop) { enviromentString = @"Develop"; } if (enviroment == $MODULE$ServiceAPIEnvironmentReleaseCandidate) { enviromentString = @"Pre Release"; } if (enviroment == $MODULE$ServiceAPIEnvironmentRelease) { enviromentString = @"Release"; } logString = [NSMutableString stringWithString:@"\\n\\n********************************************************\\nRequest Start\\n********************************************************\\n\\n"]; [logString appendFormat:@"API Name:\\t\\t%@\\n", [apiName $MODULE$_defaultValue:@"N/A"]]; [logString appendFormat:@"Method:\\t\\t\\t%@\\n", request.HTTPMethod]; [logString appendFormat:@"Service:\\t\\t%@\\n", [service class]]; [logString appendFormat:@"Status:\\t\\t\\t%@\\n", enviromentString]; [logString appendURLRequest:request]; [logString appendFormat:@"\\n\\n********************************************************\\nRequest End\\n********************************************************\\n\\n\\n\\n"]; NSLog(@"%@", logString); #endif return logString; } + (NSString *)logDebugInfoWithResponse:(NSHTTPURLResponse *)response rawResponseData:(NSData *)rawResponseData responseString:(NSString *)responseString request:(NSURLRequest *)request error:(NSError *)error { NSMutableString *logString = nil; #ifdef DEBUG // if ([$MODULE$Mediator sharedInstance].$MODULE$Networking_shouldPrintNetworkingLog == NO) { // return @""; // } BOOL isSuccess = error ? NO : YES; logString = [NSMutableString stringWithString:@"\\n\\n=========================================\\nAPI Response\\n=========================================\\n\\n"]; [logString appendFormat:@"Status:\\t%ld\\t(%@)\\n\\n", (long)response.statusCode, [NSHTTPURLResponse localizedStringForStatusCode:response.statusCode]]; [logString appendFormat:@"Content:\\n\\t%@\\n\\n", responseString]; [logString appendFormat:@"Request URL:\\n\\t%@\\n\\n", request.URL]; [logString appendFormat:@"Request Data:\\n\\t%@\\n\\n",request.originRequestParams.$MODULE$_jsonString]; [logString appendFormat:@"Raw Response String:\\n\\t%@\\n\\n", [[NSString alloc] initWithData:rawResponseData encoding:NSUTF8StringEncoding]]; [logString appendFormat:@"Raw Response Header:\\n\\t%@\\n\\n", response.allHeaderFields]; if (isSuccess == NO) { [logString appendFormat:@"Error Domain:\\t\\t\\t\\t\\t\\t\\t%@\\n", error.domain]; [logString appendFormat:@"Error Domain Code:\\t\\t\\t\\t\\t\\t%ld\\n", (long)error.code]; [logString appendFormat:@"Error Localized Description:\\t\\t\\t%@\\n", error.localizedDescription]; [logString appendFormat:@"Error Localized Failure Reason:\\t\\t\\t%@\\n", error.localizedFailureReason]; [logString appendFormat:@"Error Localized Recovery Suggestion:\\t%@\\n\\n", error.localizedRecoverySuggestion]; } [logString appendString:@"\\n--------------- Related Request Content --------------\\n"]; [logString appendURLRequest:request]; [logString appendFormat:@"\\n\\n=========================================\\nResponse End\\n=========================================\\n\\n"]; NSLog(@"%@", logString); #endif return logString; } +(NSString *)logDebugInfoWithCachedResponse:($MODULE$URLResponse *)response methodName:(NSString *)methodName service:(id <$MODULE$ServiceProtocol>)service params:(NSDictionary *)params { NSMutableString *logString = nil; #ifdef DEBUG // if ([$MODULE$Mediator sharedInstance].$MODULE$Networking_shouldPrintNetworkingLog == NO) { // return @""; // } logString = [NSMutableString stringWithString:@"\\n\\n=========================================\\nCached Response \\n=========================================\\n\\n"]; [logString appendFormat:@"API Name:\\t\\t%@\\n", [methodName $MODULE$_defaultValue:@"N/A"]]; [logString appendFormat:@"Service:\\t\\t%@\\n", [service class]]; [logString appendFormat:@"Method Name:\\t%@\\n", methodName]; [logString appendFormat:@"Params:\\n%@\\n\\n", params]; [logString appendFormat:@"Origin Params:\\n%@\\n\\n", response.originRequestParams]; [logString appendFormat:@"A$MODULE$ual Params:\\n%@\\n\\n", response.acturlRequestParams]; [logString appendFormat:@"Content:\\n\\t%@\\n\\n", response.contentString]; [logString appendFormat:@"\\n\\n=========================================\\nResponse End\\n=========================================\\n\\n"]; NSLog(@"%@", logString); #endif return logString; } @end """ xxnetos.mkclass(h_content, m_content, filename, module, "$MODULE$", selffolder)
def __generateGroupRequest(module, folder): selffolder = folder + "/APIProxy" filename = "$MODULE$GroupRequest" h_content = """// // $MODULE$Networking // // Created by JoeXu on 2018/4/26. // Copyright © 2018年 JoeXu. All rights reserved. // #import <Foundation/Foundation.h> #import "$MODULE$APIProxy.h" @interface $MODULE$GroupRequest : NSObject - (instancetype)init NS_UNAVAILABLE; - (instancetype)initWithURLRequest:(NSURLRequest *)request; - ($MODULE$GroupRequest *(^)(NSURLRequest *req))link; /**迭代器 */ - (void)resetIndex; - (NSURLRequest *)nextUrlRequest; /**给个机会重置参数 返回值: 根据response 期望的下一级request */ @property (nonatomic,copy) NSURLRequest *(^aRequestSuccess)($MODULE$URLResponse *response,NSURLRequest *request); @property (nonatomic,copy) void(^aRequestFailure)($MODULE$URLResponse *response,NSURLRequest *request); - ($MODULE$URLResponse *)responseOfCacheForRequest:(NSURLRequest *)request; - (void)cleanCache; @end @interface $MODULE$ApiProxy (ApiLinker) - (void)callApiWithGroupRequest:($MODULE$GroupRequest *)request success:($MODULE$Callback)success fail:($MODULE$Callback)fail; - (void)cancleGroupRequest:($MODULE$GroupRequest *)request; @end """ m_content = """// // $MODULE$ApiLinker.m // $MODULE$Networking // // Created by JoeXu on 2018/4/26. // Copyright © 2018年 JoeXu. All rights reserved. // #import "$MODULE$GroupRequest.h" #import "$MODULE$URLResponse.h" @interface __$MODULE$GroupRequestTuple: NSObject{ @package NSNumber *_taskID; } @property (nonatomic,strong) NSURLRequest *request; @property (nonatomic,strong) $MODULE$URLResponse *response; @end @implementation __$MODULE$GroupRequestTuple @end @interface $MODULE$GroupRequest() @property (nonatomic,strong) NSMutableArray<__$MODULE$GroupRequestTuple *> *req_respTable; @property (nonatomic,assign) int iterationIndex; @end @implementation $MODULE$GroupRequest - (instancetype)initWithURLRequest:(NSURLRequest *)request { if (!(self = [super init])) return self; self.link(request); self.iterationIndex = -1; return self; } - ($MODULE$GroupRequest *(^)(NSURLRequest *))link { __weak typeof(self) self_weak = self; return ^(NSURLRequest *req){ __strong typeof(self_weak) self_strong = self_weak; __$MODULE$GroupRequestTuple *tuple = [[__$MODULE$GroupRequestTuple alloc] init]; tuple.request = req.copy; [self_strong.req_respTable addObject:tuple]; return self_strong; }; } - (void)resetIndex { self.iterationIndex = -1; } - (NSURLRequest *)nextUrlRequest { int index = self.iterationIndex + 1; if (index >= self.req_respTable.count){ return nil; } NSURLRequest *result = [self.req_respTable[index] request]; if (result){ self.iterationIndex = index; } return result; } - ($MODULE$URLResponse *)responseOfCacheForRequest:(NSURLRequest *)request { for (__$MODULE$GroupRequestTuple *tuple in self.req_respTable) { if ([tuple isEqual:request]){ return tuple.response; } } return nil; } - (void)cleanCache { for (__$MODULE$GroupRequestTuple *tuple in self.req_respTable) { if (tuple.response){ tuple.response = nil; tuple->_taskID = nil; } } } - (void)__resetTaskID:(NSNumber *)taskID forRequese:(NSURLRequest *)urlRequest{ for (__$MODULE$GroupRequestTuple *tuple in self.req_respTable) { if ([tuple isEqual:urlRequest]){ tuple->_taskID = taskID; return; } } } - (NSMutableArray<__$MODULE$GroupRequestTuple *> *)req_respTable{ if (!_req_respTable) { _req_respTable = @[].mutableCopy; } return _req_respTable; } @end @implementation $MODULE$ApiProxy (ApiLinker) /** 递归 出队 urlrequest */ - (void)callApiWithGroupRequest:($MODULE$GroupRequest *)request success:($MODULE$Callback)success fail:($MODULE$Callback)fail { NSURLRequest *aReq = [request nextUrlRequest]; if (aReq == nil){ return; } $MODULE$Callback linkSuccess = ^($MODULE$URLResponse *response){ if (request.aRequestSuccess){ request.aRequestSuccess(response,aReq); } [self callApiWithGroupRequest:request success:success fail:fail]; }; $MODULE$Callback linkFail = ^($MODULE$URLResponse *response){ if (request.aRequestFailure){ request.aRequestFailure(response,aReq); } if (fail){fail(response);} }; $MODULE$URLResponse *aResp = [request responseOfCacheForRequest:aReq]; if (aResp && aResp.status == $MODULE$URLResponseStatusSuccess){ linkSuccess(aResp); }else{ NSNumber *taskID = [self callApiWithRequest:aReq success:linkSuccess fail:linkFail]; [request __resetTaskID:taskID forRequese:aReq]; } } - (void)cancleGroupRequest:($MODULE$GroupRequest *)request { for (__$MODULE$GroupRequestTuple *tuple in request.req_respTable) { if (tuple->_taskID){ [self cancelRequestWithRequestID:tuple->_taskID]; } } } @end """ xxnetos.mkclass(h_content, m_content, filename, module, "$MODULE$", selffolder)
def __generateAPIProxy(module, folder): selffolder = folder + "/APIProxy" if xxnetos.mkdir(selffolder) == False: return False filename = "$MODULE$APIProxy" h_content = """// // $MODULE$APIProxy.h // $MODULE$Networking // // Created by JoeXu on 2018/4/24. // Copyright © 2018年 JoeXu. All rights reserved. // #import <Foundation/Foundation.h> #import "$MODULE$NetworkingDefines.h" typedef void(^$MODULE$Callback)($MODULE$URLResponse *response); @interface $MODULE$ApiProxy : NSObject $MODULE$_SINGLETON_DEF($MODULE$ApiProxy); - (NSNumber *)callApiWithRequest:(NSURLRequest *)request success:($MODULE$Callback)success fail:($MODULE$Callback)fail; - (void)cancelRequestWithRequestID:(NSNumber *)requestID; - (void)cancelRequestWithRequestIDList:(NSArray *)requestIDList; @end """ m_content = """// // $MODULE$APIProxy.m // $MODULE$Networking // // Created by JoeXu on 2018/4/24. // Copyright © 2018年 JoeXu. All rights reserved. // #import "$MODULE$APIProxy.h" #import <AFNetworking/AFNetworking.h> #import "$MODULE$URLResponse.h" #import "$MODULE$Logger.h" #import "$MODULE$ServiceFactory.h" #import "NSURLRequest+$MODULE$NetworkingMethods.h" #import "NSString+$MODULE$NetworkingMethods.h" #import "NSObject+$MODULE$NetworkingMethods.h" static NSString * const kAXApiProxyDispatchItemKeyCallbackSuccess = @"kAXApiProxyDispatchItemCallbackSuccess"; static NSString * const kAXApiProxyDispatchItemKeyCallbackFail = @"kAXApiProxyDispatchItemCallbackFail"; NSString * const k$MODULE$ApiProxyValidateResultKeyResponseJSONObject = @"k$MODULE$ApiProxyValidateResultKeyResponseJSONObject"; NSString * const k$MODULE$ApiProxyValidateResultKeyResponseJSONString = @"k$MODULE$ApiProxyValidateResultKeyResponseJSONString"; NSString * const k$MODULE$ApiProxyValidateResultKeyResponseData = @"k$MODULE$ApiProxyValidateResultKeyResponseData"; @interface $MODULE$ApiProxy () @property (nonatomic, strong) NSMutableDictionary *dispatchTable; @property (nonatomic, strong) NSNumber *recordedRequestId; @property (nonatomic, strong) AFHTTPSessionManager *sessionManager; @end @implementation $MODULE$ApiProxy $MODULE$_SINGLETON_IMP($MODULE$ApiProxy); #pragma mark - getters and setters - (NSMutableDictionary *)dispatchTable { if (_dispatchTable == nil) { _dispatchTable = [[NSMutableDictionary alloc] init]; } return _dispatchTable; } - (AFHTTPSessionManager *)sessionManager { if (_sessionManager == nil) { _sessionManager = [AFHTTPSessionManager manager]; _sessionManager.responseSerializer = [AFHTTPResponseSerializer serializer]; _sessionManager.securityPolicy.allowInvalidCertificates = YES; _sessionManager.securityPolicy.validatesDomainName = NO; } return _sessionManager; } #pragma mark - public methods - (void)cancelRequestWithRequestID:(NSNumber *)requestID { NSURLSessionDataTask *requestOperation = self.dispatchTable[requestID]; [requestOperation cancel]; [self.dispatchTable removeObjectForKey:requestID]; } - (void)cancelRequestWithRequestIDList:(NSArray *)requestIDList { for (NSNumber *requestId in requestIDList) { [self cancelRequestWithRequestID:requestId]; } } /** 这个函数存在的意义在于,如果将来要把AFNetworking换掉,只要修改这个函数的实现即可。 */ - (NSNumber *)callApiWithRequest:(NSURLRequest *)request success:($MODULE$Callback)success fail:($MODULE$Callback)fail { // 跑到这里的block的时候,就已经是主线程了。 __block NSURLSessionDataTask *dataTask = nil; void (^completionHandler)(NSURLResponse *response, id _Nullable responseObject, NSError * _Nullable error) = ^(NSURLResponse * _Nonnull response, NSData * _Nullable responseData, NSError * _Nullable error) { NSNumber *requestID = @([dataTask taskIdentifier]); [self.dispatchTable removeObjectForKey:requestID]; NSDictionary *result = [request.service resultWithResponseData:responseData response:response request:request error:&error]; // 输出返回数据 $MODULE$URLResponse *$MODULE$Response = [[$MODULE$URLResponse alloc] initWithResponseString:result[k$MODULE$ApiProxyValidateResultKeyResponseJSONString] requestId:requestID request:request responseContent:result[k$MODULE$ApiProxyValidateResultKeyResponseJSONObject] error:error]; $MODULE$Response.logString = [$MODULE$Logger logDebugInfoWithResponse:(NSHTTPURLResponse *)response rawResponseData:responseData responseString:result[k$MODULE$ApiProxyValidateResultKeyResponseJSONString] request:request error:error]; if (error) { fail?fail($MODULE$Response):nil; } else { success?success($MODULE$Response):nil; } }; dataTask = [self.sessionManager dataTaskWithRequest:request uploadProgress:nil downloadProgress:nil completionHandler:completionHandler]; NSNumber *requestId = @([dataTask taskIdentifier]); self.dispatchTable[requestId] = dataTask; [dataTask resume]; return requestId; } @end """ xxnetos.mkclass(h_content, m_content, filename, module, "$MODULE$", selffolder)
def __generateDemoService(module, folder): filename = "$MODULE$DemoService" h_content = """// // $MODULE$DemoService.h // $MODULE$Networking // // Created by JoeXu on 2018/4/24. // Copyright © 2018年 JoeXu. All rights reserved. // #import <Foundation/Foundation.h> #import "$MODULE$ServiceProtocol.h" static NSString * const $MODULE$NetworkingDemoServiceIdentifier = @"DemoService"; @interface $MODULE$DemoService : NSObject<$MODULE$ServiceProtocol> @end """ m_content = """// // $MODULE$DemoService.m // $MODULE$Networking // // Created by JoeXu on 2018/4/24. // Copyright © 2018年 JoeXu. All rights reserved. // #import "$MODULE$DemoService.h" #import <AFNetworking/AFNetworking.h> #import "$MODULE$Networking.h" @interface $MODULE$DemoService () @property (nonatomic, strong) NSString *publicKey; @property (nonatomic, strong) NSString *privateKey; @property (nonatomic, strong) NSString *baseURL; @property (nonatomic, strong) AFHTTPRequestSerializer *httpRequestSerializer; @end @implementation $MODULE$DemoService #pragma mark - public methods - (NSURLRequest *)requestWithParams:(NSDictionary *)params methodName:(NSString *)methodName requestType:($MODULE$APIManagerRequestType)requestType { if (requestType == $MODULE$APIManagerRequestTypeGET) { NSString *urlString = [NSString stringWithFormat:@"%@/%@", self.baseURL, methodName]; NSString *tsString = [NSUUID UUID].UUIDString; NSString *md5Hash = [[NSString stringWithFormat:@"%@%@%@", tsString, self.privateKey, self.publicKey] $MODULE$_MD5]; NSMutableURLRequest *request = [self.httpRequestSerializer requestWithMethod:@"GET" URLString:urlString parameters:@{ @"apikey":self.publicKey, @"ts":tsString, @"hash":md5Hash } error:nil]; return request; } return nil; } - (NSDictionary *)resultWithResponseData:(NSData *)responseData response:(NSURLResponse *)response request:(NSURLRequest *)request error:(NSError **)error { NSMutableDictionary *result = [[NSMutableDictionary alloc] init]; result[k$MODULE$ApiProxyValidateResultKeyResponseData] = responseData; result[k$MODULE$ApiProxyValidateResultKeyResponseJSONString] = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding]; result[k$MODULE$ApiProxyValidateResultKeyResponseJSONObject] = [NSJSONSerialization JSONObjectWithData:responseData options:0 error:NULL]; return result; } #pragma mark - getters and setters - (NSString *)publicKey { return @"d97bab99fa506c7cdf209261ffd06652"; } - (NSString *)privateKey { return @"31bb736a11cbc10271517816540e626c4ff2279a"; } - (NSString *)baseURL { if (self.apiEnvironment == $MODULE$ServiceAPIEnvironmentRelease) { return @"https://gateway.marvel.com:443/v1"; } if (self.apiEnvironment == $MODULE$ServiceAPIEnvironmentDevelop) { return @"https://gateway.marvel.com:443/v1"; } if (self.apiEnvironment == $MODULE$ServiceAPIEnvironmentReleaseCandidate) { return @"https://gateway.marvel.com:443/v1"; } return @"https://gateway.marvel.com:443/v1"; } - ($MODULE$ServiceAPIEnvironment)apiEnvironment { return $MODULE$ServiceAPIEnvironmentRelease; } - (AFHTTPRequestSerializer *)httpRequestSerializer { if (_httpRequestSerializer == nil) { _httpRequestSerializer = [AFHTTPRequestSerializer serializer]; [_httpRequestSerializer setValue:@"application/json" forHTTPHeaderField:@"Content-Type"]; } return _httpRequestSerializer; } @synthesize apiEnvironment; @end """ xxnetos.mkclass(h_content, m_content, filename, module, "$MODULE$", folder)
def __generateDemoApiManager(module, folder): filename = "$MODULE$DemoAPIManager" h_content = """// // DemoAPIManager.h // $MODULE$Networking // // Created by JoeXu on 2018/4/24. // Copyright © 2018年 JoeXu. All rights reserved. // #import "$MODULE$APIBaseManager.h" #import "$MODULE$NetworkingDefines.h" @interface $MODULE$DemoAPIManager : $MODULE$APIBaseManager<$MODULE$APIManager> @end """ m_content = """// // DemoAPIManager.m // $MODULE$Networking // // Created by JoeXu on 2018/4/24. // Copyright © 2018年 JoeXu. All rights reserved. // #import "$MODULE$DemoAPIManager.h" #import "$MODULE$DemoService.h" @interface $MODULE$DemoAPIManager()<$MODULE$APIManagerParamSource,$MODULE$APIManagerValidator> @end @implementation $MODULE$DemoAPIManager - (instancetype)init{ if (!(self = [super init])) return self; self.paramSource = self; self.validator = self; return self; } #pragma mark - $MODULE$APIManager - (NSString *)methodName { return @"public/characters"; } - (NSString *)serviceIdentifier { return $MODULE$NetworkingDemoServiceIdentifier; } - ($MODULE$APIManagerRequestType)requestType { return $MODULE$APIManagerRequestTypeGET; } #pragma mark - $MODULE$APIManagerParamSource - (NSDictionary *)paramsForApi:($MODULE$APIBaseManager *)manager{ return nil; } #pragma mark - $MODULE$APIManagerValidator - ($MODULE$APIManagerErrorType)manager:($MODULE$APIBaseManager *)manager isCorrectWithParamsData:(NSDictionary *)data{ return $MODULE$APIManagerErrorTypeNoError; } - ($MODULE$APIManagerErrorType)manager:($MODULE$APIBaseManager *)manager isCorrectWithCallBackData:(NSDictionary *)data{ return $MODULE$APIManagerErrorTypeNoError; } @end """ xxnetos.mkclass(h_content, m_content, filename, module, "$MODULE$", folder)
def __generateURLRequest(module, folder): selffolder = folder + "/NSURLRequest" if xxnetos.mkdir(selffolder) == False: return False filename = "NSURLRequest+$MODULE$NetworkingMethods" h_content = """// // NSURLRequest+CTNetworkingMethods.h // RTNetworking // // Created by casa on 14-5-26. // Copyright (c) 2014年 casatwy. All rights reserved. // #import <Foundation/Foundation.h> #import "$MODULE$ServiceProtocol.h" @interface NSURLRequest ($MODULE$NetworkingMethods) @property (nonatomic, copy) NSDictionary *actualRequestParams; @property (nonatomic, copy) NSDictionary *originRequestParams; @property (nonatomic, strong) id <$MODULE$ServiceProtocol> service; @end """ m_content = """// // NSURLRequest+CTNetworkingMethods.m // RTNetworking // // Created by casa on 14-5-26. // Copyright (c) 2014年 casatwy. All rights reserved. // #import "NSURLRequest+$MODULE$NetworkingMethods.h" #import <objc/runtime.h> static void *CTNetworkingActualRequestParams = &CTNetworkingActualRequestParams; static void *CTNetworkingOriginRequestParams = &CTNetworkingOriginRequestParams; static void *CTNetworkingRequestService = &CTNetworkingRequestService; @implementation NSURLRequest ($MODULE$NetworkingMethods) - (void)setActualRequestParams:(NSDictionary *)actualRequestParams { objc_setAssociatedObject(self, CTNetworkingActualRequestParams, actualRequestParams, OBJC_ASSOCIATION_COPY); } - (NSDictionary *)actualRequestParams { return objc_getAssociatedObject(self, CTNetworkingActualRequestParams); } - (void)setOriginRequestParams:(NSDictionary *)originRequestParams { objc_setAssociatedObject(self, CTNetworkingOriginRequestParams, originRequestParams, OBJC_ASSOCIATION_COPY); } - (NSDictionary *)originRequestParams { return objc_getAssociatedObject(self, CTNetworkingOriginRequestParams); } - (void)setService:(id<$MODULE$ServiceProtocol>)service { objc_setAssociatedObject(self, CTNetworkingRequestService, service, OBJC_ASSOCIATION_RETAIN_NONATOMIC); } - (id<$MODULE$ServiceProtocol>)service { return objc_getAssociatedObject(self, CTNetworkingRequestService); } @end """ xxnetos.mkclass(h_content, m_content, filename, module, "$MODULE$", selffolder)
def __generateObject(module, folder): selffolder = folder + "/NSObject" if xxnetos.mkdir(selffolder) == False: return False filename = "NSObject+$MODULE$NetworkingMethods" h_content = """// // NSObject+$MODULE$NetworkingMethods.h // $MODULE$Networking // // Created by JoeXu on 2018/4/24. // Copyright © 2018年 JoeXu. All rights reserved. // #import <Foundation/Foundation.h> @interface NSObject ($MODULE$NetworkingMethods) - (id)$MODULE$_defaultValue:(id)defaultData; - (BOOL)$MODULE$_isEmptyObject; @end """ m_content = """// // NSObject+$MODULE$NetworkingMethods.m // $MODULE$Networking // // Created by JoeXu on 2018/4/24. // Copyright © 2018年 JoeXu. All rights reserved. // #import "NSObject+$MODULE$NetworkingMethods.h" @implementation NSObject ($MODULE$NetworkingMethods) - (id)$MODULE$_defaultValue:(id)defaultData { if (![defaultData isKindOfClass:[self class]]) { return defaultData; } if ([self $MODULE$_isEmptyObject]) { return defaultData; } return self; } - (BOOL)$MODULE$_isEmptyObject { if ([self isEqual:[NSNull null]]) { return YES; } if ([self isKindOfClass:[NSString class]]) { if ([(NSString *)self length] == 0) { return YES; } } if ([self isKindOfClass:[NSArray class]]) { if ([(NSArray *)self count] == 0) { return YES; } } if ([self isKindOfClass:[NSDictionary class]]) { if ([(NSDictionary *)self count] == 0) { return YES; } } return NO; } @end """ xxnetos.mkclass(h_content, m_content, filename, module, "$MODULE$", selffolder)
def __generateMutableString(module, folder): selffolder = folder + "/NSString" filename = "NSMutableString+$MODULE$NetworkingMethods" h_content = """// // NSMutableString+$MODULE$NetworkingMethods.h // $MODULE$Networking // // Created by JoeXu on 2018/4/24. // Copyright © 2018年 JoeXu. All rights reserved. // #import <Foundation/Foundation.h> @interface NSMutableString ($MODULE$NetworkingMethods) - (void)appendURLRequest:(NSURLRequest *)request; @end """ m_content = """// // NSMutableString+$MODULE$NetworkingMethods.m // $MODULE$Networking // // Created by JoeXu on 2018/4/24. // Copyright © 2018年 JoeXu. All rights reserved. // #import "NSMutableString+$MODULE$NetworkingMethods.h" #import "NSObject+$MODULE$NetworkingMethods.h" #import "NSURLRequest+$MODULE$NetworkingMethods.h" #import "NSDictionary+$MODULE$NetworkingMethods.h" @implementation NSMutableString ($MODULE$NetworkingMethods) - (void)appendURLRequest:(NSURLRequest *)request { [self appendFormat:@"\\n\\nHTTP URL:\\n\\t%@", request.URL]; [self appendFormat:@"\\n\\nHTTP Header:\\n%@", request.allHTTPHeaderFields ? request.allHTTPHeaderFields : @"\\t\\t\\t\\t\\tN/A"]; [self appendFormat:@"\\n\\nHTTP Origin Params:\\n\\t%@", request.originRequestParams.$MODULE$_jsonString]; [self appendFormat:@"\\n\\nHTTP Actual Params:\\n\\t%@", request.actualRequestParams.$MODULE$_jsonString]; [self appendFormat:@"\\n\\nHTTP Body:\\n\\t%@", [[[NSString alloc] initWithData:request.HTTPBody encoding:NSUTF8StringEncoding] $MODULE$_defaultValue:@"\\t\\t\\t\\tN/A"]]; NSMutableString *headerString = [[NSMutableString alloc] init]; [request.allHTTPHeaderFields enumerateKeysAndObjectsUsingBlock:^(NSString * _Nonnull key, NSString * _Nonnull obj, BOOL * _Nonnull stop) { NSString *header = [NSString stringWithFormat:@" -H \\"%@: %@\\"", key, obj]; [headerString appendString:header]; }]; [self appendString:@"\\n\\nCURL:\\n\\t curl"]; [self appendFormat:@" -X %@", request.HTTPMethod]; if (headerString.length > 0) { [self appendString:headerString]; } if (request.HTTPBody.length > 0) { [self appendFormat:@" -d '%@'", [[[NSString alloc] initWithData:request.HTTPBody encoding:NSUTF8StringEncoding] $MODULE$_defaultValue:@"\\t\\t\\t\\tN/A"]]; } [self appendFormat:@" %@", request.URL]; } @end """ xxnetos.mkclass(h_content, m_content, filename, module, "$MODULE$", selffolder)
def __generateString(module, folder): selffolder = folder + "/NSString" if xxnetos.mkdir(selffolder) == False: return False filename = "NSString+$MODULE$NetworkingMethods" h_content = """// // NSString+$MODULE$NetworkingMethods.h // $MODULE$Networking // // Created by JoeXu on 2018/4/24. // Copyright © 2018年 JoeXu. All rights reserved. // #import <Foundation/Foundation.h> @interface NSString ($MODULE$NetworkingMethods) - (NSString *)$MODULE$_MD5; - (NSString *)$MODULE$_SHA1; - (NSString *)$MODULE$_Base64Encode; @end """ m_content = """// // NSString+$MODULE$NetworkingMethods.m // $MODULE$Networking // // Created by JoeXu on 2018/4/24. // Copyright © 2018年 JoeXu. All rights reserved. // #import "NSString+$MODULE$NetworkingMethods.h" #include <CommonCrypto/CommonDigest.h> #import <CommonCrypto/CommonCryptor.h> #import "NSObject+$MODULE$NetworkingMethods.h" static char base64EncodingTable[64] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/' }; @implementation NSString ($MODULE$NetworkingMethods) - (NSString *)$MODULE$_MD5 { NSData* inputData = [self dataUsingEncoding:NSUTF8StringEncoding]; unsigned char outputData[CC_MD5_DIGEST_LENGTH]; CC_MD5([inputData bytes], (unsigned int)[inputData length], outputData); NSMutableString* hashStr = [NSMutableString string]; int i = 0; for (i = 0; i < CC_MD5_DIGEST_LENGTH; ++i) [hashStr appendFormat:@"%02x", outputData[i]]; return hashStr; } - (NSString *)$MODULE$_SHA1 { const char *cstr = [self cStringUsingEncoding:NSUTF8StringEncoding]; NSData *data = [NSData dataWithBytes:cstr length:self.length]; //使用对应的CC_SHA1,CC_SHA256,CC_SHA384,CC_SHA512的长度分别是20,32,48,64 uint8_t digest[CC_SHA1_DIGEST_LENGTH]; //使用对应的CC_SHA256,CC_SHA384,CC_SHA512 CC_SHA1(data.bytes, (unsigned int)data.length, digest); NSMutableString* output = [NSMutableString stringWithCapacity:CC_SHA1_DIGEST_LENGTH * 2]; for(int i = 0; i < CC_SHA1_DIGEST_LENGTH; i++) [output appendFormat:@"%02x", digest[i]]; return output; } - (NSString *)$MODULE$_Base64Encode { NSData *rawData = [self dataUsingEncoding:NSUTF8StringEncoding]; unsigned long ixtext, lentext; long ctremaining; unsigned char input[3], output[4]; short i, charsonline = 0, ctcopy; const unsigned char *raw; NSMutableString *result; lentext = [self length]; if (lentext < 1) return @""; result = [NSMutableString stringWithCapacity:lentext]; raw = [rawData bytes]; ixtext = 0; while (true) { ctremaining = lentext - ixtext; if (ctremaining <= 0) break; for (i = 0; i < 3; i++) { unsigned long ix = ixtext + i; if (ix < lentext) input[i] = raw[ix]; else input[i] = 0; } output[0] = (input[0] & 0xFC) >> 2; output[1] = ((input[0] & 0x03) << 4) | ((input[1] & 0xF0) >> 4); output[2] = ((input[1] & 0x0F) << 2) | ((input[2] & 0xC0) >> 6); output[3] = input[2] & 0x3F; ctcopy = 4; switch (ctremaining) { case 1: ctcopy = 2; break; case 2: ctcopy = 3; break; } for (i = 0; i < ctcopy; i++) [result appendString: [NSString stringWithFormat:@"%c", base64EncodingTable[output[i]]]]; for (i = ctcopy; i < 4; i++) [result appendString:@"="]; ixtext += 3; charsonline += 4; if ((lentext > 0) && (charsonline >= lentext)) charsonline = 0; } return result; } #pragma mark - private methods - (int)char2Int:(char)c { if (c >= 'A' && c <= 'Z') { return c - 65; } else if (c >= 'a' && c <= 'z') { return c - 97 + 26; } else if (c >= '0' && c <= '9') { return c - 48 + 26 + 26; } else { switch(c) { case '+': return 62; case '/': return 63; case '=': return 0; default: return -1; } } } @end """ xxnetos.mkclass(h_content, m_content, filename, module, "$MODULE$", selffolder)