Skip to content

Instantly share code, notes, and snippets.

@log2c
Created November 16, 2021 01:37
Show Gist options
  • Save log2c/5e71f3c13e31616e86db6ecef1c408f8 to your computer and use it in GitHub Desktop.
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
#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