在SDK中 无法直接跳App 的界面,这个时候需要使用 路由,或者通过 NSClassFromString 的

presentViewController 来跳转。

直接贴代码:

UIViewController *VC = [NSClassFromString(@"WZFullmotionPagesController") new];

    id prepareAction = ^(void (^ _Nonnull success)(void)) {

        UIViewController *VC1 = [NSClassFromString(@"WZServiceSelectController") new];
id prepareAction1 = ^(void) {
if (success) success();
};
[VC1 setValue:prepareAction1 forKey:@"defaultSetCMCCallBack"]; [self.navigationController pushViewController:VC1 animated:YES];
[VC1.view setNeedsDisplay];
}; [VC setValue:prepareAction forKey:@"prepareAction"];
[self presentViewController:VC animated:YES completion:nil];

有时候需要回调,可以再回调里 继续添加跳转

路由的使用:
有的控制器 需要先添加路由的方式,再根据plist 来调用

- (void)router:(WPKRouterAction *)action setParam:(WPKRParamModelBase *)param block:(WPKRouterBlock)block
{
//这里可以处理逻辑
NSDictionary *dict = (NSDictionary *)param;
WPKNameCamSetingController *VC = [[WPKNameCamSetingController alloc] init];
VC.deviceMac = dict [@"deviceMac"];
VC.deviceModel = dict [@"deviceModel"];
VC.nameCamsSetingType = dict[@"nameCamsSetingType"];
VC.progress = dict[@"progress"];
VC.saveBtnStr = dict[@"saveBtnStr"];
VC.routeAddress = dict[@"routeAddress"];
VC.routeAguments = dict[@"routeAguments"];
WPKRCallbackModel *callbackModel = [[WPKRCallbackModel alloc] init];
VC.NameCamSetingFinishClick = ^(NSString * _Nonnull code){
callbackModel.object = code;
block(callbackModel);
};
[[WPKUIUtils topViewController].navigationController pushViewController:VC animated:YES]; }

路由的具体实现

//
// WPKRouter.m
// WZPlatformKit
//
// Created by abc on 2019/4/30.
// Copyright © 2019 米家. All rights reserved.
// #import "WPKRouter.h"
#import "WPKRCallbackModel.h"
#import "WPKRParamModelBase.h"
#import "WPKRouterAction.h"
#import "WPKRouterUtil.h"
#import "WPKSerializationHelper.h"
#import <objc/runtime.h>
#import "WPKRouterPool.h" //router内部存储actionModel时,给参数增加识别码,用于业务结束操作时回传该识别码,注销actionmodel
static NSString * const WPK_ROUTER_KEY_STRING = @"WPK_ROUTER_KEY_STRING"; static NSString * const WPK_ROUTER_CLASS_PREFIX = @"WPK_router_executor_";
static NSString * const WPK_ROUTER_FUNC_PREFIX = @"retriveSelectorFor_"; typedef void (^WPKRouterH5Block)(WPKRCallbackModel *result, WPKRParamModelBase *modleBase); @interface WPKRouter()
@property (atomic, strong) WPKRouterAction *actionModel; /**
存储 WPKRouterAction 对象
*/
@property (nonatomic,strong)NSMutableArray * actionModelArray;
@property (nonatomic,strong)NSMutableDictionary * actionModeKeyDic; @end @implementation WPKRouter
#pragma mark - life cycles
+ (id)allocWithZone:(struct _NSZone *)zone
{
return [WPKRouter sharedInstance];
} + (instancetype)sharedInstance
{
static WPKRouter *inst;
static dispatch_once_t once_t;
dispatch_once(&once_t, ^{
inst = [[super allocWithZone:NULL] init];
});
return inst;
} - (instancetype)init
{
self = [super init];
if (self) {
_util = [[WPKRouterUtil alloc] init];
}
return self;
} #pragma mark - public - (id)callCls:(NSString *)cls sel:(NSString *)sel params:(NSArray *)params
{
// 获取类名
NSString *target = [NSString stringWithFormat:@"%@%@", WPK_ROUTER_CLASS_PREFIX, cls];
Class c = NSClassFromString(target);
if (c) {// 获取函数名获取器
NSString *action = [NSString stringWithFormat:@"%@%@", WPK_ROUTER_FUNC_PREFIX, sel];
SEL objSel = NSSelectorFromString(action);
NSObject * obj = [[c alloc] init];
if ([obj respondsToSelector:objSel]) {
// 警告!!!此处认为router框架增加的方法固定返回SEL类型,util方法返回字符串 SEL realSel = NSSelectorFromString([WPKRouterUtil performObject:obj selector:objSel withArguments:@[sel]]);
NSObject *realObj = (NSObject *)[WPKRouterPool excutorForPaths:cls, sel, nil]; // 查看路由池是否有对应的对象
if (realObj && realSel && [realObj respondsToSelector:realSel]) {
id res = [WPKRouterUtil performObject:obj selector:realSel withArguments:params];
return res;
} else if (realSel && [obj respondsToSelector:realSel]) {
//路由池无对象则使用新建的子类对象
id res = [WPKRouterUtil performObject:obj selector:realSel withArguments:params];
return res;
} else {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wformat"
WPKInfoLog(@"ERROR: router can't find selector: %s", realSel);
#pragma clang diagnostic pop
}
} else {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wformat"
WPKInfoLog(@"ERROR: router can't find selector: %s", objSel);
#pragma clang diagnostic pop
}
}
return nil;
} #pragma mark - private
- (void)pushActionModel:(WPKRouterAction*)model routerKey:(NSString *)routerKey
{
@synchronized(self) {
if (model.excutor && model.catchCallBack) {
[self.actionModelArray addObject:model];
self.actionModeKeyDic[routerKey] = model;
}
}
} - (void)popActionModelWithRouterKey:(NSString *)routerKey
{
@synchronized(self) {
WPKRouterAction * model = self.actionModeBlockDic[routerKey];
if (model.catchCallBack) {
[self.actionModelArray removeObject:model];
[self.actionModeKeyDic removeObjectForKey:routerKey];
}
}
} #pragma mark - publics /**
* H5调用WPK协议入口
*
* @param url url
*/
- (void)startUrl:(NSURL *)url
{
//通过mwap执行参数回调
WPKRouterH5Block block = ^(WPKRCallbackModel *result, WPKRParamModelBase *modleBase) {
if (result.object) {
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
result.object != nil ? [dict setObject:result.object forKey:@"content"] : nil;
modleBase.flagId != nil ? [dict setObject:modleBase.flagId forKey:@"flagId"] : nil;
[[WPKRouter sharedInstance] startModuleSecoupled:@"mwap" path:@"servicecallback" paramDict:dict block:nil];
}
};
[self callNativeFromH5Url:url block:block]; } - (void)startUrl:(NSURL *)url callback:(WPKRouterBlock)callback
{
WPKRouterH5Block block = ^(WPKRCallbackModel *result, WPKRParamModelBase *modleBase) {
callback(result);
};
[self callNativeFromH5Url:url block:block];
} //H5专用
- (void)callNativeFromH5Url:(NSURL *)url block:(WPKRouterH5Block)block
{
NSString *module = [_util getModuleStrFromUrl:url];//module
NSString *path = [_util getPathStrFromUrl:url]; //path
NSString *paramStr = [_util getParamStrFromUrl:url]; //param WPKRouterAction *actionModel = [_util getActionFromModule:module path:path]; if (![actionModel excutor]) {
[self handleOldVersionWithUrl:url];//兼容老的WPK协议跳转
return;
} if (!module || !path ) {
WPKRouterBlock temp = ^(WPKRCallbackModel *result) {
block(result, nil);
};
if (path) {
[_util goto404Error:[module stringByAppendingPathComponent:path] withBlock:temp];
}
return;
} NSDictionary *paramDic = [_util getParametersDictionaryWithParams:paramStr]; WPKRParamModelBase*param;
if ([actionModel.in length] > ) {
Class paramClass = NSClassFromString(actionModel.in);
param = [[paramClass alloc] init];
} else {
//h5不设置入参,只需要flagID
param = [[WPKRParamModelBase alloc] init];
}
if ([param isKindOfClass:[WPKRParamModelBase class]]) {
param.originURL = url;
}
[[WPKSerializationHelper sharedInstance] importDictionary:paramDic toObject:param]; WPKRouterBlock blocktemp = ^(WPKRCallbackModel *result) {
block(result, param);
};
[self startModule:module path:path param:param block:blocktemp];
} - (void)startModule:(NSString *)kWPKRouter_M
path:(NSString *)kWPKRouter_M_P
param:(WPKRParamModelBase *)param
block:(WPKRouterBlock)block
{
WPKInfoLog(@">> WPKRouter: %@/%@ param: %@",kWPKRouter_M, kWPKRouter_M_P, param );
WPKRouterAction *WPKActionModel = [_util getActionFromModule:kWPKRouter_M
path:kWPKRouter_M_P];
if (!param) {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wincompatible-pointer-types"
param = [NSObject new];
#pragma clang diagnostic pop
}
param.routerKey = [self getDateNow];
[self pushActionModel:WPKActionModel routerKey:param.routerKey];
[self handleAction:WPKActionModel paramModel:param block:block];
} - (void)startModuleSecoupled:(NSString *)kWPKRouter_M
path:(NSString *)kWPKRouter_M_P
paramDict:(NSDictionary *)paramDict
block:(WPKRouterBlock)block
{
WPKRouterAction *WPKActionModel = [_util getActionFromModule:kWPKRouter_M
path:kWPKRouter_M_P];
WPKActionModel.navigationController = self.navigationController;
if (!paramDict) {
paramDict = [NSDictionary new];
}
paramDict.routerKey = [self getDateNow];
[self pushActionModel:WPKActionModel routerKey:paramDict.routerKey];
WPKRParamModelBase*paramModel;
if ([WPKActionModel.in length] > ) {
Class paramClass = NSClassFromString(WPKActionModel.in);
paramModel = [[paramClass alloc] init];
} else {
//h5不设置入参,只需要flagID
paramModel = [[WPKRParamModelBase alloc] init];
} if ([paramModel respondsToSelector:@selector(analyzeWPKRouterModelWithModelInfo:)]) {
[paramModel analyzeWPKRouterModelWithModelInfo:paramDict];
} else if ([paramModel isKindOfClass:[NSDictionary class]]) {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wincompatible-pointer-types"
paramModel = paramDict;
#pragma clang diagnostic pop
} else {
[[WPKSerializationHelper sharedInstance] importDictionary:paramDict toObject:paramModel];
}
/*
由于 mj_setKeyValues 方法不能将动态添加的属性转到相应的模型中所以进行如此修改
*/
paramModel.routerKey = paramDict.routerKey;
[self handleAction:WPKActionModel paramModel:paramModel block:block];
} - (id)readDataModuleSecoupled:(NSString *)kWPKRouter_M
path:(NSString *)kWPKRouter_M_P
paramDict:(NSDictionary *)paramDict
{
WPKRouterAction *WPKActionModel = [_util getActionFromModule:kWPKRouter_M
path:kWPKRouter_M_P];
WPKActionModel.navigationController = self.navigationController;
if (!paramDict) {
paramDict = [NSDictionary new];
}
paramDict.routerKey = [self getDateNow];
[self pushActionModel:WPKActionModel routerKey:paramDict.routerKey];
WPKRParamModelBase*paramModel;
if ([WPKActionModel.in length] > ) {
Class paramClass = NSClassFromString(WPKActionModel.in);
paramModel = [[paramClass alloc] init];
} else {
//h5不设置入参,只需要flagID
paramModel = [[WPKRParamModelBase alloc] init];
} if ([paramModel respondsToSelector:@selector(analyzeWPKRouterModelWithModelInfo:)]) {
[paramModel analyzeWPKRouterModelWithModelInfo:paramDict];
} else if ([paramModel isKindOfClass:[NSDictionary class]]) {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wincompatible-pointer-types"
paramModel = paramDict;
#pragma clang diagnostic pop
} else {
[[WPKSerializationHelper sharedInstance] importDictionary:paramDict toObject:paramModel];
}
/*
由于 mj_setKeyValues 方法不能将动态添加的属性转到相应的模型中所以进行如此修改
*/
paramModel.routerKey = paramDict.routerKey;
return [self handleAction:WPKActionModel paramModel:paramModel];
} - (NSString *)composeURLForModule:(NSString *)kWPKRouter_M
path:(NSString *)kWPKRouter_M_P
param:(WPKRParamModelBase *)param
iswithScheme:(BOOL)isWithScheme { NSString *json = @"";
if (param) {
json = [param toJsonString];
}
NSString *scheme = [NSString stringWithFormat:@"%@://", kWPKRouter_scheme];
NSString *url = [NSString stringWithFormat:@"%@%@/%@?%@=%@",
isWithScheme?scheme:@"",
kWPKRouter_M,
kWPKRouter_M_P?kWPKRouter_M_P:kWPKRouter_default_path,
kWPKRouter_paramName,
[json stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLHostAllowedCharacterSet]]
]; return url;
}
/**
* 解析url数据
*
* @param urlString url
*
* @return 返回地址中存在的参数数据模型
*/
- (nullable WPKRParamModelBase *)parseParamModelWithUrl:(NSString *)urlString;
{
NSURL *url = [NSURL URLWithString:urlString]; //module
NSString *module = [_util getModuleStrFromUrl:url];
if (module == nil) {
return nil;
}
//path
NSString *path = [_util getPathStrFromUrl:url];
if (path == nil) {
return nil;
}
//param
NSString *paramStr = [_util getParamStrFromUrl:url]; WPKRouterAction *actionModel = [_util getActionFromModule:module path:path];
if (paramStr && actionModel.in) {
NSDictionary *paramDic = [_util getParametersDictionaryWithParams:paramStr];
WPKRParamModelBase *model = [(WPKRParamModelBase *) [NSClassFromString(actionModel.in) alloc] init];
[[WPKSerializationHelper sharedInstance] importDictionary:paramDic toObject:model];
return model;
}
return nil;
} -(void)callbackAction:(WPKRouterBlock)block result:(id)obj paramIn:(NSObject *)inModel error:(NSError *)error
{
NSString *key=@""; if ([inModel.routerKey length] > ) {
key = inModel.routerKey;
}
if ([self.actionModeBlockDic.allKeys containsObject:key]) {
[self popActionModelWithRouterKey:key];
} WPKRCallbackModel *model = [[WPKRCallbackModel alloc]init];
if ([obj isKindOfClass:[NSString class]]) {
model.object = @{@"result":obj};
} else {
model.object = obj;
}
model.code = (int)error.code;
model.errorMessage=error.localizedDescription;
if (block) {
block(model);
} }
- (void)callbackAction:(WPKRouterBlock)block result:(id)obj
{
[self callbackAction:block result:obj paramIn:nil];
} - (void)callbackAction:(WPKRouterBlock)block result:(id)obj paramIn:(NSObject *)inModel
{
[self callbackAction:block result:obj paramIn:inModel error:nil];
} - (BOOL)canCheckModel:(NSString *)kWPKRouter_M path:(NSString *)kWPKRouter_M_P
{
return [self canCheckModel:[_util getActionFromModule:kWPKRouter_M path:kWPKRouter_M_P]];
} - (BOOL)canCheckUrl:(NSURL *)url
{
return [self canCheckModel:[_util getActionFromModule:[_util getModuleStrFromUrl:url] path:[_util getPathStrFromUrl:url]]];
} - (BOOL)canCheckModel:(WPKRouterAction *)actionModel
{
if (actionModel == nil || actionModel.excutor.length == ) {
return NO;
} Class class = NSClassFromString(actionModel.excutor);
if (class == nil || class == [NSNull null]) {
return NO;
} return YES;
}
#pragma mark - 检测WPK协议是否存在 - (BOOL)startCheckSupportURL:(NSURL *)url
{
//module
NSString *module = [_util getModuleStrFromUrl:url];
//path
NSString *path = [_util getPathStrFromUrl:url];
//param
NSString *paramStr = [_util getParamStrFromUrl:url]; WPKRouterAction *actionModel = [_util getActionFromModule:module path:path];
WPKRParamModelBase*param;
if ([actionModel.in length] > ) {
Class paramClass = NSClassFromString(actionModel.in);
param = [[paramClass alloc] init];
} else {
//h5不设置入参,只需要flagID
param = [[WPKRParamModelBase alloc] init];
} NSDictionary *paramDic = [_util getParametersDictionaryWithParams:paramStr];
[[WPKSerializationHelper sharedInstance] importDictionary:paramDic toObject:param]; return [self startCheckSupportModule:module path:path param:param];
} - (BOOL)startCheckSupportURLString:(NSString *)urlString{ if (!urlString || ![urlString isKindOfClass:[NSString class]] || ![urlString hasPrefix:@"WPK://"]) {
return NO;
} NSURL *url = [NSURL URLWithString:urlString];
if (!url) {
urlString = [urlString stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
// urlString = [urlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
url = [NSURL URLWithString:urlString];
} return [self startCheckSupportURL:url];
} - (BOOL)startCheckSupportModule:(NSString *)kWPKRouter_M
path:(NSString *)kWPKRouter_M_P
param:(WPKRParamModelBase*)param
{
WPKRouterAction *WPKActionModel = [_util getActionFromModule:kWPKRouter_M
path:kWPKRouter_M_P];
if (![WPKActionModel excutor]) {
return NO;
} else {
//参数判断
if ([WPKActionModel.in length] > ) {
Class paramClass = NSClassFromString(WPKActionModel.in);
if (param && ![param isKindOfClass:paramClass]) {
return NO;
}
}
return YES;
}
} #pragma mark - private method - (void)handleAction:(WPKRouterAction *)action
paramModel:(NSObject*)paramModel
block:(WPKRouterBlock)block
{
if (![action excutor]) {
[_util goto404Error:[action.moduleName stringByAppendingPathComponent:action.pathName] withBlock:block];
} else {
if ([paramModel isKindOfClass:[WPKRParamModelBase class]]) {
action.url = [(WPKRParamModelBase*)paramModel originURL];
}
if ([action.in length] > ) {
Class paramClass = NSClassFromString(action.in);
if (paramModel && ![paramModel isKindOfClass:paramClass]) {
[_util goto404Error:[action.moduleName stringByAppendingPathComponent:action.pathName] withBlock:block];
return;
}
}
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wincompatible-pointer-types"
[action doActionWithParam:paramModel block:block];
#pragma clang diagnostic pop
} self.actionModel = action;
} - (id)handleAction:(WPKRouterAction *)action
paramModel:(NSObject *)paramModel
{
self.actionModel = action;
if (![action excutor]) {
[_util goto404Error:[action.moduleName stringByAppendingPathComponent:action.pathName] withBlock:nil];
} else {
if ([paramModel isKindOfClass:[WPKRParamModelBase class]]) {
action.url = [(WPKRParamModelBase*)paramModel originURL];
}
if ([action.in length] > ) {
Class paramClass = NSClassFromString(action.in);
if (paramModel && ![paramModel isKindOfClass:paramClass]) {
[_util goto404Error:[action.moduleName stringByAppendingPathComponent:action.pathName] withBlock:nil];
return nil;
}
}
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wincompatible-pointer-types"
return [action doActionWithParam:paramModel];
#pragma clang diagnostic pop
}
return nil;
} #pragma mark - 失败回调 - (void)handleOldVersionWithUrl:(NSURL *)url
{
/* WPK://qrcode:1#feedId:o_1462533315926565
WPK://c-2345
*/ // 浏览器对第二个#进行了混乱解析,
NSString *newAbsoluteString = [url.absoluteString stringByReplacingOccurrencesOfString:@"%23" withString:@"#"];
NSDictionary *dict = @{@"WPKUrl":newAbsoluteString.length?newAbsoluteString:@""};
[self startModuleSecoupled:@"qrcode" path:@"qrcodeTool" paramDict:dict block:nil];
} - (NSMutableArray *)actionModelArray
{
if (!_actionModelArray) {
_actionModelArray = [NSMutableArray arrayWithCapacity:];
}
if (_actionModelArray.count >= ) {
NSArray * keyArr = self.actionModeBlockDic.allKeys;
for (NSString * key in keyArr) {
if ([self.actionModeBlockDic[key] isEqual:_actionModelArray.firstObject]) {
[_actionModelArray removeObject:_actionModelArray.firstObject];
[self.actionModeBlockDic removeObjectForKey:key];
break;
}
}
}
return _actionModelArray;
} - (NSMutableDictionary *)actionModeBlockDic
{
if (!_actionModeKeyDic) {
_actionModeKeyDic = [NSMutableDictionary dictionary];
}
return _actionModeKeyDic;
} - (NSString *)getDateNow
{
NSDate* dat = [NSDate dateWithTimeIntervalSinceNow:];
NSTimeInterval a=[dat timeIntervalSince1970]*;
NSString *timeString = [NSString stringWithFormat:@"%f", a];
return timeString;
} @end @implementation NSObject(WPKRouterExtension)
- (NSString *)routerKey
{
return objc_getAssociatedObject(self, (__bridge const void *)(WPK_ROUTER_KEY_STRING));
} - (void)setRouterKey:(NSString *)routerKey
{
objc_setAssociatedObject(self, (__bridge const void *)(WPK_ROUTER_KEY_STRING), routerKey, OBJC_ASSOCIATION_COPY);
}
@end

App 调用插件代码 及传参

//    [[WPKRouter sharedInstance] startModuleSecoupled:WPK_kPlatformName path:wpk_kNameCamSetting paramDict:@{@"deviceMac":@"2CAA8E21AEC7",@"deviceModel":@"XXXC1-JZ",@"nameCamsSetingType":WPK_Type_bding,@"routeAddress":@"namecamseting",@"progress":@"0.75"} block:^(WPKRCallbackModel *result) {
// }];

plist文件 设置

基础架构

最新文章

  1. Git项目存放位置在导入Eclipse前不能存放在Eclipse Workspace
  2. Qt 子窗体嵌入父窗体
  3. [转]快速构建App界面的框架(●&#39;◡&#39;●) -----SalutJs
  4. 魔改——MDI多视图模板Tab/标签页 初始化/操作控件
  5. SharePoint开发 - 自定义导航菜单(三)附其他代码
  6. Silverlight中本地化的实现(语言切换)
  7. EasyMock 使用方法与原理剖析--转载
  8. 扩大按钮 btn 响应区域
  9. Linux安装JDK步骤
  10. 质量管理:PDCA循环
  11. Entangle 2.0 “Sodium”正式发布
  12. 最详细最全的redis配置文件解释
  13. wx:Textctrl
  14. sql server 2008 R2
  15. 课时26.a标签其它属性(掌握)
  16. 思辨“从外至内的认识和表达”——By Me at 20140928
  17. Ubuntu下安装keras
  18. spring中aop原理
  19. P2819 图的m着色问题
  20. Android系统OTA升级包制作【转】

热门文章

  1. 纪中10日T1 2313. 动态仙人掌
  2. P4197 Peaks [克鲁斯卡尔重构树 + 主席树][克鲁斯卡尔重构树学习笔记]
  3. python + excel工资条自动生成
  4. Java商城秒杀系统的设计与实战视频教程(SpringBoot版)
  5. JavaSE学习笔记(3)---面向对象三大特性
  6. Bubble Sort HDU - 5775 树状数组
  7. tsocks代理git wget
  8. C 库函数 - fmod()
  9. The Number of Inversions(逆序数)
  10. 爬虫爱用的一些python技巧