I refer to How to enable WKURLSchemeHandler to do work off main thread? and try to change to objective-c, but still report an error,
Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'This task has already been stopped', if - (void)webView:(WKWebView *)webView startURLSchemeTask:(id <WKURLSchemeTask>)urlSchemeTask interface does not add content, webview does not Display any content, still can't locate why this error is reported, try catch can't catch the exception
@implementation WKWebView (SchemeExtersion)
+ (void)load {
method_exchangeImplementations(class_getClassMethod(self, @selector(handlesURLScheme:)), class_getClassMethod(self, @selector(__handlesURLScheme:)));
}
+ (BOOL)__handlesURLScheme:(NSString *)urlScheme {
if ([urlScheme isEqualToString:@"http"] || [urlScheme isEqualToString:@"https"]) {
return NO;
}
return [self __handlesURLScheme: urlScheme];
}
@end
#import "ViewController.h"
#import <WebKit/WebKit.h>
#import "LSURLProtocol.h"
@interface ViewController ()<WKURLSchemeHandler>
//@property (nonatomic, strong) UIWebView *webView;
@property (nonatomic, strong) WKWebView *wkWebView;
@property (nonatomic, strong) dispatch_semaphore_t listSema;
@property (nonatomic, strong) NSMutableArray* stoppedTaskURLs;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
_listSema = dispatch_semaphore_create(1);
_stoppedTaskURLs = [[NSMutableArray alloc] initWithCapacity:0];
[self initWKWebView];
}
- (void)initWKWebView {
WKWebViewConfiguration *wkWebConfig = [[WKWebViewConfiguration alloc] init];
[wkWebConfig setURLSchemeHandler:self forURLScheme:@"https"];
[wkWebConfig setURLSchemeHandler:self forURLScheme:@"http"];
_wkWebView = [[WKWebView alloc]initWithFrame:self.view.frame configuration:wkWebConfig];
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"https://www.xvideos.com"] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:15];
[_wkWebView loadRequest:request];
[self.view addSubview:_wkWebView];
}
- (void)webView:(WKWebView *)webView startURLSchemeTask:(id <WKURLSchemeTask>)urlSchemeTask {
NSURLRequest *request = urlSchemeTask.request;
if (request == nil)
return;
dispatch_queue_t taskQ = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0);
NSURLSessionDataTask *task = [[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
dispatch_async(taskQ, ^{
if (!data) {
return;
} else {
// [urlSchemeTask didReceiveResponse:response];
// [urlSchemeTask didReceiveData:data];
[self postResponse:urlSchemeTask response:response];
if (![self hasTaskStopped:urlSchemeTask]) {
[self postResponse:urlSchemeTask data:data];
}
}
[self postFinished:urlSchemeTask];
NSPredicate *pred = [NSPredicate predicateWithFormat:@"SELF != %@",request];
[self.stoppedTaskURLs filterUsingPredicate:pred];
});
}];
[task resume];
}
- (BOOL) hasTaskStopped:(id <WKURLSchemeTask>) urlSchemeTask {
//return self.stoppedTaskURLs.contains{$0 == urlSchemeTask.request}
if ([self.stoppedTaskURLs containsObject:urlSchemeTask.request]) {
return true;
}
return false;
}
- (void) postResponse:(id <WKURLSchemeTask>) urlSchemeTask response:(NSURLResponse *) response {
[self post:urlSchemeTask action:^(void){
[urlSchemeTask didReceiveResponse:response];
}];
}
- (void) postResponse:(id <WKURLSchemeTask>) urlSchemeTask data:(NSData *) data {
[self post:urlSchemeTask action:^(void){
[urlSchemeTask didReceiveData:data];
}];
}
- (void) postFinished:(id <WKURLSchemeTask>) urlSchemeTask {
[self post:urlSchemeTask action:^(void){
[urlSchemeTask didFinish];
}];
}
- (void) postFailed:(id <WKURLSchemeTask>) urlSchemeTask error:(NSError *) error{
[self post:urlSchemeTask action:^(void){
[urlSchemeTask didFailWithError:error];
}];
}
- (void) post:(id <WKURLSchemeTask>) urlSchemeTask action:(void (^)(void)) action {
dispatch_group_t group = dispatch_group_create();
dispatch_group_enter(group);
dispatch_async(dispatch_get_main_queue(), ^{
if ([self hasTaskStopped:urlSchemeTask] == false) {
action();
}
dispatch_group_leave(group);
});
dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
}
- (void)webView:(WKWebView *)webView stopURLSchemeTask:(id <WKURLSchemeTask>)urlSchemeTask {
dispatch_semaphore_wait(self.listSema, DISPATCH_TIME_FOREVER);
NSLog(@"%@", urlSchemeTask.request.URL.absoluteString);
dispatch_semaphore_signal(self.listSema);
}
- (void)dealloc {
[NSURLProtocol unregisterClass:[LSURLProtocol class]];
}
@end