VKURLAction
基于target-selector 而非基于block注册式的 openURL url参数解析+运行时行为处理,各自行为还需要自定义,定义好行为,无需统一注册,即可生效
Install / Use
/learn @Awhisper/VKURLActionREADME
VKURLAction
整个代码里包括
- openURL模块 VKURLAction
- URL解析模块 VKURLParser
- 中间人模式设计 VKMediatorAction
- runtime工具 VKMsgSend
既然是基于中间人模式,那么VKMediatorAction就是整个代码的核心 VKMediatorAction的主代码并未实现什么核心内容,写了个单例是为了以后可能进行的功能扩展,从现有的代码角度,可以干掉单例,全写成类方法
本地调用
VKMediatorAction的category才是中间人的主要代码所在,使用category的方式便于在业务无限庞大的时候,分拆代码便于管理,可以看demo工程中的VKMediatorAction+webVC.m的源码
-(void)doAlertWebViewControllerWith:(NSString *)title withMainUrl:(NSString *)url
{
Class cls = NSClassFromString(@"WebViewController");
id vc = [[cls alloc]VKCallSelectorName:@"initWithTitle:url:" error:nil,title,url];
[vc VKCallSelectorName:@"doAlertAction" error:nil];
}
-(id)getWebViewControllerWithTitle:(NSString *)title withMainUrl:(NSString *)url
{
Class cls = NSClassFromString(@"WebViewController");
id vc = [[cls alloc]VKCallSelectorName:@"initWithTitle:url:" error:nil,title,url];
return vc;
}
可以看到所有API设计都是native的api,你可以设计任意的参数命名,任意参数种类。
换句话说我们如果想执行本地调用,只需要引入VKMediatorAction,然后调用你想要的api就够了
- (IBAction)native1click:(id)sender {
[[VKMediatorAction sharedInstance] doAlertWebViewControllerWith:@"webview" withMainUrl:@"http://awhisper.github.io"];
}
- (IBAction)native2click:(id)sender {
UIViewController *vc = [[VKMediatorAction sharedInstance]getWebViewControllerWithTitle:@"webview" withMainUrl:@"http://awhisper.github.io"];
[self.navigationController pushViewController:vc animated:YES];
}
需要注意的是,VKMediatorAction+webVC.m内的源码完全不import业务模块,因此需要你使用runtime的方式去调用对应方法,而我的源码里有一个封装的VKMsgSend的工具,使用这个工具可以减少写runtime代码的成本VKCallSelectorName这个方法就是工具提供的,后续还会详细的介绍。
远程调用
当你需要使用url的方式打开界面的时候,首先,你需要让中间人有能力接收url传来的字典型参数,所以特意为上面代码的2个mediatoraction,增加了处理字典参数的版本,可以看到,这个代码最初符合设计初衷,url的action最后还是会调用原来的native的action
-(void)doAlertWebViewControllerWithURLParams:(NSDictionary *)params
{
NSString *title = params[@"title"];
NSString *url = params[@"url"];
[self doAlertWebViewControllerWith:title withMainUrl:url];
}
-(id)getWebViewControllerWithURLParams:(NSDictionary *)params
{
NSString *title = params[@"title"];
NSString *url = params[@"url"];
return [self getWebViewControllerWithTitle:title withMainUrl:url];
}
完成了Mediator对URL参数的支持,其实就已经可以直接使用VKURLAction了
VKURLAction使用
VKURLAction在使用的时候需要提前指定url的scheme和host,经过指定app的scheme和host,凡是不匹配的scheme与host的url都不会进行识别,具体参见demo源码吧,源码很简单不细说了
VKURLAction支持对URL加入sign校验,如果url开启了sign校验功能,所有url必须附带sign参数,并且符合签名校验规则,不然不会进行识别跳转,具体看源码吧,这都是细节,不细说了
只要完成了Mediator对URL参数的支持,其实就已经可以直接使用VKURLAction,比如我们已经写好了getWebViewControllerWithURLParams:方法,那么我们可以直接把getWebViewControllerWithURLParams当做url的path,使用scheme://host/path?params=aa&parms2=bb的形式来打开url,这样就会自动的把url中的参数解析成字典,传入到Mediator得对应方法里
//初始化URLAction
[VKURLAction setupScheme:@"demo" andHost:@"nativeOpenUrl"];
//写url
NSString * url =@"demo://nativeOpenUrl/getWebViewControllerWithURLParams?title=webView&url=http%3A%2F%2Fawhisper.github.io";
//openURL
[VKURLAction doActionWithUrlString:url];
更多使用方法参见demo工程
URL生成
如果不熟悉如何写url,VKURLAction提供了接口来自动生成接口,尤其是开启了签名校验后,url的签名规则会比较复杂,如果想测试,可以使用相关接口来自动生成url,避免手写各种出错
url的参数必须经过url标准的encode,这一点,自动生成url工具已经实现,如果由别的方式生成url(server下发之类的),请注意调试
URL简写
getWebViewControllerWithURLParams当做一个path名字,拼写在url里面实在是有点冗长,并且不好记,因此VKURLAction提供了方法,可以注册简写(注意这不是必须的,不写也一样能够执行url)
//注册简写
[VKURLAction mapKeyword:@"openWeb" toActionName:@"getWebViewControllerWithURLParams"];
//url就可以这么写了
NSString * url =@"demo://nativeOpenUrl/openWeb?title=webView&url=http%3A%2F%2Fawhisper.github.io";
简写注册之后,写url也清爽了不少,也少去了别人猜测我们app代码的问题,╮(╯_╰)╭
URLParser
整个VKURLAction都是依托在URLParser这个模块之上,他可以进行解析url,识别出url种的scheme,host,识别出url种的path,识别出url种的每一个参数,拼接成字典,校验签名的可靠性,具体代码见源码吧这块不是很复杂
Cocoapods支持
尝试了一把发布到cocoapods上 因此可以使用pod导入
target 'VKURLActionDemo' do
pod 'VKURLAction'
end
Related Skills
node-connect
340.2kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
frontend-design
84.1kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
openai-whisper-api
340.2kTranscribe audio via OpenAI Audio Transcriptions API (Whisper).
commit-push-pr
84.1kCommit, push, and open a PR
