如何检测UIWebView中的单击文件链接?

时间:2017-08-09 09:27:03

标签: ios iphone swift webview uiwebview

我在我的应用中使用UIWebView,我想检测用户何时点击指向文件(pdf,doc,docx ....)的链接,而不是另一个HTML页面。 这将允许我下载文件并通过显示选项菜单打开它。

我尝试使用以下功能:

webView(_ webView: UIWebView, shouldStartLoadWith request: URLRequest,  navigationType: UIWebViewNavigationType) -> Bool

在此函数中,我获取URL,发送HEAD请求以获取响应的content-type,如果它不包含text/html,我将其下载并显示选项菜单。

这不是一个完美的解决方案,因为我需要发出同步请求才能获得content-type

之前有没有人遇到过这个问题?我该如何解决?

我试图在互联网上搜索,但找不到与此问题类似的内容

2 个答案:

答案 0 :(得分:0)

试试这个

override func viewDidLoad() {
        super.viewDidLoad()
        self.myWebview.delegate = self;

        // Do any additional setup after loading the view, typically from a nib.
        let url = URL(string: "YOUR_URL_STRING")
        debugPrint(url!)
        myWebview.loadRequest(URLRequest(url: url!))
    }

    func webView(_ webView: UIWebView, shouldStartLoadWith request: URLRequest, navigationType: UIWebViewNavigationType) -> Bool {
        debugPrint("func myWebView has been called")
        debugPrint(request.url!)
        if navigationType == UIWebViewNavigationType.linkClicked {
            if (request.url!.host! == "stackoverflow.com"){
                return true
            } else {
                //UIApplication.sharedApplication().openURL(request.URL!)
                UIApplication.shared.open(request.url!)
                return false
            }
        }
        return true
    }

希望这会对你有所帮助。

答案 1 :(得分:0)

最后,我找到了完美的解决方案。

在shouldStartLoadWith中:

   var checkingProcesses: [URL:CheckingProcess] = [:]

   func webView(_ webView: UIWebView, shouldStartLoadWith request: URLRequest, navigationType: UIWebViewNavigationType) -> Bool {

    Logger.log("WebviewViewController", "shouldStartLoadWith", "with url: \(String(describing: request.url?.absoluteString))")
    self.loadingViewLogic(hide: false)

    if let currentURL = request.url {

        if let process = self.checkingProcesses[currentURL]{

            Logger.log("WebviewViewController", "shouldStartLoadWith", "Known process: \(String(describing: process))")

            if(process.status == CheckingStatus.finished){

                if(process.filePath != nil){
                    self.openFileByPresentingOptions(pathURL: process.filePath!)
                    return false

                }else if(process.errorMessage != nil){

                    //error
                    Util.showAlert(context: self, title: "Error getting URL type", message: process.errorMessage!, alertActions: nil)
                    process.clearResults()//In order to try the next time the user asks.
                    self.loadingViewLogic(hide: true)
                    return false

                }else{

                    //link - open it
                    return true
                }

            }else if(process.status == CheckingStatus.processing){

                Util.showAlert(context: self, title: "Processing...", message: "Please wait...", alertActions: nil)
                return false

            }else{//inactive

                self.checkingProcesses[currentURL]?.startCheck()
                return false
            }

        }else{// did not create the process yet

            Logger.log("WebviewViewController", "shouldStartLoadWith", "Creating new process for URL: \(currentURL.absoluteString)")

            self.checkingProcesses[currentURL] = CheckingProcess(url: currentURL, webView: self.webView)
            self.checkingProcesses[currentURL]?.startCheck()
            return false
        }

    }else{

        Logger.log("WebviewViewController", "shouldStartLoadWith", "Couldn't get the currentURL")
        self.loadingViewLogic(hide: true)
        return false
    }

}

我创建了一个类" CheckingProcess.swift":

import UIKit

public enum CheckingStatus {
    case inactive
    case processing
    case finished
}

class CheckingProcess: CustomStringConvertible {

    var status : CheckingStatus;
    var url: URL;
    var filePath: URL? = nil;
    var errorMessage: String? = nil;
    let webView: UIWebView?

    init(url: URL, webView: UIWebView) {

        Logger.log("CheckingProcess", "init", "with url: \(url.absoluteString)")
        self.status = CheckingStatus.inactive;
        self.url = url;
        self.webView = webView
    }

    func startCheck(){

        Logger.log("CheckingProcess", "startCheck", "with url: \(self.url.absoluteString), START")
        self.status = CheckingStatus.processing

        let destinationUrl = Util.generateLocalFileURL(remoteURL: self.url)

        DownloadManager.downloadFileAndSaveIfNotHTML(url: url, to: destinationUrl, completion: {(finalLocalURL, errorMessage) in

            Logger.log("CheckingProcess", "startCheck callback block", "url: \(self.url.absoluteString), FinalLocalURL: \(String(describing: finalLocalURL)), errorMessage: \(String(describing: errorMessage))")
            self.filePath = finalLocalURL
            self.errorMessage = errorMessage

            self.status = CheckingStatus.finished

            self.webView?.loadRequest(NSURLRequest(url: self.url as URL) as URLRequest)
        })
    }

    func clearResults(){
        self.status = CheckingStatus.inactive
        self.filePath = nil
        self.errorMessage = nil
    }

    public var description: String {

        return "URL: \(self.url), Status: \(self.status), filePath: \(String(describing: self.filePath)), errorMessage: \(String(describing: self.errorMessage))"
    }

}

享受!