iOS WKWebView使用总结
点击上方“iOS开发”,选择“置顶公众号”
关键时刻,第一时间送达!
先不说楚枫的这般年纪,能够踏入元武一重说明了什么,最主要的是,楚枫在刚刚踏入核心地带时,明明只是灵武七重,而在这两个月不到的时间,连跳两重修为,又跳过一个大境界,踏入了元武一重,这般进步速度,简直堪称变态啊。
“这楚枫不简单,原来是一位天才,若是让他继续成长下去,绝对能成为一号人物,不过可惜,他太狂妄了,竟与龚师兄定下生死约战,一年时间,他再厉害也无法战胜龚师兄。”有人认识到楚枫的潜力后,为楚枫感到惋惜。
“哼,何须一年,此子今日就必败,巫九与龚师兄关系甚好,早就看他不顺眼了,如今他竟敢登上生死台挑战巫九,巫九岂会放过他?”但也有人认为,楚枫今日就已是在劫难逃。
“何人挑战老子?”就在这时,又是一声爆喝响起,而后一道身影自人群之中掠出,最后稳稳的落在了比斗台上。
这位身材瘦弱,身高平平,长得那叫一个猥琐,金钩鼻子蛤蟆眼,嘴巴一张牙带色儿,说话臭气能传三十米,他若是当面对谁哈口气,都能让那人跪在地上狂呕不止。
不过别看这位长得不咋地,他在核心地带可是鼎鼎有名,剑道盟创建者,青龙榜第九名,正是巫九是也。
“你就是巫九?”楚枫眼前一亮,第一次发现,世间还有长得如此奇葩的人。
巫九鼻孔一张,大嘴一咧,拍着那干瘪的肚子,得意洋洋的道:“老子就是巫九,你挑战老子?”
“不是挑战你,是要宰了你。”楚枫冷声笑道。
“好,老子满足你这个心愿,长老,拿张生死状来,老子今日在这里了解了这小子。”巫九扯开嗓子,对着下方吼了一声。
如果他对内门长老这么说话,也就算了,但是敢这么跟核心长老说话的,他可真是算作胆肥的,就连许多核心弟子,都是倒吸了一口凉气,心想这楚枫够狂,想不到这巫九更狂。
不过最让人无言的就是,巫九话音落下不久,真有一位核心长老自人群走出,缓缓得来到了比斗台上,左手端着笔墨,右手拿着生死状,来到了巫九的身前。
“我去,这巫九什么身份,竟能这般使唤核心长老?”有人吃惊不已,那长老修为不低,乃是元武七重,比巫九还要高两个层次,但却这般听巫九的话,着实让人吃惊不已。
“这你就不知道了吧,巫九在前些时日,拜了钟离长老为师尊,已正式得到钟离长老的亲传。”有人解释道。
“钟离长老?可是那位性情古怪的钟离一护?”
“没错,就是他。”
“天哪,巫九竟然拜入了他的门下?”
人们再次大吃一惊,那钟离一护在青龙宗可是赫赫有名,若要是论其个人实力,在青龙宗内绝对能够排入前三,连护宗六老单打独斗都不会是他的对手。
只不过那钟离一护,如同诸葛青云一样,也是一位客卿长老,所以在青龙宗内只是挂个头衔,什么事都不管,更别说传授宗内弟子技艺了,如今巫九竟然能拜入他老人家门下,着实让人羡慕不已。
“恩怨生死台,的确可以决斗生死,但必须要有所恩怨,你们两个人,可有恩怨?”那位长老开口询问道。
先不说楚枫的这般年纪,能够踏入元武一重说明了什么,最主要的是,楚枫在刚刚踏入核心地带时,明明只是灵武七重,而在这两个月不到的时间,连跳两重修为,又跳过一个大境界,踏入了元武一重,这般进步速度,简直堪称变态啊。
“这楚枫不简单,原来是一位天才,若是让他继续成长下去,绝对能成为一号人物,不过可惜,他太狂妄了,竟与龚师兄定下生死约战,一年时间,他再厉害也无法战胜龚师兄。”有人认识到楚枫的潜力后,为楚枫感到惋惜。
“哼,何须一年,此子今日就必败,巫九与龚师兄关系甚好,早就看他不顺眼了,如今他竟敢登上生死台挑战巫九,巫九岂会放过他?”但也有人认为,楚枫今日就已是在劫难逃。
“何人挑战老子?”就在这时,又是一声爆喝响起,而后一道身影自人群之中掠出,最后稳稳的落在了比斗台上。
这位身材瘦弱,身高平平,长得那叫一个猥琐,金钩鼻子蛤蟆眼,嘴巴一张牙带色儿,说话臭气能传三十米,他若是当面对谁哈口气,都能让那人跪在地上狂呕不止。
不过别看这位长得不咋地,他在核心地带可是鼎鼎有名,剑道盟创建者,青龙榜第九名,正是巫九是也。
“你就是巫九?”楚枫眼前一亮,第一次发现,世间还有长得如此奇葩的人。
巫九鼻孔一张,大嘴一咧,拍着那干瘪的肚子,得意洋洋的道:“老子就是巫九,你挑战老子?”
“不是挑战你,是要宰了你。”楚枫冷声笑道。
“好,老子满足你这个心愿,长老,拿张生死状来,老子今日在这里了解了这小子。”巫九扯开嗓子,对着下方吼了一声。
如果他对内门长老这么说话,也就算了,但是敢这么跟核心长老说话的,他可真是算作胆肥的,就连许多核心弟子,都是倒吸了一口凉气,心想这楚枫够狂,想不到这巫九更狂。
不过最让人无言的就是,巫九话音落下不久,真有一位核心长老自人群走出,缓缓得来到了比斗台上,左手端着笔墨,右手拿着生死状,来到了巫九的身前。
“我去,这巫九什么身份,竟能这般使唤核心长老?”有人吃惊不已,那长老修为不低,乃是元武七重,比巫九还要高两个层次,但却这般听巫九的话,着实让人吃惊不已。
“这你就不知道了吧,巫九在前些时日,拜了钟离长老为师尊,已正式得到钟离长老的亲传。”有人解释道。
“钟离长老?可是那位性情古怪的钟离一护?”
“没错,就是他。”
“天哪,巫九竟然拜入了他的门下?”
人们再次大吃一惊,那钟离一护在青龙宗可是赫赫有名,若要是论其个人实力,在青龙宗内绝对能够排入前三,连护宗六老单打独斗都不会是他的对手。
只不过那钟离一护,如同诸葛青云一样,也是一位客卿长老,所以在青龙宗内只是挂个头衔,什么事都不管,更别说传授宗内弟子技艺了,如今巫九竟然能拜入他老人家门下,着实让人羡慕不已。
“恩怨生死台,的确可以决斗生死,但必须要有所恩怨,你们两个人,可有恩怨?”那位长老开口询问道。
iOS WKWebView与JS交互
WKWebView
iOS8.0之后我们使用 WebKit框架中的WKWebView来加载网页。
WKWebViewConfiguration来配置JS交互。
其中的和JS交互的功能
WKPreferences(是WKWebViewConfiguration的属性) 中的javaScriptEnabled是Bool实行来打开或者关闭javaScript
*javaScriptCanOpenWindowsAutomaticallyBool控制javaScript打开windows。WKWebView
中的navigationDelegate
协议可以监听加载网页的周期和结果。判断链接是否允许跳转
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler;
拿到响应后决定是否允许跳转
- (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler;
链接开始加载时调用
- (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(null_unspecified WKNavigation *)navigation;
收到服务器重定向时调用
- (void)webView:(WKWebView *)webView didReceiveServerRedirectForProvisionalNavigation:(null_unspecified WKNavigation *)navigation;
加载错误时调用
- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(null_unspecified WKNavigation *)navigation withError:(NSError *)error;
当内容开始到达主帧时被调用(即将完成)
- (void)webView:(WKWebView *)webView didCommitNavigation:(null_unspecified WKNavigation *)navigation;
加载完成
- (void)webView:(WKWebView *)webView didFinishNavigation:(null_unspecified WKNavigation *)navigation;
在提交的主帧中发生错误时调用
- (void)webView:(WKWebView *)webView didFailNavigation:(null_unspecified WKNavigation *)navigation withError:(NSError *)error;
当webView需要响应身份验证时调用(如需验证服务器证书)
- (void)webView:(WKWebView *)webView didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential * _Nullable credential))completionHandler;
当webView的web内容进程被终止时调用。(iOS 9.0之后)
- (void)webViewWebContentProcessDidTerminate:(WKWebView *)webView API_AVAILABLE(macosx(10.11), ios(9.0));
WKWebView中的WKUIDelegate实现UI弹出框的一些处理(警告面板、确认面板、输入框)。
在JS端调用alert函数时,会触发此代理方法。JS端调用alert时所传的数据可以通过message拿到。在原生得到结果后,需要回调JS,是通过completionHandler回调。
- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler
{
NSLog(@"message = %@",message);
}
JS端调用confirm函数时,会触发此方法,通过message可以拿到JS端所传的数据,在iOS端显示原生alert得到YES/NO后,通过completionHandler回调给JS端
- (void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL result))completionHandler
{
NSLog(@"message = %@",message);
}
JS端调用prompt函数时,会触发此方法,要求输入一段文本,在原生输入得到文本内容后,通过completionHandler回调给JS
- (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(nullable NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString * __nullable result))completionHandler
{
NSLog(@"%s", __FUNCTION__);
NSLog(@"%@", prompt);
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"textinput" message:@"JS调用输入框" preferredStyle:UIAlertControllerStyleAlert];
[alert addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField)
{
textField.textColor = [UIColor redColor];
}];
[alert addAction:[UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action)
{
completionHandler([[alert.textFields lastObject] text]);
}]];
[self presentViewController:alert animated:YES completion:NULL];
}
JS交互实现流程
使用WKWebView,JS调iOS-JS端必须使用window.webkit.messageHandlers.JS_Function_Name.postMessage(null),其中JS_Function_Name是iOS端提供个JS交互的Name。
例:
function iOSCallJsAlert()
{
alert('弹个窗,再调用iOS端的JS_Function_Name');
window.webkit.messageHandlers.JS_Function_Name.postMessage({body: 'paramters'});
}
在注入JS交互Handler之后会用到[userContentController addScriptMessageHandler:self name:JS_Function_Name]。释放使用到[userContentController removeScriptMessageHandlerForName:JS_Function_Name]
我们JS呼叫iOS通过上面的Handler在iOS本地会有方法获取到。获取到之后我们可以根据iOS和JS之间定义好的协议,来做出相应的操作。
(void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message
{
NSLog(@"JS调iOS name : %@ body : %@",message.name,message.body);
}
处理简单的操作,可以让JS打开新的web页面,在WKWebView的WKNavigationDelegate协议中,判断要打开的新的web页面是否是含有你需要的东西,如果有需要就截获,不打开并且进行本地操作。
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler
{
NSString * url = navigationAction.request.URL.absoluteString;
if ([url hasPrefix:@"alipays://"] || [url hasPrefix:@"alipay://"])
{
if ([[UIApplication sharedApplication] canOpenURL:navigationAction.request.URL])
{
[[UIApplication sharedApplication] openURL:navigationAction.request.URL];
if(decisionHandler)
{
decisionHandler(WKNavigationActionPolicyCancel);
}
}
}
}
iOS端调用JS中的函数只需要知道在JS中的函数名称和函数需要传递的参数。通过原生的方法呼叫JS,
iOSCallJsAlert()是JS端的函数名称,如果有参数iOS端写法iOSCallJsAlert('p1','p2')
[webView evaluateJavaScript:@"iOSCallJsAlert()" completionHandler:nil]
JS和iOS注意的地方
①. 上面提到[userContentController addScriptMessageHandler:self name:JS_Function_Name]是注册JS的MessageHandler,但是WKWebView在多次调用loadRequest,会出现JS无法调用iOS端。我们需要在loadRequest和reloadWebView的时候需要重新注入。(在注入之前需要移除再注入,避免造成内存泄漏)
如果message.body中没有参数,JS代码中需要传null防止iOS端不会接收到JS的交互。
window.webkit.messageHandlers.kJS_Login.postMessage(null)
②. 在WKWebView中点击没有反应的时候,可以参考一下处理
-(WKWebView *)webView:(WKWebView *)webView createWebViewWithConfiguration:(WKWebViewConfiguration *)configuration forNavigationAction:(WKNavigationAction *)navigationAction windowFeatures:(WKWindowFeatures *)windowFeatures
{
if (!navigationAction.targetFrame.isMainFrame)
{
[webView loadRequest:navigationAction.request];
}
return nil;
}
③. HTML中不能通过拨号来拨打iOS的电话。需要在iOS端的WKNavigationDelegate中截取电话在使用原生进行调用拨打电话。其中的[navigationAction.request.URL.scheme isEqualToString:@"tel"]中的@"tel"是JS中的定义好,并iOS端需要知道的。发送请求前决定是否跳转,并在此拦截拨打电话的URL
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler
{
/// 拨号
if ([navigationAction.request.URL.scheme isEqualToString:@"tel"])
{
decisionHandler(WKNavigationActionPolicyCancel);
NSString * mutStr = [NSString stringWithFormat:@"telprompt://%@",navigationAction.request.URL.resourceSpecifier];
if ([[UIApplication sharedApplication] canOpenURL:mutStr.URL])
{
if (iOS10())
{
[[UIApplication sharedApplication] openURL:mutStr.URL options:@{} completionHandler:^(BOOL success) {}];
}
else
{
[[UIApplication sharedApplication] openURL:mutStr.URL];
}
}
}
else
{
decisionHandler(WKNavigationActionPolicyAllow);
}
}
④. 在执行goBack或reload或goToBackForwardListItem之后请不要马上执行loadRequest,使用延迟加载。
⑤在使用中JS端:H5、DOM绑定事件。每一次JS方法调用iOS方法的时候,我都为这个JS方法绑定一个对应的callBack方法,这样的话,同时在发送的消息中告诉iOS需要回调,iOS方法就可以执行完相关的方法后,直接回调相应的callBack方法,并携带相关的参数,这样就可以完美的进行交互了。这是为了在JS调用iOS的时候,在- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message获取到信息后,iOS端调用[_webView evaluateJavaScript:jsString completionHandler:^(id _Nullable data, NSError * _Nullable error) {}];给JS发送消息,保证JS在获取相关返回值时,一定能拿到值。
⑥根据需求清楚缓存和Cookie。
JS端可以参考:漫谈js自定义事件、DOM/伪DOM自定义事件
WKWebview加载远程JS文件和本地JS文件
在页面请求成功 页面加载完成之后调用
(void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation
completionHandler中JS是可以再收到调用之后给webView回调。
WKWebView远程网页加载远程JS文件
- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation
{
[self.webView evaluateJavaScript:@"var script = document.createElement('script');"
"script.type = 'text/javascript';"
"script.src = 'http://www.ohmephoto.com/test.js';"
"document.getElementsByTagName('head')[0].appendChild(script);"
completionHandler:^(id _Nullable object, NSError * _Nullable error)
{
NSLog(@"------error = %@ object = %@",error,object);
}];
}
WKWebView远程网页加载本地JS
在xcode中新建找到Other->Empty,确定文件名XXX.js
一般需要在本地加载的JS都会很小,用原生JS直接加载就可以了
题外:看到网友是自定义NSURLProtocol类 - 高端大气上档次,请自行查阅。
- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation
{
NSString * plistPath = [[NSBundle mainBundle] pathForResource:@"XXX" ofType:@"js"];
NSString * data = [NSString stringWithContentsOfFile:plistPath encoding:NSUTF8StringEncoding error:nil];// [[NSMutableDictionary alloc] initWithContentsOfFile:plistPath];
[self.webView evaluateJavaScript:[NSString stringWithFormat:@"javascript:%@",data]
completionHandler:^(id _Nullable object, NSError * _Nullable error)
{
}];
}
第三方库WebViewJavascriptBridge
GitHub地址WebViewJavascriptBridge
不做过多解释,很好用的第三方库。安卓也有相应的库。同样很强大。
WKWebView进度条
声明属性
@property (nonatomic, strong) UIProgressView *progressView;
//进度条初始化
- (UIProgressView *)progressView
{
if (!_progressView)
{
_progressView = [[UIProgressView alloc] initWithFrame:CGRectMake(0, 0, SCREEN_WIDTH, 2)];
_progressView.backgroundColor = [UIColor blueColor];
_progressView.transform = CGAffineTransformMakeScale(1.0f, 1.5f);
_progressView.progressTintColor = [UIColor app_color_yellow_eab201];
[self.view addSubview:self.progressView];
}
return _progressView;
}
给ViewController中添加Observer
[self.webView addObserver:self forKeyPath:@"estimatedProgress" options:NSKeyValueObservingOptionNew context:nil];
在dealloc找那个删除Observer
[self.webView removeObserver:self forKeyPath:@"estimatedProgress"];
在observeValueForKeyPath中添加对progressView的进度显示操作
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary< NSString *,id> *)change context:(void *)context
{
if ([keyPath isEqualToString:@"estimatedProgress"])
{
self.progressView.progress = self.webView.estimatedProgress;
if (self.progressView.progress == 1)
{
WeakSelfDeclare
[UIView animateWithDuration:0.25f delay:0.3f options:UIViewAnimationOptionCurveEaseOut animations:^
{
weakSelf.progressView.transform = CGAffineTransformMakeScale(1.0f, 1.4f);
}
completion:^(BOOL finished)
{
weakSelf.progressView.hidden = YES;
}];
}
}
}
显示progressView
- (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation
{
self.progressView.hidden = NO;
self.progressView.transform = CGAffineTransformMakeScale(1.0f, 1.5f);
[self.view bringSubviewToFront:self.progressView];
}
隐藏progressView
- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation
{
self.progressView.hidden = YES;
}
- (void)webView:(WKWebView *)webView didFailNavigation:(WKNavigation *)navigation withError:(NSError *)error
{
if(error.code==NSURLErrorCancelled)
{
[self webView:webView didFinishNavigation:navigation];
}
else
{
self.progressView.hidden = YES;
}
}
- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation withError:(NSError *)error
{
self.progressView.hidden = YES;
[self.navigationItem setTitleWithCustomLabel:@"加载失败"];
}
WKWebView清除缓存
有人是这么写的
- (void)clearCache
{
/* 取得Library文件夹的位置*/
NSString *libraryDir = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory,NSUserDomainMask, YES)[0];
/* 取得bundle id,用作文件拼接用*/ NSString *bundleId = [[[NSBundle mainBundle] infoDictionary]objectForKey:@"CFBundleIdentifier"];
/* * 拼接缓存地址,具体目录为App/Library/Caches/你的APPBundleID/fsCachedData */
NSString *webKitFolderInCachesfs = [NSString stringWithFormat:@"%@/Caches/%@/fsCachedData",libraryDir,bundleId];
NSError *error;
/* 取得目录下所有的文件,取得文件数组*/
NSFileManager *fileManager = [NSFileManager defaultManager];
//NSArray *fileList = [[NSArray alloc] init];
//fileList便是包含有该文件夹下所有文件的文件名及文件夹名的数组
NSArray *fileList = [fileManager contentsOfDirectoryAtPath:webKitFolderInCachesfs error:&error];
/* 遍历文件组成的数组*/
for(NSString * fileName in fileList)
{
/* 定位每个文件的位置*/
NSString * path = [[NSBundle bundleWithPath:webKitFolderInCachesfs] pathForResource:fileName ofType:@""];
/* 将文件转换为NSData类型的数据*/
NSData * fileData = [NSData dataWithContentsOfFile:path];
/* 如果FileData的长度大于2,说明FileData不为空*/
if(fileData.length >2)
{
/* 创建两个用于显示文件类型的变量*/
int char1 =0;
int char2 =0;
[fileData getBytes:&char1 range:NSMakeRange(0,1)];
[fileData getBytes:&char2 range:NSMakeRange(1,1)];
/* 拼接两个变量*/ NSString *numStr = [NSString stringWithFormat:@"%i%i",char1,char2];
/* 如果该文件前四个字符是6033,说明是Html文件,删除掉本地的缓存*/
if([numStr isEqualToString:@"6033"])
{
[[NSFileManager defaultManager] removeItemAtPath:[NSString stringWithFormat:@"%@/%@",webKitFolderInCachesfs,fileName]error:&error]; continue;
}
}
}
}
也可以这样写
- (void)cleanCacheAndCookie
{
//清除cookies
NSHTTPCookie *cookie;
NSHTTPCookieStorage *storage = [NSHTTPCookieStorage sharedHTTPCookieStorage];
for (cookie in [storage cookies])
{
[storage deleteCookie:cookie];
}
[[NSURLCache sharedURLCache] removeAllCachedResponses];
NSURLCache * cache = [NSURLCache sharedURLCache];
[cache removeAllCachedResponses];
[cache setDiskCapacity:0];
[cache setMemoryCapacity:0];
WKWebsiteDataStore *dateStore = [WKWebsiteDataStore defaultDataStore];
[dateStore fetchDataRecordsOfTypes:[WKWebsiteDataStore allWebsiteDataTypes]
completionHandler:^(NSArray< WKWebsiteDataRecord *> * __nonnull records)
{
for (WKWebsiteDataRecord *record in records)
{
[[WKWebsiteDataStore defaultDataStore] removeDataOfTypes:record.dataTypes
forDataRecords:@[record]
completionHandler:^
{
NSLog(@"Cookies for %@ deleted successfully",record.displayName);
}];
}
}];
}
- (void)dealloc
{
[_webView stopLoading];
[_webView setNavigationDelegate:nil];
[self clearCache];
[self cleanCacheAndCookie];
}
WKWebView修改userAgent
在项目中我们游戏直接使用以下方式写入userAgent,出现了URL可以加载,但是URL里面的资源无法加载问题。但是在微信和外部Safari是可以的。后来查出,不要去直接整个修改掉userAgent。要在原有的userAgent加上你需要的userAgent字符串,进行重新注册就可以了。(具体原因可能是外部游戏引擎,会默认取系统的userAgent来做他们的处理,你改掉整个会出现问题)。
[[NSUserDefaults standardUserDefaults] registerDefaults:@{@"UserAgent":@"CustomUserAgent"}];
[[NSUserDefaults standardUserDefaults] synchronize];
[self.webView setCustomUserAgent:newUserAgent];
使用下面的修改userAgent
使用NSUserDefaults修改本地的userAgent
使用WKWebView的setCustomUserAgent修改网络userAgent
[self.webView evaluateJavaScript:@"navigator.userAgent" completionHandler:^(id result, NSError *error)
{
NSString * userAgent = result;
NSString * newUserAgent = [userAgent stringByAppendingString:@"CustomUserAgent"];
[[NSUserDefaults standardUserDefaults] registerDefaults:@{@"UserAgent":newUserAgent}];
[[NSUserDefaults standardUserDefaults] synchronize];
[self.webView setCustomUserAgent:newUserAgent];
}];
WKWebView时间显示Nan问题 (js时间处理)
正常的处理如下:
var regTime = result.RegTime;
var dRegTime = new Date(regTime);
var regHtml = dRegTime.getFullYear() + "年" + dRegTime.getMonth() + "月";
在iOS系统下,JS需要正则把-替换成/
var regTime = result.RegTime.replace(/-/g, "/");
总结
iOS中的WKWebView使用简单方便。使用它你只用将你用到的进行封装。在你的ViewController中进行初始化WKWebView并加载和对其配置,就能完整的使用了。
iOS端和JS互相调用,有简单的函数方法进行互相配合。在交互的时候需要双方约定好特定的事件名称。比如登录、打开支付、弹出分享等常规操作。
JS向iOS端发送消息使用window.webkit.messageHandlers.JS_Function_Name.postMessage(null)。
在iOS端接受JS发来的消息需要WKUserContentController添加Handler并且处理协议,在协议中判断并处理JS端需要iOS端做的事件。
iOS调用JS直接使用WKWebView的[webView evaluateJavaScript:@"JS函数名称('参数1','参数2')" completionHandler:nil]来向JS发送消息。
作者:燃烧的大叔
https://www.jianshu.com/p/20cfd4f8c4ff
iOS开发整理发布,转载请联系作者获得授权
关注公众号:拾黑(shiheibook)了解更多
[广告]赞助链接:
四季很好,只要有你,文娱排行榜:https://www.yaopaiming.com/
让资讯触达的更精准有趣:https://www.0xu.cn/
随时掌握互联网精彩
- 1 习近平G20里约峰会展现大国担当 7981419
- 2 多国驻乌克兰大使馆因袭击风险关闭 7901931
- 3 78岁老太将减持2.5亿股股票 7822614
- 4 二十国集团里约峰会将会卓有成效 7747882
- 5 俄导弹击中乌水电站大坝 7627216
- 6 孙颖莎王艺迪不敌日本削球组合 7553981
- 7 高三女生酒后被强奸致死?检方回应 7462288
- 8 第一视角记录虎鲨吞下手机全程 7321127
- 9 手机不能看医院CT图像就要少收费 7214532
- 10 智慧乌镇点亮数字经济新未来 7191393