Created
November 16, 2021 01:37
-
-
Save log2c/5e71f3c13e31616e86db6ecef1c408f8 to your computer and use it in GitHub Desktop.
ionic-webview远端网页注入cordova.js,实现https调用native功能. 替换该文件,远端待打开的 URL https://xxx.com => ionic://xxx.com
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#import "IONAssetHandler.h" | |
#import <MobileCoreServices/MobileCoreServices.h> | |
#import "CDVWKWebViewEngine.h" | |
@implementation IONAssetHandler | |
-(void)setAssetPath:(NSString *)assetPath { | |
self.basePath = assetPath; | |
} | |
- (instancetype)initWithBasePath:(NSString *)basePath andScheme:(NSString *)scheme { | |
self = [super init]; | |
if (self) { | |
_basePath = basePath; | |
_scheme = scheme; | |
} | |
return self; | |
} | |
- (void)webView:(WKWebView *)webView startURLSchemeTask:(id <WKURLSchemeTask>)urlSchemeTask | |
{ | |
NSString * startPath = @""; | |
NSURL * url = urlSchemeTask.request.URL; | |
NSString * stringToLoad = url.path; | |
NSString * scheme = url.scheme; | |
if ([scheme isEqualToString:self.scheme]) { | |
if ([stringToLoad hasPrefix:@"/_app_file_"]) { | |
startPath = [stringToLoad stringByReplacingOccurrencesOfString:@"/_app_file_" withString:@""]; | |
} else { | |
startPath = self.basePath ? self.basePath : @""; | |
if ([stringToLoad isEqualToString:@""] || [url.pathExtension isEqualToString:@""]) { | |
startPath = [startPath stringByAppendingString:@"/index.html"]; | |
} else { | |
startPath = [startPath stringByAppendingString: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]; | |
} | |
if ([localUrl.absoluteString hasPrefix: [NSString stringWithFormat:@"%@://localhost",scheme]]) { | |
[urlSchemeTask didReceiveResponse:response]; | |
[urlSchemeTask didReceiveData:data]; | |
[urlSchemeTask didFinish]; | |
}else { | |
id newRequest = [urlSchemeTask.request copy]; | |
NSRange needleRange = NSMakeRange(scheme.length, | |
localUrl.absoluteString.length - scheme.length); | |
NSString *suffix = [localUrl.absoluteString substringWithRange:needleRange]; | |
NSString *finalUrl = [NSString stringWithFormat:@"%@%@",@"https", suffix]; | |
NSLog(@"重定向至 => %@", finalUrl); | |
NSURL *newURL = [NSURL URLWithString:finalUrl]; | |
[newRequest setURL:newURL]; | |
NSURLResponse* __autoreleasing res_; | |
NSError* __autoreleasing error_ = nil; | |
NSData* result = [self sendSynchronousRequest:newRequest returningResponse:&res_ error:&error_]; | |
// NSData* result = [NSURLConnection sendSynchronousRequest:newRequest returningResponse:&res_ error:&error_]; | |
[urlSchemeTask didReceiveResponse:res_]; | |
[urlSchemeTask didReceiveData:result]; | |
[urlSchemeTask didFinish]; | |
} | |
} | |
- (void)webView:(nonnull WKWebView *)webView stopURLSchemeTask:(nonnull id<WKURLSchemeTask>)urlSchemeTask | |
{ | |
NSLog(@"stop"); | |
} | |
- (NSData *)sendSynchronousRequest:(NSURLRequest *)request returningResponse:(NSURLResponse **)response error:(NSError **)error { | |
__block NSData *blockData = nil; | |
@try { | |
__block NSURLResponse *blockResponse = nil; | |
__block NSError *blockError = nil; | |
dispatch_group_t group = dispatch_group_create(); | |
dispatch_group_enter(group); | |
NSURLSession *session = [NSURLSession sharedSession]; | |
[[session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable subData, NSURLResponse * _Nullable subResponse, NSError * _Nullable subError) { | |
blockData = subData; | |
blockError = subError; | |
blockResponse = subResponse; | |
dispatch_group_leave(group); | |
}] resume]; | |
dispatch_group_wait(group, DISPATCH_TIME_FOREVER); | |
*error = blockError; | |
*response = blockResponse; | |
} @catch (NSException *exception) { | |
NSLog(@"%@", exception.description); | |
} @finally { | |
return blockData; | |
} | |
} | |
-(NSString *) getMimeType:(NSString *)fileExtension { | |
if (fileExtension && ![fileExtension isEqualToString:@""]) { | |
NSString *UTI = (__bridge_transfer NSString *)UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, (__bridge CFStringRef)fileExtension, NULL); | |
NSString *contentType = (__bridge_transfer NSString *)UTTypeCopyPreferredTagWithClass((__bridge CFStringRef)UTI, kUTTagClassMIMEType); | |
return contentType ? contentType : @"application/octet-stream"; | |
} else { | |
return @"text/html"; | |
} | |
} | |
-(BOOL) isMediaExtension:(NSString *) pathExtension { | |
NSArray * mediaExtensions = @[@"m4v", @"mov", @"mp4", | |
@"aac", @"ac3", @"aiff", @"au", @"flac", @"m4a", @"mp3", @"wav"]; | |
if ([mediaExtensions containsObject:pathExtension.lowercaseString]) { | |
return YES; | |
} | |
return NO; | |
} | |
@end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment