WKWebView doesn't allow files to be accessed from file storage(Document directory) directly, to access file from document directory you have to use loadFileURL:allowingReadAccessToURL:
method, below is my code.
In ViewDidLoad
//Get Document directory path
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsPath = [paths objectAtIndex:0]; //Get the docs directory
//Get html from bundle and save it to document directory
NSURL *url = [[NSBundle mainBundle] URLForResource: @"fileupload" withExtension: @"html"];
NSData *data = [[NSData alloc] initWithContentsOfFile:[url path]];
[data writeToFile:[documentsPath stringByAppendingPathComponent:@"fileupload.html"] atomically:YES];
//Get image and save it to document directory
UIImage *image = [UIImage imageNamed:@"yoga.png"];
NSData *pngData = UIImagePNGRepresentation(image);
filePath = [documentsPath stringByAppendingPathComponent:@"yoga.png"]; //Add the file name
[pngData writeToFile:filePath atomically:YES]; //Write the file
filePath = [self documentsPathForFileName:@"yoga.png"];
NSLog(@"File path: %@", [self documentsPathForFileName:@"yoga.png"]);
NSURL *fileurl = [NSURL fileURLWithPath:[documentsPath stringByAppendingPathComponent:@"fileupload.html"]];
[webView loadFileURL:fileurl allowingReadAccessToURL:[NSURL fileURLWithPath:documentsPath]];
Above code saves an image from bundle to document directory, also it saves an html file(which will use img tag to load image).
Below didFinishNavigation:
//Sending Path to javascript
[webView evaluateJavaScript:[NSString stringWithFormat:@"upload('%@')", filePath] completionHandler:^(id _Nullable obj, NSError * _Nullable error) {
NSLog(@"Java script called");
}];
Utility Method to get file url
- (NSString *)documentsPathForFileName:(NSString *)name
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES);
NSString *documentsPath = [paths objectAtIndex:0];
NSURL *url = [NSURL fileURLWithPath:[documentsPath stringByAppendingPathComponent:name]];
return [url absoluteString];
}
and last the HTML file which has methods to get path from webview and load image
<html>
<head><title>demo</title>
<script>
function upload(path)
{
alert(path);
/*
var URI = "data:image/png;base64,"+path;
convertURIToImageData(URI).then(function(imageData) {
// Here you can use imageData
console.log(imageData);
});
*/
var img = document.createElement("IMG");
img.src = path;//URI;
img.border = 1;
img.height = 750;
img.width = 900;
document.getElementById('imageDiv').appendChild(img);
}
function convertURIToImageData(URI) {
return new Promise(function(resolve, reject) {
if (URI == null) return reject();
var canvas = document.createElement('canvas'),
context = canvas.getContext('2d'),
image = new Image();
image.addEventListener('load', function() {
canvas.width = image.width;
canvas.height = image.height;
context.drawImage(image, 0, 0, canvas.width, canvas.height);
resolve(context.getImageData(0, 0, canvas.width, canvas.height));
}, false);
image.src = URI;
});
}
</script>
</head>
<body>
<p><h1>This is a Demo !!!</h1></p>
<div id="imageDiv"></div>
</body>
</html>
Above method is only way I found to load image/files from document directory.
You can also send your image/file in form of data url and pass it to the javascript method(already written in html file), just convert your image to NSData and base encode to string, javascript will convert the data url to image object itself.
UIImage to data URL conversion:
UIImage *img = [UIImage imageNamed:@"yoga.png"];
NSData *data = UIImageJPEGRepresentation(img, 0.90);
data = [data base64EncodedDataWithOptions:0];
NSString *dataurl = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
Cheers !!!