Search code examples
iosswift3uiwebviewdjvu

How to view DJVU file in UIWebview


I am having iOS application in which I want to view data from .djvu file. Is there any way to read .djvu file in Swift or inside UIWebview.

I have also tried following solutions to view djvu file in uiwebview but that doesn't help.

1. Directly open djvu file in uiwebview

 let urlPage : URL! = URL(string: "http://192.168.13.5:13/myData/5451890-OP.djvu")        
 webView.loadRequest(URLRequest(url: urlPage))

2. Secondly i have tried to convert djvu file to pdf and the showing that converted pdf file into view. Reference link: https://github.com/MadhuriMane/ios-djvu-reader But that gives mirror image with low quality.

3. I have tried to preview file with the help of UIDocumentInteractionController() and it's delegate method but didn't work.

Please suggest any possible ways to do so.


Solution

  • Keeping in mind that .djvu files are less popular then similar formats like EPUB, MOBI, PDF and other eBook file formats, I would have following approach to workaround the problem.

    1) Create a Web Service to convert djvu files to pdf ex.: http://example.com/djvuToPdf/djvuFile/outputFile

    2) Read the PDF file in UIWebView

    To create a Web Service I would assume that you have access to any Linux distributed Server, in my case Ubuntu 16.04.

    Step one: Install djvulibre sudo apt-get install djvulibre-bin ghostscript

    Step two: test run $ djvups inputFile.djvu | ps2pdf - outputFile.pdf. You may also use the ddjvu command. However, files converted with ddjvu command are 10x larger than djvups command. You would want to consider to use --help the explore the settings like mode, quality and so on.

    Step three: Creating a Web Service (to keep things simple, I use PHP, use anything at your convenience [Python golang])

    <?php
    
    $inputFile = $_GET['input_file'];
    $outputFile = $_GET['output_file'];
    
    // use shell exec to execute the command
    // keep in mind that the conversion takes quite a long time
    shell_exec(sprintf("djvups %s | ps2pdf - %s", $inputFile, $outputFile));
    
    $name = $outputFile;
    //file_get_contents is standard function
    $content = file_get_contents($name);
    header('Content-Type: application/pdf');
    header('Content-Length: '.strlen( $content ));
    header('Content-disposition: inline; filename="' . $name . '"');
    header('Cache-Control: public, must-revalidate, max-age=0');
    header('Pragma: public');
    header('Expires: Sat, 26 Jul 1997 05:00:00 GMT');
    header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');
    echo $content;
    
    
    ?>
    

    Final Step: load PDF in App

    As Apple advise, consider using WKWebView in place of UIWebView.

    if let pdfURL = Bundle.main.url(forResource: "pdfFile", withExtension: "pdf", subdirectory: nil, localization: nil)  {
        do {
            let data = try Data(contentsOf: pdfURL)
            let webView = WKWebView(frame: CGRect(x:20,y:20,width:view.frame.size.width-40, height:view.frame.size.height-40))
            webView.load(data, mimeType: "application/pdf", characterEncodingName:"", baseURL: pdfURL.deletingLastPathComponent())
            view.addSubview(webView)
    
        }
        catch {
            // catch errors here
        }
    
    }