Commit 87e234ab authored by “Icebear”'s avatar “Icebear”

登录页UI、协调器模式、中间件模式配置、URL配置

parent 483d2fd8
......@@ -6,7 +6,6 @@
//
#import "AppDelegate.h"
@interface AppDelegate (AppService)
//初始化 window
......
......@@ -6,19 +6,17 @@
//
#import "AppDelegate+AppService.h"
#import "NRLoginViewController.h"
#import "MainCoordinator.h"
@implementation AppDelegate (AppService)
#pragma mark ————— 初始化window —————
-(void)initWindow{
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
self.window.backgroundColor = UIColor.whiteColor;
self.window.rootViewController = UIViewController.new;
[self.window makeKeyAndVisible];
[[UIButton appearance] setExclusiveTouch:YES];
if (@available(iOS 11.0, *)){
[[UIScrollView appearance] setContentInsetAdjustmentBehavior:UIScrollViewContentInsetAdjustmentNever];
}
self.coordinator = [[MainCoordinator alloc] initWithWindow:self.window];
[self.coordinator start];
}
......
......@@ -6,10 +6,13 @@
//
#import <UIKit/UIKit.h>
@class MainCoordinator;
@interface AppDelegate : UIResponder <UIApplicationDelegate>
@property(strong, nonatomic) UIWindow *window;
@property(strong, nonatomic) MainCoordinator *coordinator;
@end
{
"product": {
"kDomain" : "api.docker.naiterui.com/",
"kHost" : "ad",
"kSwagger" : "emr",
"kMHost" : "recommend",
"kH5Path" : "",
"kChat" : "yun",
"kHHost" : "im",
"kTHost" : "push",
"kH5Zip" : "",
"kH5_envir" : "1",
"useSSL" : 1,
},
"developer": {
}
}
//
// NRBaseModelAgent.h
// NetrainFrame
//
// Created by Gin on 2020/9/24.
//
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface NRBaseModelAgent : NSObject
/**
* Quick way to create Agent
*
* @return instance of JHModelAgent
*/
+ (instancetype)agent;
/**
* Create Model instance from Json Data
*
* @param modelClass maybe any class.
* @param json Json data. Should be a NSArray or a NSDictionary.
*
* @return A NSArray contains the Model instances.
*/
- (NSArray *)createModel:(Class)modelClass fromJson:(id)json;
/**
* Create Json data from a JHModel.
*
* @param model Should be derived from JHModel.
*
* @return Json data.(NSDictionary)
*/
- (NSDictionary *)createJsonFromModel:(NSObject *)model;
/**
* Create Json data from a JHModel.
*
* @param modelArray A NSArray contains models. Models Should be derived from JHModel.
*
* @return Json data.(NSArray)
*/
- (NSArray *)createJsonArrayFromModel:(NSArray *)modelArray;
@end
NS_ASSUME_NONNULL_END
//
// NRBaseModelAgent.m
// NetrainFrame
//
// Created by Gin on 2020/9/24.
//
#import "NRBaseModelAgent.h"
@implementation NRBaseModelAgent
+ (instancetype)agent {
return [[NRBaseModelAgent alloc] init];
}
#pragma mark - json to model
- (NSArray *)createModel:(Class)modelClass fromJson:(id)json {
NSArray *result = nil;
if ([json isKindOfClass:[NSString class]]) {
result = [NSArray yy_modelArrayWithClass:modelClass json:json];
} else if ([json isKindOfClass:[NSDictionary class]]) {
id model = [modelClass yy_modelWithDictionary:json];
if (model) {
result = @[model];
} else {
NSLog(@"Fail to create model");
}
} else {
NSLog(@"Not json data.");
}
return result;
}
- (NSDictionary *)createJsonFromModel:(NSObject *)model {
NSDictionary *result = [model yy_modelToJSONObject];
if (![result isKindOfClass:[NSDictionary class]]) {
NSLog(@"Fail to get Json data.");
}
return result;
}
- (NSArray *)createJsonArrayFromModel:(NSArray *)modelArray {
NSArray *result = [modelArray yy_modelToJSONObject];
if (![result isKindOfClass:[NSArray class]]) {
NSLog(@"Fail to get Json data.");
}
return result;
}
@end
//
// NRGlobalUrlModel.h
// NetrainFrame
//
// Created by Gin on 2020/9/24.
//
#import <Foundation/Foundation.h>
typedef enum : NSUInteger {
AppServer_Developer,
AppServer_Product,
} AppServer;
NS_ASSUME_NONNULL_BEGIN
@interface NRGlobalUrlModel : NSObject
+(NRGlobalUrlModel *)sharedInstance;
@property(nonatomic, assign) AppServer appServer;
@property(nonatomic, strong) NSString *kHost;
@property(nonatomic, strong) NSString *kSwagger;
@property(nonatomic, strong) NSString *kMHost;
@property(nonatomic, strong) NSString *kH5Path;
@property(nonatomic, strong) NSString *kChat;
@property(nonatomic, strong) NSString *kHHost;
@property(nonatomic, strong) NSString *kTHost;
@property(nonatomic, strong) NSString *kH5Version;
@property(nonatomic, strong) NSString *kH5Zip;
@property(nonatomic, strong) NSString *kH5Environmental;
@end
NS_ASSUME_NONNULL_END
//
// NRGlobalUrlModel.m
// NetrainFrame
//
// Created by Gin on 2020/9/24.
//
#import "NRGlobalUrlModel.h"
@interface URLModel : NSObject
@property(nonatomic, copy) NSString *kDomain;
@property(nonatomic, copy) NSString *kHost;
@property(nonatomic, copy) NSString *kSwagger;
@property(nonatomic, copy) NSString *kMHost;
@property(nonatomic, copy) NSString *kH5Path;
@property(nonatomic, copy) NSString *kChat;
@property(nonatomic, copy) NSString *kHHost;
@property(nonatomic, copy) NSString *kTHost;
@property(nonatomic, copy) NSString *kH5Zip;
@property(nonatomic, copy) NSString *kH5_envir;
@property(nonatomic, assign) BOOL useSSL;
@end
@implementation URLModel
@end
@implementation NRGlobalUrlModel
+ (NRGlobalUrlModel *)sharedInstance {
static NRGlobalUrlModel *sharedInstance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
if (!sharedInstance) {
sharedInstance = [[self alloc] init];
[sharedInstance cofigureAppServer];
}
});
return sharedInstance;
}
- (void)cofigureAppServer{
NSString *path = [[NSBundle mainBundle] pathForResource:@"BaseUrlConfig" ofType:@"json"];
if (path == nil) {
NSAssert(NO, @"出错了!");
}
NSString *str = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil];
NSDictionary *urlDict = [str yy_modelToJSONObject];
URLModel *urlModel = [[URLModel alloc] init];
if(self.appServer == ProductSever){
urlModel = [[[NRBaseModelAgent agent] createModel:[URLModel class] fromJson:urlDict[@"product"]] objectAtIndex:0];
}else{
urlModel = [[[NRBaseModelAgent agent] createModel:[URLModel class] fromJson:urlDict[@"developer"]] objectAtIndex:0];
}
if(urlModel){
self.kHost = [NSString stringWithFormat:@"%@%@%@",urlModel.useSSL?@"https://":@"http://",urlModel.kDomain,urlModel.kHost];
self.kSwagger = [NSString stringWithFormat:@"%@%@%@",urlModel.useSSL?@"https://":@"http://",urlModel.kDomain,urlModel.kSwagger];
self.kMHost = [NSString stringWithFormat:@"%@%@%@",urlModel.useSSL?@"https://":@"http://",urlModel.kDomain,urlModel.kMHost];
self.kH5Path = [NSString stringWithFormat:@"%@%@%@",urlModel.useSSL?@"https://":@"http://",urlModel.kDomain,urlModel.kH5Path];
self.kChat = [NSString stringWithFormat:@"%@%@%@",urlModel.useSSL?@"https://":@"http://",urlModel.kDomain,urlModel.kChat];
self.kHHost = [NSString stringWithFormat:@"%@%@%@",urlModel.useSSL?@"https://":@"http://",urlModel.kDomain,urlModel.kHHost];
self.kTHost = [NSString stringWithFormat:@"%@%@%@",urlModel.useSSL?@"https://":@"http://",urlModel.kDomain,urlModel.kTHost];
self.kH5Version = @"1.0";
self.kH5Zip = [NSString stringWithFormat:@"%@%@",urlModel.useSSL?@"https://":@"http://",urlModel.kDomain];
self.kH5Environmental = urlModel.kH5_envir;
}
}
@end
//
// BaseRequestAPI.h
// NRBaseRequest.h
// NetrainFrame
//
// Created by Gin on 2020/9/21.
// Created by Gin on 2020/9/23.
//
#import <YTKNetwork/YTKNetwork.h>
/**
///环境Url
#import "NRGlobalUrlModel.h"
/*
接口请求基类,所有请求必须继承此类
这里采用的是YTKNetwork网络库,中大型APP专用,可满足所有网络需求
学习地址:https://github.com/yuantiku/YTKNetwork
*/
@interface BaseRequestAPI : YTKBaseRequest
NS_ASSUME_NONNULL_BEGIN
@interface NRBaseRequest : YTKBaseRequest
//自定义属性值
@property(nonatomic,assign)BOOL isSuccess;//是否成功
@property (nonatomic,copy) NSString * message;//服务器返回的信息
@property (nonatomic,copy) NSDictionary * result;//服务器返回的数据 已解密
- (void)startWithCompletionBlock:(void (^)(NRBaseRequest *request, NSString *error))block;
@end
NS_ASSUME_NONNULL_END
//
// NRBaseRequest.m
// NetrainFrame
//
// Created by Gin on 2020/9/23.
//
#import "NRBaseRequest.h"
#import "NRGlobalUrlModel.h"
#define kBaseApiOtherError @"服务器错误,请稍后再试"
#define kSuccHttpCode 0
@implementation NRBaseRequest
- (void)dealloc {
NSLog(@"dealloc %@", [NSString stringWithUTF8String:class_getName([self class])]);
}
- (NSString *)baseUrl {
return [NRGlobalUrlModel sharedInstance].kHost;
}
-(BOOL)statusCodeValidator{
return YES;
}
- (BOOL)ignoreCache {
return YES;
}
- (YTKRequestMethod)requestMethod {
return YTKRequestMethodPOST;
}
//- (BaseHttpModel *)httpModel {
// if (!_httpModel) {
// NSArray *arr = [[BookModelAgent agent] createModel:[BaseHttpModel class] fromJson:self.responseJSONObject];
// _httpModel = [arr objectAtIndexSafely:0];
// }
//
// return _httpModel;
//}
//- (BOOL)isSucc {
// BaseHttpModel *httpModel = self.httpModel;
// return httpModel && httpModel.errcode == kSuccHttpCode;
//}
//- (NSString *)errorMsg {
// BaseHttpModel *httpModel = self.httpModel;
// return httpModel.errmsg.length > 0 ? httpModel.errmsg : kBaseApiOtherError;
//}
#pragma mark ————— 如果是加密方式传输,自定义request —————
-(NSURLRequest *)buildCustomUrlRequest{
return nil;
}
- (void)startWithCompletionBlock:(void (^)(NRBaseRequest *request, NSString *error))block {
__weak __typeof(self) weakSelf = self;
[self startWithCompletionBlockWithSuccess:^(__kindof YTKBaseRequest *_Nonnull request) {
if (!block) {
return;
}
__strong typeof(weakSelf) strongSelf = weakSelf;
// if ([strongSelf isSucc]) {
// block(strongSelf, nil);
// }
// else {
// block(strongSelf, [strongSelf errorMsg]);
// }
} failure:^(__kindof YTKBaseRequest *_Nonnull request) {
if (!block) {
return;
}
__strong typeof(weakSelf) strongSelf = weakSelf;
block(strongSelf, request.error.userInfo[NSLocalizedDescriptionKey] ?: kBaseApiOtherError);
}];
}
@end
//
// BaseRequestAPI.h
// NetrainFrame
//
// Created by Gin on 2020/9/21.
//
#import "BaseRequestAPI.h"
@implementation BaseRequestAPI
-(instancetype)init{
self = [super init];
if (self) {
}
return self;
}
#pragma mark ————— 自定义数据 —————
- (NSString *)message {
if (self.error) {
return self.error.localizedDescription;
}
NSString *message = [NSString stringWithFormat:@"%@",self.result[@"codemsg"]];
return message;
}
- (NSString *)code {
NSString *code = [NSString stringWithFormat:@"%@",self.result[@"code"]];
return code;
}
- (BOOL)isSuccess {
NSString *code = [self code];
BOOL isSuccess = NO;
if ([code isEqualToString:@"0"]) {
isSuccess = YES;
}
return isSuccess;
}
#pragma mark ————— 定义返回数据格式,若是加密要用HTTP接受 —————
-(YTKResponseSerializerType)responseSerializerType {
return YTKResponseSerializerTypeJSON;
}
#pragma mark ————— 默认请求方式 POST —————
-(YTKRequestMethod)requestMethod{
return YTKRequestMethodPOST;
}
#pragma mark ————— 请求失败过滤器 —————
-(void)requestFailedFilter{
//失败处理器
}
#pragma mark ————— 请求成功过滤器 —————
-(void)requestCompleteFilter{
self.result = self.responseJSONObject;
}
#pragma mark ————— 非加密时也要传输的头部内容 也可能不需要,暂时保留 —————
-(NSDictionary<NSString *,NSString *> *)requestHeaderFieldValueDictionary{
//header部分
return @{};
}
#pragma mark ————— 如果是加密方式传输,自定义request —————
-(NSURLRequest *)buildCustomUrlRequest{
return nil;
}
@end
//
// NRCommonViewController.h
// NetrainFrame
//
// Created by Gin on 2020/9/22.
//
#import <QMUIKit/QMUIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface NRCommonViewController : QMUICommonViewController
+(instancetype)instantiateWithStoryboardName:(NSString *)storyboardName;
@end
NS_ASSUME_NONNULL_END
//
// NRCommonViewController.m
// NetrainFrame
//
// Created by Gin on 2020/9/22.
//
#import "NRCommonViewController.h"
@interface NRCommonViewController ()
@end
@implementation NRCommonViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
}
+(instancetype)instantiateWithStoryboardName:(NSString *)storyboardName{
NSString *fullName = NSStringFromClass(self);
NSString *className = [fullName componentsSeparatedByString:@"."].lastObject;
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:storyboardName bundle:[NSBundle mainBundle]];
return [storyboard instantiateViewControllerWithIdentifier:className];
}
- (BOOL)shouldCustomizeNavigationBarTransitionIfHideable {
return YES;
}
/*
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
*/
@end
//
// CTMediator+MainCoordinatorActions.h
// NetrainFrame
//
// Created by Gin on 2020/9/23.
//
#import <CTMediator/CTMediator.h>
NS_ASSUME_NONNULL_BEGIN
@interface CTMediator (MainCoordinatorActions)
- (UIViewController *)CTMediator_viewControllerForLoginCoordinator;
@end
NS_ASSUME_NONNULL_END
//
// CTMediator+MainCoordinatorActions.m
// NetrainFrame
//
// Created by Gin on 2020/9/23.
//
#import "CTMediator+MainCoordinatorActions.h"
NSString * const kCTMediatorTargetLoginCoordinator = @"LoginCoordinator";
NSString * const kCTMediatorActionLoginCoordinatorRootController = @"LoginCoordinatorRootController";
@implementation CTMediator (MainCoordinatorActions)
- (UIViewController *)CTMediator_viewControllerForLoginCoordinator{
UIViewController *viewController = [self performTarget:kCTMediatorTargetLoginCoordinator
action:kCTMediatorActionLoginCoordinatorRootController
params:nil
shouldCacheTarget:NO
];
if (viewController) {
// view controller 交付出去之后,可以由外界选择是push还是present
return viewController;
} else {
// 这里处理异常场景,具体如何处理取决于产品
return [[UINavigationController alloc] init];
}
}
@end
//
// MainCoordinator.h
// NetrainFrame
//
// Created by Gin on 2020/9/23.
//
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface MainCoordinator : NSObject
- (instancetype)initWithWindow:(UIWindow *)window;
- (void)start;
@end
NS_ASSUME_NONNULL_END
//
// MainCoordinator.m
// NetrainFrame
//
// Created by Gin on 2020/9/23.
//
#import "MainCoordinator.h"
#import "CTMediator+MainCoordinatorActions.h"
@interface MainCoordinator()
@property(nonatomic, weak) UIWindow *window;
@property(nonatomic, strong) NSMutableArray *childCoordinators;
@end
@implementation MainCoordinator
- (instancetype)initWithWindow:(UIWindow *)window
{
self = [super init];
if (self) {
self.window = window;
}
return self;
}
-(void)start{
BOOL isLogin = YES;
if(isLogin){
[self showLogin];
}else{
[self showLogin];
}
}
-(void)close:(NSObject *)loginCoordinator{
[self.childCoordinators removeObject:loginCoordinator];
[self showNew];
}
- (void)showLogin{
UIViewController *viewController = [[CTMediator sharedInstance] CTMediator_viewControllerForLoginCoordinator];
self.window.rootViewController = viewController;
[self.window makeKeyAndVisible];
}
-(void)showNew{
// UITabBarController *navigationController = [[UITabBarController alloc] init];
// NewCoordinator *newCoordinator = [[NewCoordinator alloc] initWithNavigationController:navigationController];
// [newCoordinator start];
//
// [self.childCoordinators addObject:newCoordinator];
//
// self.window.rootViewController = navigationController;
// [self.window makeKeyAndVisible];
}
- (NSMutableArray *)childCoordinators {
if (!_childCoordinators) {
self.childCoordinators = [NSMutableArray array];
}
return _childCoordinators;
}
@end
......@@ -12,6 +12,27 @@
#define FontAndColorMacros_h
#pragma mark - 颜色区
#pragma 颜色
///主题文字色,当前为蓝色(部分标签的颜色,跟项目主题色相似)
#define UIColorThemeColor [UIColor qmui_colorWithHexString:@"009AFF"]
///主题边框色,当前为浅蓝(部分标签边框的颜色,跟项目主题色相似)
#define UIColorThemeBorderColor [UIColor qmui_colorWithHexString:@"58BDFF"]
///主题线颜色,当前为灰色(分隔线的颜色)
#define UIColorThemeLineColor [UIColor qmui_colorWithHexString:@"F5F5F5"]
///主题提示文字颜色(输入框提示文字的颜色,比如:请务必上传医生头像)
#define UIColorThemePlaceholderColor [UIColor qmui_colorWithHexString:@"989898"]
///主题输入文字颜色(输入框输入文字的颜色)
#define UIColorThemeInputColor [UIColor qmui_colorWithHexString:@"171717"]
///主题黑色按钮颜色(部分按钮的颜色,类似获取验证码按钮)
#define UIColorThemeButtonBlackColor [UIColor qmui_colorWithHexString:@"444444"]
///部分页面灰色底色(部分页面的底色,大部分为白色)
#define UIColorThemePageBgGrayColor [UIColor qmui_colorWithHexString:@"f7f7f7"]
///导航栏标题颜色(导航栏标题颜色)
#define UIColorThemeNavTitleColor [UIColor qmui_colorWithHexString:@"151515"]
///详情文字颜色(详情内容的文字颜色,比如处方详情里编号、分发的文字颜色)
#define UIColorThemeDetailsTextColor [UIColor qmui_colorWithHexString:@"727272"]
///提示警告文字颜色(警告颜色,比如输入框的错误提示)
#define UIColorThemeWarningTextColor [UIColor qmui_colorWithHexString:@"D70C19"]
#pragma mark - 字号区
......
......@@ -114,11 +114,11 @@
//单例化一个类
#define SINGLETON_FOR_HEADER(className) \
\
+ (className *)shared##className;
+ (className *)sharedInstance;
#define SINGLETON_FOR_CLASS(className) \
\
+ (className *)shared##className { \
+ (className *)sharedInstance { \
static className *shared##className = nil; \
static dispatch_once_t onceToken; \
dispatch_once(&onceToken, ^{ \
......
//
// NRLoginViewController.h
// NetrainFrame
//
// Created by Gin on 2020/9/22.
//
#import "NRCommonViewController.h"
@class MainCoordinator;
NS_ASSUME_NONNULL_BEGIN
@interface NRLoginViewController : NRCommonViewController
@property(weak, nonatomic) MainCoordinator *coordinator;
@end
NS_ASSUME_NONNULL_END
//
// NRLoginViewController.m
// NetrainFrame
//
// Created by Gin on 2020/9/22.
//
#import "NRLoginViewController.h"
#import "NRLoginLogic.h"
typedef NS_ENUM(NSUInteger, UserSelectLoginMode) {
passswdLogin = 10, //密码登录
verificationLogin, //验证码登录
};
@interface NRLoginViewController ()<QMUITextFieldDelegate>
@property (weak, nonatomic) IBOutlet QMUITextField *phoneNumberField;
@property (weak, nonatomic) IBOutlet QMUITextField *passwdField;
@property (weak, nonatomic) IBOutlet UIButton *showPwdBtn;
@property (weak, nonatomic) IBOutlet UIButton *loginButton;
@property (weak, nonatomic) IBOutlet UIButton *verificationBtn;
@property (weak, nonatomic) IBOutlet UIImageView *verificationBtnBottomArc;
@property (weak, nonatomic) IBOutlet UIButton *passwdLogBtn;
@property (weak, nonatomic) IBOutlet UIImageView *passwdBtnBottomArc;
@property (weak, nonatomic) IBOutlet UIButton *verificationLogBtn;
@property (assign, nonatomic) UserSelectLoginMode loginMode;
@property (strong,nonatomic) NSDate *resignBackgroundDate;
@property (assign,nonatomic) int timeout;
@property (strong,nonatomic) NSTimer* countDownTimer;
@property (weak, nonatomic) IBOutlet UIView *forgetAndRegisterView;
@property (weak, nonatomic) IBOutlet UIView *accountView;
@property (weak, nonatomic) IBOutlet UIButton *registerButton;
@property (weak, nonatomic) IBOutlet UIView *forgetAndRegisterDividingLine;
@property (weak, nonatomic) IBOutlet UIButton *forgetPwdButton;
@property (weak, nonatomic) IBOutlet UIView *passwordView;
///Logic
@property(strong, nonatomic) NRLoginLogic *loginLogic;
@end
#define kAccountMaxLength 11 //手机号长度限制
#define kPassswordMaxLength 16 //登录密码长度最大限制
#define kPassswordMinLength 9 //登录密码长度最小限制
#define kVerifyCodeMaxLength 4 //验证码长度限制
@implementation NRLoginViewController
-(BOOL)preferredNavigationBarHidden{
return YES;
}
- (void)viewDidLoad {
[super viewDidLoad];
[self configSubviews];
// Do any additional setup after loading the view.
}
-(void)initSubviews{
[super initSubviews];
self.accountView.layer.borderColor = UIColorThemeLineColor.CGColor;
self.passwordView.layer.borderColor = UIColorThemeLineColor.CGColor;
self.accountView.layer.borderWidth = 1;
self.passwordView.layer.borderWidth = 1;
[self.registerButton setTitleColor:UIColorThemeColor forState:UIControlStateNormal];
[self.forgetPwdButton setTitleColor:UIColorThemeColor forState:UIControlStateNormal];
[self.forgetAndRegisterDividingLine setBackgroundColor:UIColorThemeBorderColor];
[self.passwdLogBtn setTitleColor:UIColorThemeColor forState:UIControlStateSelected];
[self.verificationLogBtn setTitleColor:UIColorThemeColor forState:UIControlStateSelected];
[self.verificationBtn setTitleColor:UIColorThemeButtonBlackColor forState:UIControlStateNormal];
}
-(void)configSubviews{
self.loginMode = verificationLogin;
self.passwdField.maximumTextLength = (self.loginMode == passswdLogin)? kPassswordMaxLength : kVerifyCodeMaxLength;
self.passwdField.keyboardType = self.loginMode == passswdLogin? UIKeyboardTypeNumbersAndPunctuation : UIKeyboardTypeNumberPad;
self.phoneNumberField.delegate = self;
self.passwdField.delegate = self;
}
#pragma mark -- QMUITextFieldDelegate
-(void)textFieldDidBeginEditing:(UITextField *)textField{
if(textField == self.phoneNumberField){
self.accountView.layer.borderColor = UIColorThemeBorderColor.CGColor;
}else{
self.passwordView.layer.borderColor=UIColorThemeBorderColor.CGColor;
}
}
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string{
[self checkLoginStatus];
return YES;
}
-(void)textFieldDidEndEditing:(UITextField *)textField{
if(textField == self.phoneNumberField){
self.accountView.layer.borderColor = UIColorThemeLineColor.CGColor;
}else{
self.passwordView.layer.borderColor=UIColorThemeLineColor.CGColor;
}
}
#pragma mark -- IBAction
///显示密码
- (IBAction)showPassword:(id)sender {
UIButton *btn = (UIButton *)sender;
btn.selected = !btn.selected;
self.passwdField.secureTextEntry = btn.selected ? NO : YES;
}
///点击登录
- (IBAction)loginBtnClick:(id)sender {
if(self.loginMode == verificationLogin){
[self.loginLogic verifyCodeLoginAction];
}else{
[self.loginLogic passwordLoginAction];
}
}
///获取验证码
- (IBAction)getVerification:(id)sender {
[self.loginLogic getVerifyCodeAction:self.phoneNumberField.text];
}
///密码登录
- (IBAction)passwdLogin:(id)sender {
[self.phoneNumberField becomeFirstResponder];
self.passwdField.text = @"";
self.passwdField.placeholder = @"请输入密码";
self.verificationBtn.hidden = YES;
self.showPwdBtn.hidden = NO;
self.passwdLogBtn.selected = YES;
self.passwdBtnBottomArc.hidden = NO;
self.verificationLogBtn.selected = NO;
self.verificationBtnBottomArc.hidden = YES;
self.passwdField.maximumTextLength = kPassswordMaxLength;
self.loginMode = passswdLogin;
self.passwdField.secureTextEntry = YES;
self.passwdField.keyboardType = UIKeyboardTypeNumbersAndPunctuation;
[self checkLoginStatus];
}
///验证码登录
- (IBAction)verificationLogin:(id)sender {
[self.phoneNumberField becomeFirstResponder];
self.passwdField.text = @"";
self.passwdField.placeholder = @"请输入验证码";
self.verificationBtn.hidden = NO;
self.showPwdBtn.hidden = YES;
self.passwdLogBtn.selected = NO;
self.passwdBtnBottomArc.hidden = YES;
self.verificationLogBtn.selected = YES;
self.verificationBtnBottomArc.hidden = NO;
self.passwdField.maximumTextLength = kVerifyCodeMaxLength;
self.loginMode = verificationLogin;
self.passwdField.keyboardType = UIKeyboardTypeNumberPad;
self.passwdField.secureTextEntry = NO;
[self checkLoginStatus];
}
#pragma mark -- private method
//按钮状态随文本变化而变化
- (void)checkLoginStatus{
if (self.loginMode == verificationLogin) {
if(self.passwdField.text.length == kVerifyCodeMaxLength && self.phoneNumberField.text.length == kAccountMaxLength) {
self.loginButton.enabled = YES;
}else{
if(self.loginButton.isEnabled){
self.loginButton.enabled = NO;
}
}
}else{
if(self.passwdField.text.length >= kPassswordMinLength && self.passwdField.text.length <= kPassswordMaxLength && self.phoneNumberField.text.length == kAccountMaxLength) {
self.loginButton.enabled = YES;
}
else{
if(self.loginButton.isEnabled){
self.loginButton.enabled = NO;
}
}
}
}
-(NRLoginLogic *)loginLogic{
if(!_loginLogic){
_loginLogic = [[NRLoginLogic alloc] init];
}
return _loginLogic;
}
/*
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
*/
@end
//
// NRRegisterViewController.h
// NetrainFrame
//
// Created by Gin on 2020/9/22.
//
#import "NRCommonViewController.h"
NS_ASSUME_NONNULL_BEGIN
@interface NRRegisterViewController : NRCommonViewController
@end
NS_ASSUME_NONNULL_END
//
// NRRegisterViewController.m
// NetrainFrame
//
// Created by Gin on 2020/9/22.
//
#import "NRRegisterViewController.h"
@interface NRRegisterViewController ()
@end
@implementation NRRegisterViewController
- (BOOL)preferredNavigationBarHidden {
return NO;
}
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
}
-(void)dealloc{
NSLog(@"register delloc");
}
/*
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
*/
@end
//
// NRLoginCoordinator.h
// NetrainFrame
//
// Created by Gin on 2020/9/23.
//
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface Target_LoginCoordinator : NSObject
- (UIViewController *)Action_LoginCoordinatorRootController:(NSDictionary *)params;
@end
NS_ASSUME_NONNULL_END
//
// NRLoginCoordinator.m
// NetrainFrame
//
// Created by Gin on 2020/9/23.
//
#import "Target_LoginCoordinator.h"
#import "NRLoginViewController.h"
@interface Target_LoginCoordinator()
@property(nonatomic, weak) UINavigationController *navigationController;
@end
@implementation Target_LoginCoordinator
- (UIViewController *)Action_LoginCoordinatorRootController:(NSDictionary *)params{
NRLoginViewController *vc = [NRLoginViewController instantiateWithStoryboardName:@"NRLogin"];
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:vc];
return navigationController;
}
@end
//
// NRLoginLogic.h
// NetrainFrame
//
// Created by Gin on 2020/9/23.
//
#import "NRBaseRequest.h"
@protocol NRLoginLogicDelegate <NSObject>
@optional
/**
数据加载开始
*/
-(void)requestDataStarted;
/**
数据加载完成
*/
-(void)requestDataCompleted;
@end
NS_ASSUME_NONNULL_BEGIN
@interface NRLoginLogic : NRBaseRequest
@property(nonatomic,weak)id<NRLoginLogicDelegate> delegagte;
- (void)getVerifyCodeAction:(NSString *)phoneNumber;
- (void)verifyCodeLoginAction;
- (void)passwordLoginAction;
@end
NS_ASSUME_NONNULL_END
//
// NRLoginLogic.m
// NetrainFrame
//
// Created by Gin on 2020/9/23.
//
#import "NRLoginLogic.h"
#import "NRPasswordLoginRequest.h"
#import "NRServerTimeRequest.h"
#import "NRVerifyCodeRequest.h"
@implementation NRLoginLogic
- (void)getVerifyCodeAction:(NSString *)phoneNumber{
NRServerTimeRequest *servertimeRequest = [[NRServerTimeRequest alloc] init];
[servertimeRequest startWithCompletionBlock:^(NRBaseRequest * _Nonnull request, NSString * _Nonnull error) {
if (!error) {
if (self.delegagte && [self.delegagte respondsToSelector:@selector(requestDataCompleted)]) {
[self.delegagte requestDataCompleted];
}
}
}];
}
- (void)verifyCodeLoginAction{
}
- (void)passwordLoginAction{
}
@end
//
// NRLoginKeyRequest.h
// NetrainFrame
//
// Created by Gin on 2020/9/23.
//
#import "NRBaseRequest.h"
NS_ASSUME_NONNULL_BEGIN
@interface NRLoginKeyRequest : NRBaseRequest
@end
NS_ASSUME_NONNULL_END
//
// NRLoginKeyRequest.m
// NetrainFrame
//
// Created by Gin on 2020/9/23.
//
#import "NRLoginKeyRequest.h"
@implementation NRLoginKeyRequest
-(NSString *)requestUrl{
return @"/login/genLoginKey";
}
@end
//
// NRLoginRequest.h
// NetrainFrame
//
// Created by Gin on 2020/9/23.
//
#import "NRBaseRequest.h"
NS_ASSUME_NONNULL_BEGIN
@interface NRPasswordLoginRequest : NRBaseRequest
@end
NS_ASSUME_NONNULL_END
//
// NRLoginRequest.m
// NetrainFrame
//
// Created by Gin on 2020/9/23.
//
#import "NRPasswordLoginRequest.h"
@implementation NRPasswordLoginRequest
-(NSString *)requestUrl{
return @"/login";
}
@end
//
// NRRegisterRequest.h
// NetrainFrame
//
// Created by Gin on 2020/9/23.
//
#import "NRBaseRequest.h"
NS_ASSUME_NONNULL_BEGIN
@interface NRRegisterRequest : NRBaseRequest
@end
NS_ASSUME_NONNULL_END
//
// NRRegisterRequest.m
// NetrainFrame
//
// Created by Gin on 2020/9/23.
//
#import "NRRegisterRequest.h"
@implementation NRRegisterRequest
@end
//
// NRServerTimeRequest.h
// NetrainFrame
//
// Created by Gin on 2020/9/23.
//
#import "NRBaseRequest.h"
NS_ASSUME_NONNULL_BEGIN
@interface NRServerTimeRequest : NRBaseRequest
@end
NS_ASSUME_NONNULL_END
//
// NRServerTimeRequest.m
// NetrainFrame
//
// Created by Gin on 2020/9/23.
//
#import "NRServerTimeRequest.h"
@implementation NRServerTimeRequest
-(NSString *)requestUrl{
return @"/time.jsp";
}
@end
//
// NRVerifyCodeLoginRequest.h
// NetrainFrame
//
// Created by Gin on 2020/9/23.
//
#import "NRBaseRequest.h"
NS_ASSUME_NONNULL_BEGIN
@interface NRVerifyCodeLoginRequest : NRBaseRequest
@end
NS_ASSUME_NONNULL_END
//
// NRVerifyCodeLoginRequest.m
// NetrainFrame
//
// Created by Gin on 2020/9/23.
//
#import "NRVerifyCodeLoginRequest.h"
@implementation NRVerifyCodeLoginRequest
-(NSString *)requestUrl{
return @"/login/validLogin";
}
-(id)requestArgument{
return @{};
}
@end
//
// NRVerifyCodeRequest.h
// NetrainFrame
//
// Created by Gin on 2020/9/23.
//
#import "NRBaseRequest.h"
NS_ASSUME_NONNULL_BEGIN
@interface NRVerifyCodeRequest : NRBaseRequest
@property(nonatomic, copy) NSString *phoneNumber;
@end
NS_ASSUME_NONNULL_END
//
// NRVerifyCodeRequest.m
// NetrainFrame
//
// Created by Gin on 2020/9/23.
//
#import "NRVerifyCodeRequest.h"
@implementation NRVerifyCodeRequest
-(NSString *)requestUrl{
return @"/sendSms";
}
@end
{
"colors" : [
{
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0.000",
"green" : "0.000",
"red" : "0.000"
}
},
"idiom" : "universal"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0.000",
"green" : "0.000",
"red" : "0.000"
}
},
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "分组@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "分组@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "分组@2x(1).png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "分组@3x(1).png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
{
"info" : {
"version" : 1,
"author" : "xcode"
}
}
\ No newline at end of file
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "分组 2@2x(1).png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "分组 2@3x(1).png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "路径@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "路径@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "btn_psw_invisible@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "btn_psw_invisible@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "btn_psw_available@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "btn_psw_available@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "login_password_delete@2x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"filename" : "login_password_delete@3x.png",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
\ No newline at end of file
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "椭圆形@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "椭圆形@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "分组 2@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "分组 2@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="13122.16" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="BYZ-38-t0r">
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13104.12"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--View Controller-->
<scene sceneID="tne-QT-ifu">
<objects>
<viewController id="BYZ-38-t0r" customClass="ViewController" customModuleProvider="" sceneMemberID="viewController">
<view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" xcode11CocoaTouchSystemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
<viewLayoutGuide key="safeArea" id="6Tk-OE-BBY"/>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
</objects>
</scene>
</scenes>
</document>
......@@ -14,6 +14,10 @@
#import "ThirdMacros.h"
#import "NotificationMacros.h"
///Model解析
#import "NRBaseModelAgent.h"
//第三方
#import <Masonry.h>
#import <YYModel.h>
......
/**
* Tencent is pleased to support the open source community by making QMUI_iOS available.
* Copyright (C) 2016-2020 THL A29 Limited, a Tencent company. All rights reserved.
* Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
* http://opensource.org/licenses/MIT
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
*/
//
// QMUIConfigurationTemplate.h
//
// Created by QMUI Team on 15/3/29.
//
#import <Foundation/Foundation.h>
#import <QMUIKit/QMUIKit.h>
/**
* QMUIConfigurationTemplate 是一份配置表,用于配合 QMUIConfiguration 来管理整个 App 的全局样式,使用方式:
* 在 QMUI 项目代码的文件夹里找到 QMUIConfigurationTemplate 目录,把里面所有文件复制到自己项目里,保证能被编译到即可,不需要在某些地方 import,也不需要手动运行。
*
* @warning 更新 QMUIKit 的版本时,请留意 Release Log 里是否有提醒更新配置表,请尽量保持自己项目里的配置表与 QMUIKit 里的配置表一致,避免遗漏新的属性。
* @warning 配置表的 class 名必须以 QMUIConfigurationTemplate 开头,并且实现 <QMUIConfigurationTemplateProtocol>,因为这两者是 QMUI 识别该 NSObject 是否为一份配置表的条件。
* @warning QMUI 2.3.0 之后,配置表改为自动运行,不需要再在某个地方手动运行了。
*/
@interface QMUIConfigurationTemplate : NSObject <QMUIConfigurationTemplateProtocol>
@end
//
// NSMutableArray+Safe.m
// method swizzling
//
// Created by bgcr on 2018/3/14.
// Copyright © 2018年 bgcr. All rights reserved.
//
#import <Foundation/Foundation.h>
#import <objc/runtime.h>
@implementation NSMutableArray (Safe)
+ (void)load
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
id obj = [[self alloc] init];
[obj swizzleMethod:@selector(addObject:) withMethod:@selector(safeAddObject:)];
[obj swizzleMethod:@selector(objectAtIndex:) withMethod:@selector(safeObjectAtIndex:)];
[obj swizzleMethod:@selector(objectAtIndexedSubscript:) withMethod:@selector(safeobjectAtIndexedSubscript:)];
[obj swizzleMethod:@selector(insertObject:atIndex:) withMethod:@selector(safeInsertObject:atIndex:)];
[obj swizzleMethod:@selector(removeObjectAtIndex:) withMethod:@selector(safeRemoveObjectAtIndex:)];
[obj swizzleMethod:@selector(replaceObjectAtIndex:withObject:) withMethod:@selector(safeReplaceObjectAtIndex:withObject:)];
[obj swizzleMethod:@selector(setObject:atIndexedSubscript:) withMethod:@selector(safesetObject:atIndexedSubscript:)];
});
}
- (id)safeobjectAtIndexedSubscript:(NSUInteger)idx{
if(idx<[self count]){
return [self safeobjectAtIndexedSubscript:idx];
}else{
NSLog(@"index is beyond bounds ");
}
return nil;
}
- (void)safeAddObject:(id)anObject
{
if (anObject) {
[self safeAddObject:anObject];
}else{
NSLog(@"obj is nil");
}
}
- (id)safeObjectAtIndex:(NSInteger)index
{
if(index<[self count]){
return [self safeObjectAtIndex:index];
}else{
NSLog(@"index is beyond bounds ");
}
return nil;
}
- (void)safeInsertObject:(id)anObject atIndex:(NSUInteger)index{
if (index > [self count]) {
NSLog(@"index is beyond bounds ");
}else if (anObject){
[self safeInsertObject:anObject atIndex:index];
}else{
NSLog(@"obj is nil");
}
}
- (void)safeRemoveObjectAtIndex:(NSUInteger)index{
if (index < [self count]) {
[self safeRemoveObjectAtIndex:index];
}else{
NSLog(@"index is beyond bounds ");
}
}
- (void)safesetObject:(id)obj atIndexedSubscript:(NSUInteger)idx{
if (idx < [self count]) {
if (obj) {
[self safesetObject:obj atIndexedSubscript:idx];
}else{
NSLog(@"obj is nil");
}
}else{
NSLog(@"index is beyond bounds ");
}
}
- (void)safeReplaceObjectAtIndex:(NSUInteger)index withObject:(id)anObject{
if (index < [self count]) {
if (anObject) {
[self safeReplaceObjectAtIndex:index withObject:anObject];
}else{
NSLog(@"obj is nil");
}
}else{
NSLog(@"index is beyond bounds ");
}
}
- (void)swizzleMethod:(SEL)origSelector withMethod:(SEL)newSelector
{
Class class = [self class];
Method originalMethod = class_getInstanceMethod(class, origSelector);
Method swizzledMethod = class_getInstanceMethod(class, newSelector);
BOOL didAddMethod = class_addMethod(class,
origSelector,
method_getImplementation(swizzledMethod),
method_getTypeEncoding(swizzledMethod));
if (didAddMethod) {
class_replaceMethod(class,
newSelector,
method_getImplementation(originalMethod),
method_getTypeEncoding(originalMethod));
} else {
method_exchangeImplementations(originalMethod, swizzledMethod);
}
}
@end
@implementation NSArray (Safe)
+ (void)load
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
id obj = [[self alloc] init];
//__NSArrayI(多项) __NSArray0(0项) __NSSingleObjectArrayI(一项) 目前就这三个类 有新的再加
[obj swizzleMethod:@selector(objectAtIndex:) withMethod:@selector(swizzleObjectAtIndexNSArrayI:) withClass:objc_getClass("__NSArrayI")];
[obj swizzleMethod:@selector(objectAtIndex:) withMethod:@selector(swizzleObjectAtIndexNSArray0:) withClass:objc_getClass("__NSArray0")];
[obj swizzleMethod:@selector(objectAtIndex:) withMethod:@selector(swizzleObjectAtIndexNSSingleObjectArrayI:) withClass:objc_getClass("__NSSingleObjectArrayI")];
[obj swizzleMethod:@selector(objectAtIndexedSubscript:) withMethod:@selector(safeobjectAtIndexedSubscript:) withClass:objc_getClass("__NSArrayI")];
});
}
- (id)swizzleObjectAtIndexNSArrayI:(NSInteger)index{
if(index<[self count]){
return [self swizzleObjectAtIndexNSArrayI:index];
}else{
NSLog(@"index is beyond bounds ");
}
return nil;
}
- (id)swizzleObjectAtIndexNSArray0:(NSInteger)index{
if(index<[self count]){
return [self swizzleObjectAtIndexNSArray0:index];
}else{
NSLog(@"index is beyond bounds ");
}
return nil;
}
- (id)swizzleObjectAtIndexNSSingleObjectArrayI:(NSInteger)index{
if(index<[self count]){
return [self swizzleObjectAtIndexNSSingleObjectArrayI:index];
}else{
NSLog(@"index is beyond bounds ");
}
return nil;
}
- (id)safeobjectAtIndexedSubscript:(NSUInteger)idx{
if(idx<[self count]){
return [self safeobjectAtIndexedSubscript:idx];
}else{
NSLog(@"index is beyond bounds ");
}
return nil;
}
- (void)swizzleMethod:(SEL)origSelector withMethod:(SEL)newSelector withClass:(Class)class
{
Method originalMethod = class_getInstanceMethod(class, origSelector);
Method swizzledMethod = class_getInstanceMethod(class, newSelector);
BOOL didAddMethod = class_addMethod(class,
origSelector,
method_getImplementation(swizzledMethod),
method_getTypeEncoding(swizzledMethod));
if (didAddMethod) {
class_replaceMethod(class,
newSelector,
method_getImplementation(originalMethod),
method_getTypeEncoding(originalMethod));
} else {
method_exchangeImplementations(originalMethod, swizzledMethod);
}
}
@end
......@@ -11,6 +11,7 @@ pod 'SVProgressHUD','2.2.5'
pod 'MJRefresh','3.4.3'
pod 'YTKNetwork','3.0.2'
pod 'QMUIKit','4.2.0'
pod "CTMediator",'44'
end
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment