VDWebView提供了最全的API调用和最方便的JS交互方式,可经过pod更新迭代;设计方案为Protocol和Target-Action;有任何意见或者问题欢迎指出。html
pod 'VDWebView', '~> 1.0.3'
复制代码
WKWebView
是iOS8后推出的WebKit框架中的控件,因为iOS12后已经弃用UIWebView
了并且如今的大多数项目只适配到iOS8UIWebView
且解决了加载网页时的内存泄露问题WKUserContentController
UIWebView
代理方法,处理对象(WKNavigationDelegate
)/// 类UIWebView代理方法
- (void)webViewDidStartLoad:(VDWebView *)webView;
- (void)webViewDidFinishLoad:(VDWebView *)webView;
- (void)webView:(VDWebView *)webView didFailLoadWithError:(NSError *)error;
- (BOOL)webView:(VDWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType;
复制代码
WKUIDelegate
和WKScriptMessageHandler
代理的合并/**
JS调原生代理方法(注册了过的方法将所有经过此方法回调)
*/
- (void)webView:(VDWebView *)webView didReceiveScriptMessage:(WKScriptMessage *)message;
/**
JS弹框拦截方法--若是须要自定义弹框建议声明此方法
*/
- (void)webView:(VDWebView *)webView showAlertWithType:(VDJSAlertType)type title:(NSString *)title content:(NSString *)content completionHandler:(void (^)(id))completionHandler;
复制代码
详情可见VDWebViewProtocol
java
///预估网页加载进度
@property (nonatomic, readonly) CGFloat estimatedProgress;
// 是否显示进度条 默认不显示
@property (nonatomic, assign) BOOL isShowProgressBar;
///进度条
@property (nonatomic, strong) UIView *progressBar;
/**
web页面加载完毕后的内容高度(在页面加载完成后获取)
*/
@property (nonatomic, readonly) CGFloat *contentHeight;
/// 是否启用js调用原生弹框 默认为NO 禁止(默认加载弹框在根试图)
@property (nonatomic, assign) BOOL enableAllAlert;
@property (nonatomic, assign) BOOL enableAlert;
@property (nonatomic, assign) BOOL enableConfirm;
@property (nonatomic, assign) BOOL enablePrompt;
///back 层数
- (NSInteger)countOfHistory;
- (void)gobackWithStep:(NSInteger)step;
复制代码
在使用WKWebView
时咱们须要调用WKWebView
内configuration
中的userContentController
所属类WKUserContentController
提供的实例方法进行注册,具体方法以下:git
- (void)addScriptMessageHandler:(id <WKScriptMessageHandler>)scriptMessageHandler name:(NSString *)name;
复制代码
对应的注销方法为:github
- (void)removeScriptMessageHandlerForName:(NSString *)name;
复制代码
在使用addScriptMessageHandler:name:
方法注册时传入的这个handler被循环引用,若是不调用对应的注销方法就会致使handler这个对象没法被释放,若是你这个handler传入是webView所在的控制器,那么你就要在销毁这个控制器前注销掉你注册的方法.web
tip: 如何知道控制器有没有被释放,重写dealloc(),没走此方法说明未被释放json
简要分析可分为下面三步安全
VDScripMessageHandler
做为注册的handler
WKScriptMessageHandler
VDWebView
的dealloc()
方法中获取注册记录并注销这些作的好处在于你在使用VDWebView时无需本身去一个个手动注销了(若是你注册的方法多的话那就是噩梦了)bash
- (void)addScriptMessageHandler:(id)scriptMessageHandler name:(NSString *)name;
复制代码
// 没效果可以使用try-catch
window.webkit.messageHandlers.#OC方法名#.postMessage(#参数#)
复制代码
回调方式分两种:delegate和target-action; 两种方式只能存一,优先delegatecookie
VDWebViewDelegate
中的方法- (void)webView:(VDWebView *)webView didReceiveScriptMessage:(WKScriptMessage *)message;
复制代码
target-action:目标-动做模式,拜C语言所赐,更是灵活不少,编译期没有任何检查,都是运行时的绑定框架
VDWebView
中就是经过NSSelectorFromString()
动态加载方法,再经过NSMethodSignature
和NSInvocation
进行方法的签名和调用可经过两种方式进行JS方法的调用,推荐第一种
- (void)evaluateJavaScript:(NSString *)javaScriptString completionHandler:(void (^)(id, NSError *))completionHandler;
复制代码
- (NSString *)stringByEvaluatingJavaScriptFromString:(NSString *)javaScriptString;
复制代码
脚本的注入和移除
/**
注入脚本(js...)
*/
- (void)addUserScriptWithSource:(NSString *)source injectionTime:(WKUserScriptInjectionTime)injectionTime forMainFrameOnly:(BOOL)mainFrameOnly;
/**
移除全部注入的脚本
*/
- (void)removeAllUserScripts;
复制代码
VDWebViewCookiesProtocol
因为WKWebView的cookie是和NSHTTPCookieStorage不共享,这就形成使用WKWebView打开的web页面没法获取到经过原生请求登陆的cookie,固然其它解决方案有不少种,好比
可是用了VDWebView就不须要考虑cookie的问题了,由于它已经默认把cookie带过去了,固然你也能够手动去关闭
/**
不一样步NSHTTPCookieStorage存储的cookies 默认同步:NO
同步NSHTTPCookieStorage中的cookie到WKWebView中,有可能会污染WKWebView中的cookie管理
*/
@property (nonatomic, assign)BOOL httpCookiesDisable;
复制代码
/**
设置cookie
*/
- (void)setCookieWithKey:(NSString *)key value:(NSString *)value expires:(NSTimeInterval)expires domain:(NSString *)domain;
- (void)setCookies:(NSString *)cookies;
/**
获取cookie
*/
- (NSArray *)getCookies;
复制代码
VDWebViewJSBridge
你只须要调用VDWebView
继承的协议VDWebViewProtocol
所提供的初始化方法bridgeInitialized
便可
// 调用初始化 在webView的控制器中实现同名方法
self.webView.delegate = self;
[self.webView bridgeInitialized];
复制代码
与对应的js配套使用,此方案适用于iOS和Android对应的js文件以下
// 在js中直接调用VDJSWebBridge.js提供的方法,详情请查看js
// methodName为控制器中声明的方法名,params为json字符串
vd_jsBridge(methodName, params)
复制代码
// JS 方法
function jsMethod(param1, param2, param3) {
alert("使用jsBridge调用js方法成功参数为:"+param1+param2+param3)
return "success";
}
// OC调用JS方法
[self.webView.bridge executeJsMethod:@"jsMethod" params:@[@"1",@"2",@"3"] completionHandler:^(id result, NSError *error) {
NSLog(@"\njs方法执行h结果回调:%@\n错误信息:%@",result,error);
}];
复制代码