iosobjective-cuiwebviewcgpdf

How to open Password Protected PDF/DOC in UIWebview without using a temp file?


We are trying to open a password protected PDF/DOC file in UIWebview. Due to security concern, we can only retrieve the files from server and store into memory (i.e. NSData), but cannot store as a file.

We tried to use loaddata function in UIWebiew and it can only success to load doc/xls/ppt/pdf without password protected.

For doc/xls files with password, it shows "Unable to Read Document. The operation couldn't be completed (QuickLookErrorDomain error 44820/912". May I ask how can we open the file in UIWebview?

For pdf file with password, it shows "The document "blank" is password protected". May I ask how can we show the correct document name instead of "Blank"?

I have also searched the cgpdf and know how to unlock the pdf file as CGPDFDocumentRef, but cannot find the way to change it back to NSData and input into UIWebview directly.

Thanks.


Solution

  • Write file in local and read the data and show it in web view

    //convert file data(ie : NSData) as string
    NSData *fileData;//This is the data from your request
    NSString *fileString = [[NSString alloc] initWithData:fileData encoding:NSUTF8StringEncoding];
    
    //get the file path
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *filePath = [[paths objectAtIndex:0] stringByAppendingPathComponent:@"sample.pdf"];
    
    //Save as file
    NSError *error;
    BOOL hasFileWritten = [fileString writeToFile:filePath atomically:YES encoding:NSUTF8StringEncoding error:&error];
    
    if(!hasFileWritten)
    {
        NSLog(@"Write file error: %@", error);
    }
    
    //open pdf in webview
    NSURL *targetURL = [NSURL fileURLWithPath:filePath];
    NSURLRequest *request = [NSURLRequest requestWithURL:targetURL];
    [webView loadRequest:request];
    

    Update without writing the file data in local, Process the data in memory and show the pdf file in webview

    @interface ViewController ()
    {
        IBOutlet UIWebView *webView;
        CATiledLayer *tiledLayer;
        CGPDFPageRef pageRef;
    }
    @end
    
    
    CGPDFDocumentRef pdf = CGPDFDocumentCreateWithURL((CFURLRef)url);
    
    BOOL success = CGPDFDocumentUnlockWithPassword(pdf, "test");
    
    if(success)
    {
        pageRef = CGPDFDocumentGetPage(pdf, 1);
    
        CGRect pageRect = self.view.frame;
    
        tiledLayer = [CATiledLayer layer];
        tiledLayer.delegate = self;
        tiledLayer.tileSize = CGSizeMake(1024.0, 1024.0);
        tiledLayer.levelsOfDetail = 1000;
        tiledLayer.levelsOfDetailBias = 1000;
        tiledLayer.frame = pageRect;
    
        UIView *contentView = [[UIView alloc] initWithFrame:pageRect];
        [contentView.layer addSublayer:tiledLayer];
    
        [webView addSubview:contentView];
    }
    
    
    - (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx
    {
        CGContextSetRGBFillColor(ctx, 1.0, 1.0, 1.0, 1.0);
        CGContextFillRect(ctx, CGContextGetClipBoundingBox(ctx));
        CGContextTranslateCTM(ctx, 0.0, layer.bounds.size.height);
        CGContextScaleCTM(ctx, 1.0, -1.0);
        CGContextConcatCTM(ctx, CGPDFPageGetDrawingTransform(pageRef, kCGPDFCropBox, layer.bounds, 0, true));
        CGContextDrawPDFPage(ctx, pageRef);
    }