2

I have a UIWebView that loads a PDF using Basic Auth like so

NSURL* url = [[NSURL alloc] initWithString:_urlString];
NSString *authStr = [NSString stringWithFormat:@"%@:%@", usr, pwd];
NSData *authData = [authStr dataUsingEncoding:NSASCIIStringEncoding];
NSString *authValue = [NSString stringWithFormat:@"Basic %@", [authData base64EncodedStringWithOptions:NSDataBase64Encoding76CharacterLineLength]];
NSMutableURLRequest *mutableRequest = [[NSMutableURLRequest alloc] initWithURL:url];
[mutableRequest setValue:authValue forHTTPHeaderField:@"Authorization"];
[_webView loadRequest:mutableRequest];

Is there a way for me to easily save this PDF file onto disk? I've tried this but failed:

NSData *fileData = [[NSData alloc] initWithContentsOfURL:_webView.request.URL];

My URL looks like this: www.domain.com/files/foo.pdf

7ball
  • 2,183
  • 4
  • 26
  • 61
  • `initWithContentsOfURL:` method of `NSData` does a simple GET, but you needed to set tom Auth params that's why it fails. What about: https://stackoverflow.com/questions/992348/reading-html-content-from-a-uiwebview to retrieve the content (already downloaded) from the UIWebView, and then save it? – Larme Sep 05 '17 at 09:43
  • I tried evaluating the javascript in webViewDidFinishLoad but it returns an empty string. Probably because I'm only having UIWebView load a PDF, not any actual HTML markup. – 7ball Sep 05 '17 at 16:22
  • Try `[[[NSURLSession sharedSession] dataTaskWithRequest:mutableRequest completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) { if (data) { //SaveDataIntoDisk + dispatch_async(dispatch_get_main_queue(), ^(){ [_webView loadData:data MIMEType:@"application/pdf" textEncodingName:@"UTF-8" baseURL:nil]; }); } }] resume];`? – Larme Sep 05 '17 at 16:28
  • @Larme This works perfectly. If you want to write up an answer, I'll accept it. For future readers, I'll include what I ended up doing in an EDIT. – 7ball Sep 05 '17 at 17:00

3 Answers3

2

-initWithContentsOfURL: method of NSData does a simple HTTP GET, but you needed to set some Authorization params that's why it fails.

To avoid downloading twice the data, you could use NSURLSession to download it, save it, and use the -loadData:MIMEType:textEncodingName:baseURL: of UIWebView to load it.

NSMutableURLRequest *mutableRequest = //Your Custom request with URL and Headers
[[[NSURLSession sharedSession] dataTaskWithRequest:mutableRequest completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) 
{
    if (data) 
    { 
        //SaveDataIntoDisk
        dispatch_async(dispatch_get_main_queue(), ^(){ 
            [_webView loadData:data MIMEType:@"application/pdf" textEncodingName:@"UTF-8" baseURL:nil]; 
        }); 
    } 
}] resume];
Larme
  • 24,190
  • 6
  • 51
  • 81
1

For Swift :

        let webView = UIWebView()
        let url = URL(string: "")!
        let urlRequest : URLRequest = URLRequest(url: url)
        let task = URLSession.shared.dataTask(with: urlRequest , completionHandler: { (data, urlResponse, error) in

            if (data != nil){
                DispatchQueue.main.async {
                    webView.load(data!, mimeType: "application/pdf", textEncodingName: "UTF-8", baseURL: url)
                }
            }
        })
        task.resume()
Manikandan
  • 1,195
  • 8
  • 26
0

Another Approach:- You can download the PDF file Data and save it in Temp Directory or Your Prefered Directory. then use that saved directory to open the file in WebView.

        URLSession.shared.dataTask(with: url) { data, response, error in
                    guard let data = data, error == nil else {

                        return
                    }
//MARK:- Now Saving the Document Data into Directory. I am using the temp directory you can change it to yours.
                    let tempDirectory = URL(fileURLWithPath: NSTemporaryDirectory())
                    self.tmpURL = tempDirectory.appendingPathComponent(response?.suggestedFilename ?? "fileName.png")

                     do {
                        try data.write(to: self.tmpURL! )
                     } catch {
                        print(error)
                     }
                     DispatchQueue.main.async {
 //MARK:- Instead of using MIME type and NSData .now you can use the file directory to open the file in WEBView
                         self.webView.loadFileURL(self.tmpURL!, allowingReadAccessTo: self.tmpURL!)     
                      }
                } 
Manikandan
  • 1,195
  • 8
  • 26