-
Notifications
You must be signed in to change notification settings - Fork 28
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
iOS Support #2
Comments
Hello, Are you getting any error? Also what are you getting in the log? |
Hi, I am not getting any error in Xcode log, but will see the Safari developer console for JS error. Did the plugin work at your end? |
Nope, I'm gonna try and fix it this week. |
I only see this error in my Safari inspect window - |
@PeterHdd I am also facing the same issue. |
yes IOS part is not working, only android part until now. Still checking the ios part. |
Ok, let me know if you need any help in debugging. |
If you are able to figure it out also, please commit it, thank you! |
OK, so I have been testing and trying to make it work on IOS, but its not working. So, I need either of you to help me(@FawadNL @an-rahulpandey ) as my knowledge in iOS or objective C is null actually. So here is the thing, the iOS part has not been updated for 4 years, so basically I need to fix everything. First since ionic webview version 2.0+ works on localhost:8080 server, then the plugin Therefore in the javascript part, I did the following if it is platform iOS (it works): if (platform == 'ios') {
var pluginDir;
console.log(platformInfo);
var iosProject = platformInfo.locations.xcodeCordovaProj;
pluginDir = path.join(iosProject, 'Plugins',context.opts.plugin.id);
replaceCryptKey_ios(pluginDir, key, iv);
var cfg = new ConfigParser(platformInfo.projectConfig.path);
var port = cfg.getGlobalPreference("cryptoPort");
if( port == '')
{
cfg.doc.getroot().getchildren().filter(function(child, idx, arr) {
return (child.tag == 'content');
}).forEach(function(child) {
child.attrib.src = 'http://localhost:8080/' + child.attrib.src;
});
}
else
{
cfg.doc.getroot().getchildren().filter(function(child, idx, arr) {
return (child.tag == 'content');
}).forEach(function(child) {
child.attrib.src = 'http://localhost:' + port + '/' + child.attrib.src;
});
}
cfg.write();
}
Now, the file that needs to be modified is #import "CDVCryptURLProtocol.h"
#import <MobileCoreServices/MobileCoreServices.h>
#import <CommonCrypto/CommonCryptor.h>
#import <CommonCrypto/CommonDigest.h>
static NSString* const kCryptKey = @" ";
static NSString* const kCryptIv = @" ";
static int const kIncludeFileLength = 1;
static int const kExcludeFileLength = 0;
static NSString* const kIncludeFiles[] = { @"\\.(htm|html|js|css)$" };
static NSString* const kExcludeFiles[] = { };
NSString *retrievePath;
NSString *wwwPath;
NSString *checkPath;
@implementation CDVCryptURLProtocol
+ (BOOL)canInitWithRequest:(NSURLRequest*)theRequest
{
NSLog(@"the url inside the init request: %@",theRequest);
if ([self checkCryptFile:theRequest.URL]) {
return YES;
}
return [super canInitWithRequest:theRequest];
}
- (void)startLoading
{
NSURL* url = self.request.URL;
wwwPath = [[NSBundle mainBundle].resourcePath stringByAppendingString:@"/www"];
NSString *urling = [@"file://"stringByAppendingString:wwwPath];
NSString *urlings = [urling stringByAppendingString:checkPath];
NSString *finalUrl = [urlings stringByReplacingOccurrencesOfString:@" " withString:@"%20"];
NSURL *urls = [[NSURL alloc] initWithString:finalUrl];
url = urls;
// if ([[self class] checkCryptFile:url]) {
NSString *mimeType = [self getMimeType:url];
NSError* error;
NSString* content = [[NSString alloc] initWithContentsOfFile:url.path encoding:NSUTF8StringEncoding error:&error];
if(error)
{
NSLog(@"the error inside is: %@", error);
}
if (!error) {
NSLog(@"Decrypt: %@",url);
NSData* data = [self decryptAES256WithKey:kCryptKey iv:kCryptIv data:content];
[self sendResponseWithResponseCode:200 data:data mimeType:mimeType];
}
[super startLoading];
}
+ (BOOL)checkCryptFile:(NSURL *)url {
checkPath = [url.path stringByReplacingOccurrencesOfString:@"http://localhost:8080/" withString:@""];//index.html
NSLog(@"the check path: %@", checkPath); //index.html
if (![self hasMatch:checkPath regexArr:kIncludeFiles length:kIncludeFileLength]) {
return NO;
}
if ([self hasMatch:checkPath regexArr:kExcludeFiles length:kExcludeFileLength]) {
return NO;
}
return YES;
}
+ (BOOL)hasMatch:(NSString *)text regexArr:(NSString* const [])regexArr length:(int)length {
for (int i = 0; i < length; i++) {
NSString* const regex = regexArr[i];
if ([self isMatch:text pattern:regex]) {
return YES;
}
}
return NO;
}
+ (BOOL)isMatch:(NSString *)text pattern:(NSString *)pattern {
NSError *error = nil;
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:pattern options:0 error:&error];
if (error) {
return NO;
}
if ([regex firstMatchInString:text options:0 range:NSMakeRange(0, text.length)]) {
return YES;
}
return NO;
}
- (NSString*)getMimeType:(NSURL *)url
{
NSString *fullPath = url.path;
NSString *mimeType = nil;
if (fullPath) {
CFStringRef typeId = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, (__bridge CFStringRef)[fullPath pathExtension], NULL);
if (typeId) {
mimeType = (__bridge_transfer NSString*)UTTypeCopyPreferredTagWithClass(typeId, kUTTagClassMIMEType);
if (!mimeType) {
// special case for m4a
if ([(__bridge NSString*)typeId rangeOfString : @"m4a-audio"].location != NSNotFound) {
mimeType = @"audio/mp4";
} else if ([[fullPath pathExtension] rangeOfString:@"wav"].location != NSNotFound) {
mimeType = @"audio/wav";
} else if ([[fullPath pathExtension] rangeOfString:@"css"].location != NSNotFound) {
mimeType = @"text/css";
}
}
CFRelease(typeId);
}
}
return mimeType;
}
- (NSData *)decryptAES256WithKey:(NSString *)key iv:(NSString *)iv data:(NSString *)base64String {
NSLog(@"inside decrypt");
NSData *data = [[NSData alloc] initWithBase64EncodedString:base64String options:0];
size_t bufferSize = [data length] + kCCBlockSizeAES128;
void *buffer = malloc(bufferSize);
size_t numBytesDecrypted = 0;
NSData *keyData = [key dataUsingEncoding:NSUTF8StringEncoding];
NSData *ivData = [iv dataUsingEncoding:NSUTF8StringEncoding];
CCCryptorStatus status = CCCrypt(kCCDecrypt,
kCCAlgorithmAES128,
kCCOptionPKCS7Padding,
keyData.bytes,
kCCKeySizeAES256,
ivData.bytes,
data.bytes,
data.length,
buffer,
bufferSize,
&numBytesDecrypted);
if (status == kCCSuccess) {
return [NSData dataWithBytes:buffer length:numBytesDecrypted];
}
free(buffer);
return nil;
}
- (NSString*)getMimeTypeFromPath:(NSString*)fullPath
{
NSString* mimeType = nil;
if (fullPath) {
CFStringRef typeId = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, (__bridge CFStringRef)[fullPath pathExtension], NULL);
if (typeId) {
mimeType = (__bridge_transfer NSString*)UTTypeCopyPreferredTagWithClass(typeId, kUTTagClassMIMEType);
if (!mimeType) {
// special case for m4a
if ([(__bridge NSString*)typeId rangeOfString : @"m4a-audio"].location != NSNotFound) {
mimeType = @"audio/mp4";
} else if ([[fullPath pathExtension] rangeOfString:@"wav"].location != NSNotFound) {
mimeType = @"audio/wav";
} else if ([[fullPath pathExtension] rangeOfString:@"css"].location != NSNotFound) {
mimeType = @"text/css";
}
}
CFRelease(typeId);
}
}
return mimeType;
}
- (void)sendResponseWithResponseCode:(NSInteger)statusCode data:(NSData*)data mimeType:(NSString*)mimeType
{
NSLog(@"inside response");
if (mimeType == nil) {
mimeType = @"text/plain";
}
NSHTTPURLResponse* response = [[NSHTTPURLResponse alloc] initWithURL:[[self request] URL] statusCode:statusCode HTTPVersion:@"HTTP/1.1" headerFields:@{@"Content-Type" : mimeType}];
[[self client] URLProtocol:self didReceiveResponse:response cacheStoragePolicy:NSURLCacheStorageNotAllowed];
if (data != nil) {
[[self client] URLProtocol:self didLoadData:data];
}
[[self client] URLProtocolDidFinishLoading:self];
}
+ (NSURLRequest*)canonicalRequestForRequest:(NSURLRequest*)request
{
NSLog(@"%@ received %@", self, NSStringFromSelector(_cmd));
return request;
}
@end To explain this, the Then in the
But the problem is I keep getting a white screen with no data and nothing just a white screen. So, it is decrypting and you can see in the log when you run it, but in the simulator (iPhone XR), I keep getting white screen after its loaded. Note: Also im testing this without Summary: Good Part: Javascript part of Bad Part: After finishing loading, only white screen is appearing in the app, sometimes the design and the data appear in the screen though. |
@PeterHdd Thanks for trying. I am also looking it now. |
@PeterHdd The plugin works properly, the problem is with the decryption time. If you open the safari inspect window and press reload button you will see that it will work one in five times. The plugins JS files sometimes doesn't get decrypted properly which also gives error. Also I have noticed that sometimes the files contents are overwritten by other files. See the Resources tab in inspect window and try to see some js files. For e.g device plugin js content will be also shown in splashscreen js file, main.js file content shown in vendor.js file, etc.. |
@PeterHdd I am seeing same issue with decryption time, however my knowledge of objective-C is also null so I can't help you unfortunately. Hope you find a fix soon. |
According to my tests using cordova-plugin-ionic-webview, canInitWithRequest isn't even being instantiated. Something to do with CDVURLProtocol not working with WkWebView I suppose. |
Hello, |
@PeterHdd where is the update? Still ios not working. Nothing there after January |
hello any updates ????????????????????????? |
If there is an ios developer who is willing to fix this, please let me know (I can help pay for your time and efforts, God willing). Thank you. |
@givethanks1 check the forks, maybe someone fixed it there |
Updates to include @PeterHdd code from PeterHdd#2
More updates from PeterHDD code PeterHdd#2
Hi,
It is not working with iOS. The files are getting encrypted properly, but when I run the app via Xcode, the app gets stuck at splashscreen.
The text was updated successfully, but these errors were encountered: