4

I'm working on a Iphone app that needs to open remote html files and use local images. I found this answer and it's the perfect solution for me :

iOS WebView remote html with local image files

but the problem is that this solution loads only the first image when I'm trying to load more images, like so :

<html>
<body>
    <h1>we are loading a custom protocl</h1>
    <b>image?</b><br/>
    <img src="myapp://image1.png" />
<img src="myapp://image1.png" />
<img src="myapp://image2.png" />
<img src="myapp://image3.png" />
<body>
</html>

The page will display the first image right but the other images will display the source of the first.

Community
  • 1
  • 1
user1920678
  • 51
  • 1
  • 6
  • the link you posted for the code to implement a custom protocol is hardcoded to load "image1.png" from the main bundle. you need to extract the image filename from the request URL and use that instead. – XJones Dec 21 '12 at 06:27
  • @XJones the code load first image with any name not just img1 that's mean the code works to extract file name – user1920678 Dec 21 '12 at 06:42
  • I'm very much love to see the answers. – HelmiB Dec 21 '12 at 07:01

3 Answers3

1

Why are you using custom protocol implementations for loading local images in a html file ?

You can easily set the root of the html to the following :

[webView loadHTMLString:htmlString baseURL:[[NSBundle mainBundle] bundleURL]];

This will load all image files from your bundle.

Or, you can override the load call, with a webview delegate like so :

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType

And there completely customize how and where files should be loaded.

Nils Munch
  • 8,805
  • 11
  • 51
  • 103
0

you can use the same idea in iOS WebView remote html with local image files but, use different custom protocol name for each image For example

<html>
<body>
    <h1>we are loading a custom protocl</h1>
    <b>image?</b><br/>
    <img src="myapp://image1.png" />
<img src="myapp1://image1.png" />
<img src="myapp2://image2.png" />
<img src="myapp3://image3.png" />
<body>
</html>

Then ask which protocol name used in the canInitWithRequest method, then you can know which image you will load in startLoading method.

Note : canInitWithRequest is a class method therefore you can declare a static variable to hold the image file name in canInitWithRequest method

Community
  • 1
  • 1
0

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 !!!

Harish Pathak
  • 1,567
  • 1
  • 18
  • 32