简单笔记,不具备参考价值~
WKURLSchemeHandler 的使用参考:https://zhuanlan.zhihu.com/p/56965133,文章相对比较清晰简单。
阅读上文后,你可以知道 WKURLSchemeHandler 协议的使用,以及如何加载离线化资源。
由于WebKit内部限制,我们无法拦截 https/http 等协议,会导致崩溃,原因在于 WebKit 有内置协议白名单,这次协议由内部进行处理。
// 下面代码会崩溃
[webViewConfiguration setURLSchemeHandler:
[[MyWKURLSchemeHandler alloc] init] forURLScheme:@"https"];
解决方案:
iOS 11 系统提供了 handlesURLScheme
方法,判断 WKWebView 是否能处理 urlScheme ,我们可以 hook 此方法,来支持自己处理 http/https 请求。
/* @abstract Checks whether or not WKWebViews handle the given URL scheme by default.
@param scheme The URL scheme to check.
*/
+ (BOOL)handlesURLScheme:(NSString *)urlScheme API_AVAILABLE(macos(10.13), ios(11.0));
最终代码:
void WKClassSwizzle(Class class, SEL originalSelector, SEL swizzledSelector) {
class = object_getClass(class);
Method originalMethod = class_getClassMethod(class, originalSelector);
Method swizzledMethod = class_getClassMethod(class, swizzledSelector);
BOOL didAddMethod =
class_addMethod(class,
originalSelector,
method_getImplementation(swizzledMethod),
method_getTypeEncoding(swizzledMethod));
if (didAddMethod) {
class_replaceMethod(class,
swizzledSelector,
method_getImplementation(originalMethod),
method_getTypeEncoding(originalMethod));
} else {
method_exchangeImplementations(originalMethod, swizzledMethod);
}
}
// 在合适的场景调用
+ (void)wk_hookHandlesURLScheme {
IWKMetaClassSwizzle(self, @selector(handlesURLScheme:), @selector(wk_handlesURLScheme:));
}
+ (BOOL)wk_handlesURLScheme:(NSString *)name {
if ([name isEqualToString:@"http"] ||
[name isEqualToString:@"https"]) {
return NO;
}
if (name.length == 0) {
return NO;
}
return [self wk_handlesURLScheme:name];
}
扩展
WKWebView拦截请求资源:http://events.jianshu.io/p/4b2fc44cef8b
WKWebView离线包开发小记(包含WKWebView复用池):https://freelf.me/WKWebView%E7%A6%BB%E7%BA%BF%E5%8C%85%E5%BC%80%E5%8F%91%E5%B0%8F%E8%AE%B0