123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355 |
- //
- // SPSBRouteManager.m
- // 我的社保
- //
- // Created by shanp on 2021/4/26.
- //
- #import "SPSBRouteManager.h"
- #import <objc/runtime.h>
- #import "YYClassInfo.h"
- #import "SPSBBaseNetworkModel.h"
- #import "SPSBHtmlViewController.h"
- #import <JXHGeneralTools.h>
- #import <JXHMacro.h>
- #import <JXHSystemShortcut.h>
- #import "SPSBGeneralManager.h"
- #import "SPSBBusinessManager.h"
- #import "SPSBNavigationController.h"
- #import "AppDelegate+SPSBRootViewController.h"
- #import "WXApi.h"
- #define force_inline __inline__ __attribute__((always_inline))
- static force_inline NSNumber *_Nullable spsb_NSNumberCreateFromID(id value) {
- static NSCharacterSet *dot;
- static NSDictionary *dic;
- static dispatch_once_t onceToken;
- dispatch_once(&onceToken, ^{
- dot = [NSCharacterSet characterSetWithRange:NSMakeRange('.', 1)];
- dic = @{@"TRUE" : @(YES),
- @"True" : @(YES),
- @"true" : @(YES),
- @"FALSE" : @(NO),
- @"False" : @(NO),
- @"false" : @(NO),
- @"YES" : @(YES),
- @"Yes" : @(YES),
- @"yes" : @(YES),
- @"NO" : @(NO),
- @"No" : @(NO),
- @"no" : @(NO),
- @"NIL" : (id)kCFNull,
- @"Nil" : (id)kCFNull,
- @"nil" : (id)kCFNull,
- @"NULL" : (id)kCFNull,
- @"Null" : (id)kCFNull,
- @"null" : (id)kCFNull,
- @"(NULL)" : (id)kCFNull,
- @"(Null)" : (id)kCFNull,
- @"(null)" : (id)kCFNull,
- @"<NULL>" : (id)kCFNull,
- @"<Null>" : (id)kCFNull,
- @"<null>" : (id)kCFNull};
- });
-
- if (!value || value == (id)kCFNull) return nil;
- if ([value isKindOfClass:[NSNumber class]]) return value;
- if ([value isKindOfClass:[NSString class]]) {
- NSNumber *num = dic[value];
- if (num != nil) {
- if (num == (id)kCFNull) return nil;
- return num;
- }
- if ([(NSString *)value rangeOfCharacterFromSet:dot].location != NSNotFound) {
- const char *cstring = ((NSString *)value).UTF8String;
- if (!cstring) return nil;
- double num = atof(cstring);
- if (isnan(num) || isinf(num)) return nil;
- return @(num);
- } else {
- const char *cstring = ((NSString *)value).UTF8String;
- if (!cstring) return nil;
- return @(atoll(cstring));
- }
- }
- return nil;
- }
- @interface SPSBRouter () {
- NSString *_className;
- NSDictionary *_property;
- }
- @end
- @implementation SPSBRouter
- - (instancetype)initWithClassName:(NSString *)className property:(nullable NSDictionary *)property tabBarType:(SPSBTabBarType)tabBarType {
- self = [super init];
- if (!self) return nil;
- _className = className;
- _property = property;
- _spsb_tabBarType = tabBarType;
- return self;
- }
- - (UIViewController *)getTarget {
- Class class = NSClassFromString(_className);
- UIViewController *controller = [[class alloc] init];
- if (!controller) {
- return nil;
- }
- __block bool canReturn = true;
- if (!_property) {
- return controller;
- }
- [_property enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull obj, BOOL * _Nonnull stop) {
- if ([key isKindOfClass:[NSString class]] && [(NSString *)key hasPrefix:@"spsb_"]) {
- canReturn = [self handleKey:key Value:obj controller:controller class:class];
- }
- }];
- if (canReturn) {
- return controller;
- } else {
- return nil;
- }
- }
- - (bool)handleKey:(NSString *)key Value:(id)obj controller:(UIViewController *)controller class:(Class)class {
- if (![controller canPerformAction:NSSelectorFromString(key) withSender:nil]) {
- return false;//没有查到类有相关属性
- }
- Class _class = NSClassFromString(_className);
- while ([NSStringFromClass(_class) hasPrefix:@"SPSB"]) {
- objc_property_t property = class_getProperty(class, [key UTF8String]);
- if (property) {
- YYClassPropertyInfo *info = [[YYClassPropertyInfo alloc] initWithProperty:property];
- switch (info.type & YYEncodingTypeMask) {
- case YYEncodingTypeObject: {
- if ([info.cls isSubclassOfClass:[SPSBBaseNetworkModel class]]) {
- if (![obj isKindOfClass:[NSDictionary class]]) {
- return false;//类型不对
- }
- id object = [info.cls performSelector:@selector(getModelWithDictionary:) withObject:obj];
- [controller setValue:object forKey:key];
- return true;
- } else if ([info.cls isSubclassOfClass:[NSString class]]) {
- if (![obj isKindOfClass:[NSString class]] && ![obj isKindOfClass:[NSNumber class]]) {
- return false;//类型不对
- }
- [controller setValue:[NSString stringWithFormat:@"%@", obj] forKey:key];
- return true;
- } else if ([info.cls isSubclassOfClass:[NSNumber class]]) {
- NSNumber *num = spsb_NSNumberCreateFromID(obj);
- if (!num) {
- return false;//类型不对
- }
- [controller setValue:num forKey:key];
- return true;
- } else {
- return false;//不支持类型
- }
- }
- break;
- case YYEncodingTypeBool:
- case YYEncodingTypeInt8:
- case YYEncodingTypeUInt8:
- case YYEncodingTypeInt16:
- case YYEncodingTypeUInt16:
- case YYEncodingTypeInt32:
- case YYEncodingTypeUInt32:
- case YYEncodingTypeInt64:
- case YYEncodingTypeUInt64:
- case YYEncodingTypeFloat:
- case YYEncodingTypeDouble:
- case YYEncodingTypeLongDouble: {
- NSNumber *num = spsb_NSNumberCreateFromID(obj);
- if (!num) {
- return false;//类型不对
- }
- switch (info.type & YYEncodingTypeMask) {
- case YYEncodingTypeBool:
- [controller setValue:num forKey:key];
- break;
- case YYEncodingTypeInt8:
- case YYEncodingTypeInt16:
- case YYEncodingTypeInt32:
- case YYEncodingTypeInt64:
- [controller setValue:@(num.longLongValue) forKey:key];
- break;
- case YYEncodingTypeUInt8:
- case YYEncodingTypeUInt16:
- case YYEncodingTypeUInt32:
- case YYEncodingTypeUInt64:
- [controller setValue:@(num.unsignedLongLongValue) forKey:key];
- break;
- case YYEncodingTypeFloat:
- case YYEncodingTypeDouble:
- case YYEncodingTypeLongDouble:
- [controller setValue:@(num.doubleValue) forKey:key];
- break;
- default:
- break;
- }
-
- return true;
- }
- break;
- default: return false;//不支持类型
- break;
- }
- }
- _class = class_getSuperclass(_class);
- }
- return false;//没有查到类有相关属性
- }
- @end
- @implementation SPSBRouteManager
- + (bool)pageJumpWithData:(NSString *)jump completion:(void (^ _Nullable)(void))completion {
- if ([jump hasPrefix:@"http"]) {
- SPSBHtmlViewController *vc = SPSBHtmlViewController.new;
- vc.spsb_url = jump;
- return [self routeToTarget:vc isNeedLogin:false isNeedNavi:true completion:completion];
- } else if ([jump hasPrefix:@"xsbanruo://"]) {
- NSDictionary *dic = jxh_getUrlPathAndParameters(jump).jxh_parameters;
- if (dic[@"iOS"]) {
- NSString *param = jxh_decode(dic[@"iOS"]);
- debugLog(@"-=-=-=-=-=-=%@", param);
- NSMutableDictionary *dict = [jxh_jsonToDictionary(param) mutableCopy];
- if (dict[@"page"]) {
- SPSBRouter *router = [[SPSBRouter alloc] initWithClassName:dict[@"page"] property:dict tabBarType:SPSBTabBarTypeHome];
- if (dict[@"needNavi"]) {
- router.spsb_needNavi = [dict[@"needNavi"] boolValue];
- }
- if (dict[@"needLogin"]) {
- router.spsb_needLogin = [dict[@"needLogin"] boolValue];
- }
- return [self routeTo:router completion:completion];
- }
- }
- } else if ([jump hasPrefix:@"miniptogram://"]) {
- NSString *path = [jump substringFromIndex:14];
- WXLaunchMiniProgramReq *launchMiniProgramReq = [WXLaunchMiniProgramReq object];
- launchMiniProgramReq.userName = path; //拉起的小程序的username
- launchMiniProgramReq.miniProgramType = WXMiniProgramTypeRelease; //拉起小程序的类型
- [WXApi sendReq:launchMiniProgramReq completion:^(BOOL success) {
- }];
- return false;
- }
- return false;
- }
- + (bool)routeTo:(SPSBRouter *)router completion:(void (^_Nullable)(void))completion {
- UIViewController *targetController = [router getTarget];
- return [self routeToTarget:targetController isNeedLogin:router.spsb_needLogin isNeedNavi:router.spsb_needNavi completion:completion];
- }
- + (bool)routeToTarget:(UIViewController *)target isNeedLogin:(bool)isNeedLogin isNeedNavi:(bool)isNeedNavi completion:(void (^_Nullable)(void))completion {
- if (dispatch_queue_get_label(DISPATCH_CURRENT_QUEUE_LABEL) == dispatch_queue_get_label(dispatch_get_main_queue())) {
- if (!target) {
- return false;
- }
- jxh_windowUserInteractionEnabled(false);
- UIViewController *presentedController = jxh_findPresentedViewControllerStartingFrom(spsb_keyWindow().rootViewController);
- if (!presentedController) {
- jxh_windowUserInteractionEnabled(true);
- return false;
- }
- if (isNeedLogin) {
- jxh_windowUserInteractionEnabled(true);
- spsb_needLogin(^{
- [self routeToTarget:target isNeedLogin:false isNeedNavi:isNeedNavi completion:completion];
- });
- return true;
- }
- if (isNeedNavi) {
- if ([presentedController isKindOfClass:[UINavigationController class]]) {
- [(UINavigationController *)presentedController pushViewController:target animated:true];
- if (completion) {
- dispatch_async(dispatch_get_main_queue(), completion);
- }
-
- } else if (presentedController.navigationController) {
- [presentedController.navigationController pushViewController:target animated:true];
- if (completion) {
- dispatch_async(dispatch_get_main_queue(), completion);
- }
- } else {
- SPSBNavigationController *nav = [[SPSBNavigationController alloc] initWithRootViewController:target];
- nav.modalPresentationStyle = UIModalPresentationFullScreen;
- [presentedController presentViewController:nav animated:true completion:completion];
- }
- } else {
- [presentedController presentViewController:target animated:true completion:completion];
- }
-
- jxh_windowUserInteractionEnabled(true);
- return true;
- } else {
- return false;
- }
- }
- + (void)navigationBackAndRouteTo:(SPSBRouter *)router {
- dispatch_main_async_safe(^{
- jxh_windowUserInteractionEnabled(false);
- [self navigationBackRoot];
- [jxh_appDelegate() changeTabBarType:router.spsb_tabBarType];
-
- UIViewController *viewController = [router getTarget];
- if (viewController) {
- [((SPSBNavigationController *)spsb_keyWindow().rootViewController) pushViewController:viewController animated:true];
- }
- jxh_windowUserInteractionEnabled(true);
- });
-
- }
- + (void)navigationBackRoot {
- dispatch_main_async_safe(^{
- [self navigationBackLastVC];
- });
- }
- + (void)navigationBackLastVC {
- SPSBNavigationController *rootVC = (SPSBNavigationController *)spsb_keyWindow().rootViewController;
- if (![rootVC isKindOfClass:[SPSBNavigationController class]]) return;
- if (rootVC.viewControllers.lastObject.presentedViewController) {
- [rootVC.viewControllers.lastObject dismissViewControllerAnimated:false completion:^{
- [rootVC popToRootViewControllerAnimated:false];
- }];
- } else {
- [rootVC popToRootViewControllerAnimated:false];
- }
- // return;
- // UIViewController *vc = jxh_findPresentedViewControllerStartingFrom(rootVC);
- // if ([vc isEqual:rootVC.viewControllers.firstObject]) return;
- // if (vc.navigationController) {
- // if (vc.navigationController.presentingViewController) {
- // [vc.navigationController.viewControllers.lastObject dismissViewControllerAnimated:false completion:^{
- // [self navigationBackLastVC];
- // }];
- // } else {
- // [vc.navigationController popToRootViewControllerAnimated:false];
- // dispatch_async(dispatch_get_main_queue(), ^{
- // [self navigationBackLastVC];
- // });
- //
- // }
- // } else if (vc.presentingViewController) {
- // [vc dismissViewControllerAnimated:false completion:^{
- // [self navigationBackLastVC];
- // }];
- // } else {
- // return;
- // }
- }
- @end
|