文章目录

  • 属性customUserAgent
  • 问题1
  • 思考
  • 关于customUserAgent
    • 作用
    • 读customUserAgent的值
    • 设置customUserAgent
  • 问题2

属性customUserAgent

WKWebView有一个属性customUserAgent

/*! @abstract The custom user agent string or nil if no custom user agent string has been set.
*/
@property (nullable, nonatomic, copy) NSString *customUserAgent API_AVAILABLE(macosx(10.11), ios(9.0));

问题1

在一次使用webView的时候出现了这样一个问题:在iOS9上加载显示空白,iOS12上加载显示成功,但是加载的不是手机上的网页,而是网页版。

网页版:

手机版:

可以看出同一个链接地址,手机版和网页版区别还是很大的,手机上我们需要加载手机版网页,才能显示正常。

找了找问题,后来发现是设置customUserAgent位置不当导致的。

起初我在创建webView的时候直接设置customUserAgent:

    self.webView = [[WKWebView alloc] initWithFrame:self.view.bounds configuration:config];self.webView.UIDelegate = self;self.webView.navigationDelegate = self;//self.webView.customUserAgent = @"xxx";//bug,切勿再此设置,切记在didFinishNavigation处设置。NSURLRequest *request = [NSURLRequest requestWithURL:self.webURL];[self.webView loadRequest:request];[self.view addSubview:self.webView];

后来将这里的设置注释掉,发现加载就正常了,iOS9加载正常,iOS12也加载正常,而且加载的是手机版页面,而不是网页版。

虽然现实正常了,但是js端小伙伴要用到userAgent判断是哪一个端,iOS,安卓还是h5,所以就还是需要设置userAgent,将设置放在网页加载成功后设置:

- (void)webView:(WKWebView *)webView didFinishNavigation:(null_unspecified WKNavigation *)navigation {NSLog(@"webView load finished");webView.customUserAgent = @"xxx";
}

这里不设置userAgent的话,js端是不会把事件回调给OC端的,因为我们的js根据userAgen判断是哪一个端,然后js交互调用不同的方法传进行传值。如果js端不用这个userAgent的话不用设置也可以。

思考

为什么我们在创建webView的时候设置userAgent,有些机型会加载H5的网页而不是手机浏览器的网页内容?

这就得知道userAgent的作用是什么,浏览器通过userAgent来判断是哪一端,百度“移动和pc userAgent判断”。

我们在创建webView的时候给userAgent赋值,这样的话,覆盖了原有的userAgent的值,导致浏览器无法判断是pc端还是手机端,所以在手机上加载了pc上的网页。

再看一下customUserAgent这个属性在文档中的描述,如果我们设置,原customUserAgent的值就会被覆盖。

关于customUserAgent

作用

其他端用customUserAgent来判断是是哪一端,pc端还是手机端。

读customUserAgent的值

在webView未加载出来前获取webView的customUserAgent,会获取不到。只有loading之后才能获取到值,获取办法:

- (void)webView:(WKWebView *)webView didFinishNavigation:(null_unspecified WKNavigation *)navigation
{NSLog(@"webView load finished");[self.loadingView stopAnimating];//设置userAgent[self.webView evaluateJavaScript:@"navigator.userAgent" completionHandler:^(id _Nullable result, NSError * _Nullable error) {NSString *newUserAgent = [NSString stringWithFormat:@"%@iphone iOS xxx",result];self.webView.customUserAgent = newUserAgent;NSLog(@"customUserAgent : %@",self.webView.customUserAgent);}];
}

通过js方法获取userAgent,回调里的result即userAgent。

打印了两个手机的userAgent

iPhone6

Mozilla/5.0 (iPhone; CPU iPhone OS 12_1_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/16D57i phonexxx

iPhoneX

Mozilla/5.0 (iPhone; CPU iPhone OS 12_3_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148i phonexxx

iPadAri3 Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/605.1.15 (KHTML, like Gecko)

iPhone11模拟器 Mozilla/5.0 (iPhone; CPU iPhone OS 14_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148

需要设置App Transport Security Settings。

上面的设置方式在新一些的iOS版本中可能会存在customUserAgent字符串被重复的拼接 iphone iOS xxx 的问题,较早一些的版本我还没发现这个问题,今天发现是在iOS 14上,重新来编辑一下笔记。

使用下面的方式来设置,避免多次重复的设置和多次拼接我们需要添加的字符串。

例如我们要加一个版本号

 NSString *versionIdentifier = [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString *)kCFBundleVersionKey][webView evaluateJavaScript:@"navigator.userAgent" completionHandler:^(id _Nullable result, NSError * _Nullable error) {if (![result containsString:versionIdentifier]) {NSString *deviceIdentifier = (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) ? @"iPad" :@"iPhone";webView.customUserAgent = [NSString stringWithFormat:@"%@^%@^%@",result,deviceIdentifier,versionIdentifier];}NSLog(@"user-Agent : %@",webView.customUserAgent);}];

调试一下就知道是什么问题,该怎么处理了,很简单,不赘述。

设置customUserAgent

上面我们获取到userAgent后,使用NSString *newUserAgent = [NSString stringWithFormat:@"%@iphonevhallclass",result]; 拼接了一段“iphone iOS xxx”,这个跟js商量好就行。这样设置不会覆盖userAgent原有值。

问题2

H5的小伙伴需要在网页加载前就用userAgent,要判断是iOS还是安卓或者是pc。

感觉这种网页没加载就要userAgent的值的做法不是很合理,网页未加载前我们拿不到userAgent的值,如果设置成别的值就会出现userAgent被覆盖问题。

    self.webView = [[WKWebView alloc] initWithFrame:CGRectMake(0, 20, CGRectGetWidth(self.view.frame), CGRectGetHeight(self.view.frame)-20) configuration:config];self.webView.UIDelegate = self;self.webView.navigationDelegate = self;self.webView.allowsBackForwardNavigationGestures = YES;self.webView.customUserAgent = @"Mozilla/5.0 (iPhone; CPU iPhone OS 12_1_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/16D57 iphone iOS xxx";

直接用了iPhone6的userAgent后面拼接上’iphone iOS xxx‘,在开始创建的时候直接设置上了。

这是个投机的解决办法,最好不要这样,H5的同学还有没有其他的办法呢?非得网页加载前就用userAgent?这合理吗?

WKWebView的customUserAgent相关推荐

  1. html ua ios,iOS 修改默认 UserAgent

    前言: 有个项目需求,要区分打开H5是在本地APP还是在手机浏览器,前端伙伴说需要配合修改默认的 UserAgent,以便区分. 一.如何获取UserAgent UIWebView方式: UIWebV ...

  2. wkwebView基本使用方法

    WKWebView有两个delegate,WKUIDelegate 和 WKNavigationDelegate.WKNavigationDelegate主要处理一些跳转.加载处理操作,WKUIDel ...

  3. OC WKWebView的JS与OC交互、Cookie管理

    完全抄录:iOS中UIWebView与WKWebView.JavaScript与OC交互.Cookie管理看我就够(中) ####WKWebView 是Apple于iOS 8.0推出的WebKit中的 ...

  4. iOS之深入解析WKWebView的坑点收录和优化处理

    一.Cookie 处理 ① Cookie 说明 WKWebView 在设置 Cookie 的时候,经常做的是在请求的请求头里添加 Cookie,但这只是把 Cookie 发送给了服务端,本地并没有保存 ...

  5. swift中WKWebView和JS交互实现

    在Swift中加载HTML网页有两个view,分别是WKWebView和UIWebView,这里我使用的是WKWebView 这里分享一下我的写法: 1.定义变量WKWebView: lazy var ...

  6. WKWebView设置UserAgent踩坑

    WKWebView设置UserAgent踩坑 通过下面的方法给wkwebview设置自定义useragent,解决了常见的问题,如第一次设置不生效,第一次获取不到原来的useragent等问题 思路如 ...

  7. WKWebView 设置 UserAgent

    一.全局设置UserAgent(必须等completionHandler回调完成才生效) [self.wkWebView evaluateJavaScript:@"navigator.use ...

  8. WKWebView使用及注意点(keng)

    iOS8之后,苹果推出了WebKit这个框架,用来替换原有的UIWebView,新的控件优点多多,不一一叙述.由于一直在适配iOS7,就没有去替换,现在仍掉了iOS7,以为很简单的就替换过来了,然而在 ...

  9. WKWebView 使用及注意点(keng)

    来源:伯乐在线 - Toyun 链接:http://ios.jobbole.com/90729/ 点击 → 申请加入伯乐在线专栏作者 iOS8之后,苹果推出了WebKit这个框架,用来替换原有的UIW ...

  10. WKWebView WebKit (SwiftUI中文文档手册)

    WKWebView 显示交互式Web内容的对象,例如应用程序内浏览器. class WKWebView : UIView class WKWebView : NSView ###总览 重要,从iOS ...

最新文章

  1. 第四周课程总结实验报告(二)
  2. spring初始化相关
  3. 小米6通话音量补丁_智能手机的音量键有很多功能,你用过吗?
  4. c++ try catch
  5. LAMP攻略: LAMP环境搭建,Linux下Apache,MySQL,PHP安装与配置
  6. jsp+javabean实现购物车
  7. mysql测试题汇总_总结:SQL练习【SQL经典练习题】
  8. vc可以实现对话框里显示html文档内容,也可以显示word内容吗,VC6中使用CHtmlView在对话框控制中显示HTML文档...
  9. 计算机课程教改论文,高职计算机教改的课程设计研究论文
  10. Oracle - 导入异常ORA-01659和11G在Exp时空表不能导出
  11. 深入浅出聊Unity3D项目优化:从Draw Calls到GC
  12. 提高服务器响应时间,如何提高服务器qps
  13. mysql远程连接出错
  14. 月考分析五年级英语html,第一学期五年级英语期末考试试卷分析
  15. android+即刻点赞,Android开发仿即刻点赞文字部分的自定义View
  16. Python实现文件编码转换GB2312、GBK、UTF-8
  17. 杭州电子科技大学ACM 1018
  18. python小游戏之超级玛丽进阶版(1~4关)。好玩到爆炸~【内附github源码,及其详细备注】
  19. 彻底掌握基于HTTP网络层的 “前端性能优化“
  20. “犯强汉者,虽远必诛!”----遥想伟大汉人当年

热门文章

  1. Windows7集成SP1微软原版光盘镜像下载大全
  2. JanusGraph学习-安装和使用
  3. python程序设计实训报告-Python编程实践(1)
  4. Hyperion神器之SmartView产品(下篇)
  5. JavaScript---BOM和DOM
  6. RS232串口MODBUS协议工业读写器读卡器配置软件|工具的功能与界面说明
  7. 光纤MPO端面脏了也会造成您所不知道的故障
  8. 地图转换|用arcgis 将cad转kmz
  9. SAE J1939学习笔记(一)
  10. 《数字电子技术基础》3.3 CMOS门电路(上)