Implement WKURLSchemeHandler to intercept http, https error NSInternalInconsistencyException

246 Views Asked by At

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
0

There are 0 best solutions below