Files
OrderScheduling/Pods/CocoaDebug/Sources/Swizzling/_WKWebView+Swizzling.m
DDIsFriend 63ca919ed5 update
2023-08-23 09:24:40 +08:00

172 lines
7.6 KiB
Objective-C

//
// WKWebView+Swizzling.m
// 1233213
//
// Created by man 2019/1/8.
// Copyright © 2020 man. All rights reserved.
//
#import <WebKit/WebKit.h>
#import <objc/runtime.h>
#import "_ObjcLog.h"
#import "_NetworkHelper.h"
@interface WKWebView () <WKScriptMessageHandler>
@end
@implementation WKWebView (_Swizzling)
#pragma mark - life
+ (void)load {
if ([[NSUserDefaults standardUserDefaults] boolForKey:@"enableWKWebViewMonitoring_CocoaDebug"]) {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
SEL original_sel = @selector(initWithFrame:configuration:);
SEL replaced_sel = @selector(replaced_initWithFrame:configuration:);
Method original_method = class_getInstanceMethod([self class], original_sel);
Method replaced_method = class_getInstanceMethod([self class], replaced_sel);
if (!class_addMethod([self class], original_sel, method_getImplementation(replaced_method), method_getTypeEncoding(replaced_method))) {
method_exchangeImplementations(original_method, replaced_method);
}
/*********************************************************************************************************************************/
SEL original_sel2 = NSSelectorFromString(@"dealloc");
SEL replaced_sel2 = @selector(replaced_dealloc);
Method original_method2 = class_getInstanceMethod([self class], original_sel2);
Method replaced_method2 = class_getInstanceMethod([self class], replaced_sel2);
if (!class_addMethod([self class], original_sel2, method_getImplementation(replaced_method2), method_getTypeEncoding(replaced_method2))) {
method_exchangeImplementations(original_method2, replaced_method2);
}
SEL original_sel3 = NSSelectorFromString(@"willDealloc");
SEL replaced_sel3 = @selector(replaced_willDealloc);
Method replaced_method3 = class_getInstanceMethod([self class], replaced_sel3);
class_addMethod([self class], original_sel3, method_getImplementation(replaced_method3), method_getTypeEncoding(replaced_method3));
});
}
}
#pragma mark - replaced method
- (BOOL)replaced_willDealloc {
// removeScriptMessageHandlerForName
[self.configuration.userContentController removeScriptMessageHandlerForName:@"log"];
[self.configuration.userContentController removeScriptMessageHandlerForName:@"error"];
[self.configuration.userContentController removeScriptMessageHandlerForName:@"warn"];
[self.configuration.userContentController removeScriptMessageHandlerForName:@"debug"];
[self.configuration.userContentController removeScriptMessageHandlerForName:@"info"];
return true;
}
- (void)replaced_dealloc {
//WKWebView
[_ObjcLog logWithFile:"[WKWebView]" function:"" line:0 color:[UIColor redColor] message:@"-------------------------------- dealloc --------------------------------"];
}
- (instancetype)replaced_initWithFrame:(CGRect)frame configuration:(WKWebViewConfiguration *)configuration {
//WKWebView
[_ObjcLog logWithFile:"[WKWebView]" function:"" line:0 color:[_NetworkHelper shared].mainColor message:@"----------------------------------- init -----------------------------------"];
[self log:configuration];
[self error:configuration];
[self warn:configuration];
[self debug:configuration];
[self info:configuration];
return [self replaced_initWithFrame:frame configuration:configuration];
}
#pragma mark - private
- (void)log:(WKWebViewConfiguration *)configuration {
[configuration.userContentController removeScriptMessageHandlerForName:@"log"];
[configuration.userContentController addScriptMessageHandler:self name:@"log"];
//rewrite the method of console.log
NSString *jsCode = @"console.log = (function(oriLogFunc){\
return function(str)\
{\
window.webkit.messageHandlers.log.postMessage(str);\
oriLogFunc.call(console,str);\
}\
})(console.log);";
//injected the method when H5 starts to create the DOM tree
[configuration.userContentController addUserScript:[[WKUserScript alloc] initWithSource:jsCode injectionTime:WKUserScriptInjectionTimeAtDocumentStart forMainFrameOnly:YES]];
}
- (void)error:(WKWebViewConfiguration *)configuration {
[configuration.userContentController removeScriptMessageHandlerForName:@"error"];
[configuration.userContentController addScriptMessageHandler:self name:@"error"];
//rewrite the method of console.error
NSString *jsCode = @"console.error = (function(oriLogFunc){\
return function(str)\
{\
window.webkit.messageHandlers.error.postMessage(str);\
oriLogFunc.call(console,str);\
}\
})(console.error);";
//injected the method when H5 starts to create the DOM tree
[configuration.userContentController addUserScript:[[WKUserScript alloc] initWithSource:jsCode injectionTime:WKUserScriptInjectionTimeAtDocumentStart forMainFrameOnly:YES]];
}
- (void)warn:(WKWebViewConfiguration *)configuration {
[configuration.userContentController removeScriptMessageHandlerForName:@"warn"];
[configuration.userContentController addScriptMessageHandler:self name:@"warn"];
//rewrite the method of console.warn
NSString *jsCode = @"console.warn = (function(oriLogFunc){\
return function(str)\
{\
window.webkit.messageHandlers.warn.postMessage(str);\
oriLogFunc.call(console,str);\
}\
})(console.warn);";
//injected the method when H5 starts to create the DOM tree
[configuration.userContentController addUserScript:[[WKUserScript alloc] initWithSource:jsCode injectionTime:WKUserScriptInjectionTimeAtDocumentStart forMainFrameOnly:YES]];
}
- (void)debug:(WKWebViewConfiguration *)configuration {
[configuration.userContentController removeScriptMessageHandlerForName:@"debug"];
[configuration.userContentController addScriptMessageHandler:self name:@"debug"];
//rewrite the method of console.debug
NSString *jsCode = @"console.debug = (function(oriLogFunc){\
return function(str)\
{\
window.webkit.messageHandlers.debug.postMessage(str);\
oriLogFunc.call(console,str);\
}\
})(console.debug);";
//injected the method when H5 starts to create the DOM tree
[configuration.userContentController addUserScript:[[WKUserScript alloc] initWithSource:jsCode injectionTime:WKUserScriptInjectionTimeAtDocumentStart forMainFrameOnly:YES]];
}
- (void)info:(WKWebViewConfiguration *)configuration {
[configuration.userContentController removeScriptMessageHandlerForName:@"info"];
[configuration.userContentController addScriptMessageHandler:self name:@"info"];
//rewrite the method of console.info
NSString *jsCode = @"console.info = (function(oriLogFunc){\
return function(str)\
{\
window.webkit.messageHandlers.info.postMessage(str);\
oriLogFunc.call(console,str);\
}\
})(console.info);";
//injected the method when H5 starts to create the DOM tree
[configuration.userContentController addUserScript:[[WKUserScript alloc] initWithSource:jsCode injectionTime:WKUserScriptInjectionTimeAtDocumentStart forMainFrameOnly:YES]];
}
#pragma mark - WKScriptMessageHandler
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wobjc-protocol-method-implementation"
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message {
[_ObjcLog logWithFile:"[WKWebView]" function:[message.name UTF8String] line:0 color:[UIColor whiteColor] message:message.body];
}
#pragma clang diagnostic pop
@end