WKWebView 将 pdf 保存到 ibooks,从链接保存 pdf

Posted

技术标签:

【中文标题】WKWebView 将 pdf 保存到 ibooks,从链接保存 pdf【英文标题】:WKWebView save pdf to ibooks, save pdf from link 【发布时间】:2016-11-08 15:48:42 【问题描述】:

我是 Junior,目前正在从事我在 WKWebView 中的项目,并且有打开 pdf 的链接。我可以在 Safari 中打开它,然后在 iBooks 中打开它,但我希望它在我的应用程序中完成。是否可以 ?

下面是它的样子:

我可以选择pdf的图片

想象一下它会打开什么

我的网络视图类

class WebVC: UIViewController, WKUIDelegate 



var webView: WKWebView!

override func viewDidLoad() 
    super.viewDidLoad()
    let myURL = NSURL(string: "\(savedURL!)")
    let myRequest = URLRequest(url: myURL! as URL)
    webView.load(myRequest)
    webView.allowsBackForwardNavigationGestures = true
    webView.allowsLinkPreview = false


override func viewWillAppear(_ animated: Bool) 
    self.navigationController?.toolbar.isHidden = false


override func loadView() 
    let webConfiguration = WKWebViewConfiguration()
    webView = WKWebView(frame: CGRect(x: 100, y: 100, width: 110, height: 110), configuration: webConfiguration)
    webView.uiDelegate = self
    view = webView



@IBAction func logoutPressed(_ sender: AnyObject) 
    defaults.set(false, forKey: "isLogged")
    defaults.set("EMPTY URL", forKey: "savedURL")
    _ = self.navigationController?.popToRootViewController(animated: true)



@IBAction func goBack(_ sender: Any?) 
    if (self.webView.canGoBack) 
        self.webView.goBack()
    



【问题讨论】:

【参考方案1】:

在 webview 中打开 pdf

//第一步

webview.uiDelegate = self

//第 2 步 - 实现委托函数(此函数将让您在 webview 中打开任何点击的 pdf)

func webView(_ webView: WKWebView, createWebViewWith configuration: WKWebViewConfiguration, for navigationAction: WKNavigationAction, windowFeatures: WKWindowFeatures) -> WKWebView? 

     // open in current view
     webView.load(navigationAction.request)
     // don't return a new view to build a popup into (the default behavior).
     return nil;
 

下载

在我的情况下,一旦我在 webview 中打开了 pdf,我就有了下载按钮,我用它来下载当前打开的 pdf

//第 3 步 - 委托函数

    func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) 
        decisionHandler(WKNavigationActionPolicy.allow)
    
    //find the mimeTime of the current url opened in webview, If it's pdf, we'll give option to download 
    func webView(_ webView: WKWebView, decidePolicyFor navigationResponse: WKNavigationResponse, decisionHandler: @escaping (WKNavigationResponsePolicy) -> Void) 
        
        if let mimeType = navigationResponse.response.mimeType 
            //check if mime exists in our acceptable mimes list
            if self.isMimeTypeConfigured(mimeType) 
                self.mime = mimeType
                self.currentUrl = navigationResponse.response.url
                addDownloadButton()
            
        
        decisionHandler(.allow)
    

//第 4 步 - 使用辅助函数创建扩展

//=== PDF downloading ===
struct MimeType 
    var type:String
    var fileExtension:String

extension DownloadManual 
    //button
    private func addDownloadButton()
        let btn = UIBarButtonItem(image: UIImage(systemName: "tray.and.arrow.down.fill"), style: .plain, target: nil, action: #selector(downloadTapped))
        self.navigationItem.rightBarButtonItem = btn
    
    @objc func downloadTapped()
        self.showActivityIndicator(show: true)
        if let url = currentUrl 
            print("download from: \(url)")
            let filename = getDefaultFileName(forMimeType: self.mime)
            
            downloadData(fromURL: url, fileName: filename)  success, destinationURL in
                if success, let destinationURL = destinationURL 
                    
                    self.showActivityIndicator(show: false)
                    print("download result: \(success), \(destinationURL)")
                    self.fileDownloadedAtURL(url: destinationURL)
                
            
        
    
    
    //helper funcs
    private func isMimeTypeConfigured(_ mimeType:String) -> Bool 
        for record in self.mimeTypes 
            if mimeType.contains(record.type) 
                return true
            
        
        return false
    
    
    func fileDownloadedAtURL(url: URL) 
        print("downloaded at: \(url)")
        DispatchQueue.main.async 
            let activityVC = UIActivityViewController(activityItems: [url], applicationActivities: nil)
            activityVC.popoverPresentationController?.sourceView = self.view
            activityVC.popoverPresentationController?.sourceRect = self.view.frame
            activityVC.popoverPresentationController?.barButtonItem = self.navigationItem.rightBarButtonItem
            self.present(activityVC, animated: true, completion: nil)
        
    
    private func downloadData(fromURL url:URL,
                              fileName:String,
                              completion:@escaping (Bool, URL?) -> Void) 
        webview.configuration.websiteDataStore.httpCookieStore.getAllCookies()  cookies in
            let session = URLSession.shared
            print("downloading ....")
            session.configuration.httpCookieStorage?.setCookies(cookies, for: url, mainDocumentURL: nil)
            let task = session.downloadTask(with: url)  localURL, urlResponse, error in
                if let localURL = localURL 
                    let destinationURL = self.moveDownloadedFile(url: localURL, fileName: fileName)
                    completion(true, destinationURL)
                
                else 
                    completion(false, nil)
                
            

            task.resume()
        
    
    private func getDefaultFileName(forMimeType mimeType:String) -> String 
        for record in self.mimeTypes 
            if mimeType.contains(record.type) 
                return "default." + record.fileExtension
            
        
        return "default"
    
    
    private func moveDownloadedFile(url:URL, fileName:String) -> URL 
        let tempDir = NSTemporaryDirectory()
        let destinationPath = tempDir + fileName
        let destinationURL = URL(fileURLWithPath: destinationPath)
        try? FileManager.default.removeItem(at: destinationURL)
        try? FileManager.default.moveItem(at: url, to: destinationURL)
        return destinationURL
    

希望这对某人有帮助:)

【讨论】:

【参考方案2】:

我用 UIDocumentInteractionController 解决了这个问题,添加一个按钮,当我按下按钮时,它将下载整个页面,然后在“导入到 iBooks”选项所在的位置显示 DocumentController。希望对您有所帮助。

@IBAction func shareBtn(_ sender: AnyObject) 
    var localPath: NSURL?

    Alamofire.download(webView.url!, method: .get, parameters: nil, headers: nil)  (tempUrl, response)  in

        let directoryURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
        let pathComponent = response.suggestedFilename

        localPath = directoryURL.appendingPathComponent(pathComponent!) as NSURL?
        return (destinationURL: localPath as! URL, options: .removePreviousFile)


        .response  response in
            if localPath != nil


                self.docController = UIDocumentInteractionController(url: localPath! as URL)
                self.docController.presentOptionsMenu(from: sender as! UIBarButtonItem, animated: true)

            
    

【讨论】:

这将再次下载PDF,有什么方法可以使用从WKWebView加载的PDF。

以上是关于WKWebView 将 pdf 保存到 ibooks,从链接保存 pdf的主要内容,如果未能解决你的问题,请参考以下文章

使用自定义 URL 方案将 PDF url 发送到使用 as3 和 FlashBuilder 4.6 的 iBooks 应用程序?

如何通过应用程序将 PDF 文件保存在 iPhone 设备中

如何创建 ibooks 应用程序中的书架类型 [关闭]

iBooks 打开 PDF -“无法从没有窗口的视图中呈现弹出窗口”

下载 WKWebView 中加载的嵌入式 PDF

iOS 将WKWebView内的HTML打印为PDF