Skip to content

Commit

Permalink
Allow plugins to hook into the WKURLSchemeHandler (#1030)
Browse files Browse the repository at this point in the history
  • Loading branch information
NiklasMerz authored Jan 31, 2021
1 parent fb5fd2f commit 1e331b7
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 35 deletions.
2 changes: 2 additions & 0 deletions CordovaLib/Classes/Public/CDVURLSchemeHandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@

@property (nonatomic, strong) CDVViewController* viewController;

@property (nonatomic) CDVPlugin* schemePlugin;

- (instancetype)initWithVC:(CDVViewController *)controller;


Expand Down
97 changes: 62 additions & 35 deletions CordovaLib/Classes/Public/CDVURLSchemeHandler.m
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ Licensed to the Apache Software Foundation (ASF) under one
#import "CDVURLSchemeHandler.h"
#import <MobileCoreServices/MobileCoreServices.h>

#import <objc/message.h>

@implementation CDVURLSchemeHandler


Expand All @@ -39,52 +41,77 @@ - (void)webView:(WKWebView *)webView startURLSchemeTask:(id <WKURLSchemeTask>)ur
NSURL * url = urlSchemeTask.request.URL;
NSString * stringToLoad = url.path;
NSString * scheme = url.scheme;

CDVViewController* vc = (CDVViewController*)self.viewController;

/*
* Give plugins the chance to handle the url
*/
BOOL anyPluginsResponded = NO;
BOOL handledRequest = NO;

NSDictionary *pluginObjects = [[vc pluginObjects] copy];
for (NSString* pluginName in pluginObjects) {
self.schemePlugin = [vc.pluginObjects objectForKey:pluginName];
SEL selector = NSSelectorFromString(@"overrideSchemeTask:");
if ([self.schemePlugin respondsToSelector:selector]) {
handledRequest = (((BOOL (*)(id, SEL, id <WKURLSchemeTask>))objc_msgSend)(self.schemePlugin, selector, urlSchemeTask));
if (handledRequest) {
anyPluginsResponded = YES;
break;
}
}
}

if ([scheme isEqualToString:self.viewController.appScheme]) {
if ([stringToLoad hasPrefix:@"/_app_file_"]) {
startPath = [stringToLoad stringByReplacingOccurrencesOfString:@"/_app_file_" withString:@""];
} else {
if ([stringToLoad isEqualToString:@""] || [url.pathExtension isEqualToString:@""]) {
startPath = [startPath stringByAppendingPathComponent:self.viewController.startPage];
if (!anyPluginsResponded) {
if ([scheme isEqualToString:self.viewController.appScheme]) {
if ([stringToLoad hasPrefix:@"/_app_file_"]) {
startPath = [stringToLoad stringByReplacingOccurrencesOfString:@"/_app_file_" withString:@""];
} else {
startPath = [startPath stringByAppendingPathComponent:stringToLoad];
if ([stringToLoad isEqualToString:@""] || [url.pathExtension isEqualToString:@""]) {
startPath = [startPath stringByAppendingPathComponent:self.viewController.startPage];
} else {
startPath = [startPath stringByAppendingPathComponent:stringToLoad];
}
}
}
}

NSError * fileError = nil;
NSData * data = nil;
if ([self isMediaExtension:url.pathExtension]) {
data = [NSData dataWithContentsOfFile:startPath options:NSDataReadingMappedIfSafe error:&fileError];
}
if (!data || fileError) {
data = [[NSData alloc] initWithContentsOfFile:startPath];
}
NSInteger statusCode = 200;
if (!data) {
statusCode = 404;
}
NSURL * localUrl = [NSURL URLWithString:url.absoluteString];
NSString * mimeType = [self getMimeType:url.pathExtension];
id response = nil;
if (data && [self isMediaExtension:url.pathExtension]) {
response = [[NSURLResponse alloc] initWithURL:localUrl MIMEType:mimeType expectedContentLength:data.length textEncodingName:nil];
} else {
NSDictionary * headers = @{ @"Content-Type" : mimeType, @"Cache-Control": @"no-cache"};
response = [[NSHTTPURLResponse alloc] initWithURL:localUrl statusCode:statusCode HTTPVersion:nil headerFields:headers];
}
NSError * fileError = nil;
NSData * data = nil;
if ([self isMediaExtension:url.pathExtension]) {
data = [NSData dataWithContentsOfFile:startPath options:NSDataReadingMappedIfSafe error:&fileError];
}
if (!data || fileError) {
data = [[NSData alloc] initWithContentsOfFile:startPath];
}
NSInteger statusCode = 200;
if (!data) {
statusCode = 404;
}
NSURL * localUrl = [NSURL URLWithString:url.absoluteString];
NSString * mimeType = [self getMimeType:url.pathExtension];
id response = nil;
if (data && [self isMediaExtension:url.pathExtension]) {
response = [[NSURLResponse alloc] initWithURL:localUrl MIMEType:mimeType expectedContentLength:data.length textEncodingName:nil];
} else {
NSDictionary * headers = @{ @"Content-Type" : mimeType, @"Cache-Control": @"no-cache"};
response = [[NSHTTPURLResponse alloc] initWithURL:localUrl statusCode:statusCode HTTPVersion:nil headerFields:headers];
}

[urlSchemeTask didReceiveResponse:response];
if (data) {
[urlSchemeTask didReceiveData:data];
[urlSchemeTask didReceiveResponse:response];
if (data) {
[urlSchemeTask didReceiveData:data];
}
[urlSchemeTask didFinish];
}
[urlSchemeTask didFinish];

}

- (void)webView:(nonnull WKWebView *)webView stopURLSchemeTask:(nonnull id<WKURLSchemeTask>)urlSchemeTask
{

SEL selector = NSSelectorFromString(@"stopSchemeTask:");
if (self.schemePlugin != nil && [self.schemePlugin respondsToSelector:selector]) {
(((void (*)(id, SEL, id <WKURLSchemeTask>))objc_msgSend)(self.schemePlugin, selector, urlSchemeTask));
}
}

-(NSString *) getMimeType:(NSString *)fileExtension {
Expand Down

0 comments on commit 1e331b7

Please sign in to comment.