我正在使用的iPhone应用程序使用WKWebView,但(我的客户端要求......)必须拥有自定义用户代理。
我们希望用户代理字符串模仿Safari,它看起来像这样:
Mozilla/5.0 (iPhone; CPU iPhone OS 9_0_2 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13A452 Safari/601.1
我知道如何来设置用户代理字符串。最简单的方法是将UserAgent设置为标准用户默认值。
[[NSUserDefaults standardUserDefaults] registerDefaults:@{@"UserAgent": userAgent}];
我遇到的问题实际上是提出Apple在Safari的User-Agent中使用的版本号。具体来说,AppleWebKit版本,紧接在Mobile(13A452)之后的代码,以及Safari版本号。
我提出的唯一解决方案涉及
Mozilla/5.0 (iPhone; CPU iPhone OS 9_0_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13A452 (like Safari/601.1) TheAppName/1.12
(通过提供的系统调用找到两个iPhone版本,这不是问题。)
有更好的方法吗? (显然,步骤3-4可以替换为通过javascript提取版本号,但这只会改变一切。)
简而言之,有没有什么方法可以获得AppleWebKit / Mobile / Safari版本号,而不是通过向webview实例询问其自己的用户代理字符串?
如果您不能按照上述步骤操作,我可以提供一些示例代码甚至示例项目,但我的意图应该是明确的。
答案 0 :(得分:2)
我认为最好的办法是坚持使用与您正在做的事情相符的事情:它是派生用户代理字符串非常类似于系统默认字符串的最安全的方法。即使创建Web视图,加载字符串以及查询用户代理存在开销,但在大型方案中它仍然是微不足道的。
另一方面,您感兴趣的数据应该是紧急的"可废弃的"来自系统自己的框架。请记住,虽然iOS进程是沙盒,但这主要是为了防止他们访问其他应用程序'数据。 iOS和Mac上的沙盒设计使应用程序进程能够从系统文件中大量读取,这是有道理的,因为这些文件支持代表应用程序将动态库和资源数据预期加载到内存中。
所以,例如,在你的applicationDidFinishLaunching方法中添加这样的一行:
NSLog(@"System frameworks: %@", [[NSFileManager defaultManager] directoryContentsAtPath:@"/System/Library/Frameworks/" excludingDirectories:NO]);
您将看到所有可用的系统框架列表。要正确使用WebKit框架的CFBundleVersion,例如:
NSLog(@"%@", [[NSDictionary dictionaryWithContentsOfFile:@"/System/Library/Frameworks/WebKit.framework/Info.plist"] objectForKey:@"CFBundleVersion"]);
但是当然NSBundle将这个文件抽象出来并让你直接得到可能已经在内存中的字典:
NSLog(@"%@", [[[NSBundle bundleForClass:[[WKWebView class] infoDictionary] objectForKey:@"CFBundleVersion"]);
您可以使用类似的技巧通过NSBundle的infoDictionaruy访问属性,或者直接从"磁盘"中读取数据。对你的客户'电话。