diff --git a/CordovaLib/Classes/Public/CDVURLSchemeHandler.h b/CordovaLib/Classes/Public/CDVURLSchemeHandler.h index 1cd84d09d..c074fa61c 100644 --- a/CordovaLib/Classes/Public/CDVURLSchemeHandler.h +++ b/CordovaLib/Classes/Public/CDVURLSchemeHandler.h @@ -26,6 +26,8 @@ @property (nonatomic, strong) CDVViewController* viewController; +@property (nonatomic) CDVPlugin* schemePlugin; + - (instancetype)initWithVC:(CDVViewController *)controller; diff --git a/CordovaLib/Classes/Public/CDVURLSchemeHandler.m b/CordovaLib/Classes/Public/CDVURLSchemeHandler.m index 86e92aebe..333124c2a 100644 --- a/CordovaLib/Classes/Public/CDVURLSchemeHandler.m +++ b/CordovaLib/Classes/Public/CDVURLSchemeHandler.m @@ -21,6 +21,8 @@ Licensed to the Apache Software Foundation (ASF) under one #import "CDVURLSchemeHandler.h" #import +#import + @implementation CDVURLSchemeHandler @@ -39,52 +41,77 @@ - (void)webView:(WKWebView *)webView startURLSchemeTask:(id )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 ))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)urlSchemeTask { - + SEL selector = NSSelectorFromString(@"stopSchemeTask:"); + if (self.schemePlugin != nil && [self.schemePlugin respondsToSelector:selector]) { + (((void (*)(id, SEL, id ))objc_msgSend)(self.schemePlugin, selector, urlSchemeTask)); + } } -(NSString *) getMimeType:(NSString *)fileExtension {