2017-08-09 59 views
0

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

我尝试使用以下功能:

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

在此功能中我得到的URL,以获得响应的content-type发送HEAD请求,如果它不包含text/html我下载并出现选项菜单。

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

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

我试图寻找所有在互联网上,但无法找到类似的话这个问题

+0

Swift 4&ObjC [answer here](https://stackoverflow.com/a/48072230/7576100) – Jack

回答

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))" 
    } 

} 

享受!

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 
    } 

希望这将帮助你。

+0

谢谢你的回答,但不,这不是我要找的。我期待知道网址的web视图试图加载,PDF,DOC,DOCX或只是一个HTML页面.. – Oday10

+1

类型UIDocumentInteractionController会帮助你 https://code.tutsplus.com/tutorials/ios-sdk -previewing-and-opening-documents - mobile-15130或者请查看https://stackoverflow.com/q/28279463/3515115 –

+0

谢谢。这些解决方案并不完美,而且它们不是很迅速。 – Oday10