一张图概括H5与原生交互
- (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt
defaultText:(nullable NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame
completionHandler:(void (^)(NSString * _Nullable result))completionHandler
runJavaScriptTextInputPanelWithPrompt方法中获取到JS传给原生的方法。
调用JS与原生定义好的方法名和获取到参数
SEL sel=NSSelectorFromString(methodOne);
SEL selasyn=NSSelectorFromString(methodTwo);
NSDictionary * args=[JSBUtil jsonStringToObject:argStr];
id arg=args[@"data"];
if(arg==[NSNull null]){
arg=nil;
}
定义一个action执行objc_msgsend
void(*action)(id,SEL,id,id) = (void(*)(id,SEL,id,id))objc_msgSend;
action(JavascriptInterfaceObject,selasyn,arg,completionHandler);
定义一个JsApi
//
// JsApiTest.m
//
// Created by 杜文 on 16/12/30.
// Copyright © 2016年 杜文. All rights reserved.
//
#import "JsApiTest.h"
@interface JsApiTest(){
NSTimer * timer ;
void(^hanlder)(id value,BOOL isComplete);
int value;
}
@end
@implementation JsApiTest
- (NSString *) testSyn: (NSString *) msg
{
return [msg stringByAppendingString:@"[ syn call]"];
}
- (void) testAsyn:(NSString *) msg :(JSCallback) completionHandler
{
completionHandler([msg stringByAppendingString:@" [ asyn call]"],YES);
}
- (NSString *)testNoArgSyn:(NSDictionary *) args
{
return @"testNoArgSyn called [ syn call]";
}
- ( void )testNoArgAsyn:(NSDictionary *) args :(JSCallback)completionHandler
{
completionHandler(@"testNoArgAsyn called [ asyn call]",YES);
}
- (void)goBack:(NSString *)dic
{
[[AutoSwitchFlag shared].currentController.navigationController popViewControllerAnimated:YES];
}
/*
dic:js返回给原生的数据
completionHandler:原生回调给js的数据
jumpNativaPage:js调用原生的方法
*/
-(void)jumpNativePage:(NSDictionary *)dic{
/*
原生实现的操作
*/
NSString* routeId = [NSString stringWithFormat:@"%@",[dic objectForKey:@"routeId"]];
if ([routeId isEqualToString:@"HOMEPAGE_ORDER_LIST"]) {
[[AutoSwitchFlag shared].currentController.navigationController popToRootViewControllerAnimated:NO];
[[CRZYCoreRouter shared] pushToTabBarVC:0];
}else if ([routeId isEqualToString:@"RECHARGE"]){
[CRZYCoreRouter shared].showAnimated = NO;
[[CRZYCoreRouter shared] pushToRechargePage];
}else if([routeId isEqualToString:@"AUTHENTICATION"]){
[[CRZYCoreRouter shared] NoneVerifiedPushToVerifyPage];
}
}
-(void)jumpToCheckIn:(NSString *)dic{
/*
原生实现的操作
*/
}
-(void)changeAppBarDisplayStatus:(NSString *)dic{
/*
原生实现的操作
*/
}
-(void)getUserToken:(NSString *)token args :(JSCallback)completionHandler{
NSString* SessionID = [UIKitFactory getCacheValueWithType:LoginValueSESSION];
completionHandler(SessionID,YES);
}
- ( void )callProgress:(NSDictionary *) args :(JSCallback)completionHandler
{
value=10;
hanlder=completionHandler;
timer = [NSTimer scheduledTimerWithTimeInterval:1.0
target:self
selector:@selector(onTimer:)
userInfo:nil
repeats:YES];
}
-(void)onTimer:t{
if(value!=-1){
hanlder([NSNumber numberWithInt:value--],NO);
}else{
hanlder(0,YES);
[timer invalidate];
}
}
/**
* Note: This method is for Fly.js
* In browser, Ajax requests are sent by browser, but Fly can
* redirect requests to native, more about Fly see https://github.com/wendux/fly
* @param requestInfo passed by fly.js, more detail reference https://wendux.github.io/dist/#/doc/flyio-en/native
*/
-(void)onAjaxRequest:(NSDictionary *) requestInfo :(JSCallback)completionHandler{
}
@end
在初始化的时候需要将上述的方法在注册在自定义web view中
// add internal Javascript Object
InternalApis * interalApis= [[InternalApis alloc] init];
interalApis.webview=self;
[self addJavascriptObject:interalApis namespace:@"_dsb"];
- (void) addJavascriptObject:(id)object namespace:(NSString *)namespace{
if(namespace==nil){
namespace=@"";
}
if(object!=NULL){
[javaScriptNamespaceInterfaces setObject:object forKey:namespace];
}
}
接口文档:https://www.showdoc.com.cn/1352616397497535
密码:2021