Swift 3.0:使用 URLSessionDownloadDelegate 完成下载后如何在不同的视图控制器中打开 PDF
Posted
技术标签:
【中文标题】Swift 3.0:使用 URLSessionDownloadDelegate 完成下载后如何在不同的视图控制器中打开 PDF【英文标题】:Swift 3.0: How to open a PDF in a different view controller when finished downloading using URLSessionDownloadDelegate 【发布时间】:2016-12-14 19:30:41 【问题描述】:在我正在编写的应用程序中,我需要从服务器下载 PDF 并将其显示在 UIWebView 中。为此,我有一些代码可以从端点检索 PDF(它不是 URL,在台式计算机上,打开一个对话框以在浏览器中保存)并通过抓取将其加载到设备上名为 PDFGrabber 的类中的数据:
func getPDF(completionHandler:@escaping (URL) -> Void)
let theURL:String = "https://mywebsite.com/Endpoint"
let fileURL:URL = URL(string: theURL)!
var request = URLRequest(url: fileURL, cachePolicy: .useProtocolCachePolicy, timeoutInterval: 10.0)
let session = URLSession.shared
let task = session.dataTask(with: request, completionHandler: data, response, error -> Void in
var documentURL = (FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)).last
documentURL = documentURL?.appendingPathComponent("MyDocument.pdf")
do
try data?.write(to: documentURL!, options: .atomic)
completionHandler(documentURL!)
catch
print(error)
)
task.resume()
然后,在显示 PDF 的表格视图控制器中(我们称之为 PDFTableView,当请求 PDF 时(通过点击表格中的单元格),我可以使用 PDFGrabber 中的 documentURL:
PDFGrabber.getPDF()fileURL -> () in
DispatchQueue.main.async
if let resultController = self.storyboard!.instantiateViewController(withIdentifier: "PDFViewer") as? PDFViewer
resultController.thePDFPath = stringURL
self.present(resultController, animated: true, completion: nil)
最后,我在 PDFViewer 视图控制器中有另一个带有 UIWebView 的视图控制器,名为“WebView”,属性“thePDFPath”作为字符串。在 viewDidLoad() 方法中,我可以说:
override func viewDidLoad()
let pathToPDF:URL = URL(string: thePDFPath)!
WebView.loadRequest(URLRequest(url: pathToPDF))
这会将 PDF 加载到 Web 视图中。但是,加载时间可能有点慢,我希望能够使用进度条和字符串计算有多少 PDF 已加载到用户的设备上。从其他问题中,我收集到我需要让我的 PDFGrabber 类扩展 URLSessionDownloadDelegate,然后实现这些功能。获取下载的字节数很简单,因为我可以简单地去:
func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didWriteData bytesWritten: Int64, totalBytesWritten writ: Int64, totalBytesExpectedToWrite exp: Int64)
percentDownloaded = (Float(writ)/Float(exp)) * 100
print("Progress: " + String(describing: percentDownloaded))
但我也希望仅在 PDF 以百分比显示进度后完全下载后才能打开 PDFView(我有一个覆盖视图)。之前,我可以使用完成处理程序并等待 PDF 完成下载,然后再打开它。
但是,这种方法不允许我访问下载的字节数;我可以从
中打开视图吗urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL)
功能,或者我还有什么需要做的吗?
非常感谢您的建议;谢谢!
【问题讨论】:
【参考方案1】:导入 WebKit
您可以在此处将 pdf 加载到您的应用程序中
override func viewDidLoad()
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
if let pdfURL = Bundle.main.url(forResource: "food-and-drink-menu-trafalgar-tavern", withExtension: "pdf", subdirectory: nil, localization: nil)
do
let data = try Data(contentsOf: pdfURL)
let webView = WKWebView(frame: CGRect(x:0,y:NavigationView.frame.size.height,width:view.frame.size.width, height:view.frame.size.height-NavigationView.frame.size.height))
webView.load(data, mimeType: "application/pdf", characterEncodingName:"", baseURL: pdfURL.deletingLastPathComponent())
view.addSubview(webView)
catch
// catch errors here
【讨论】:
以上是关于Swift 3.0:使用 URLSessionDownloadDelegate 完成下载后如何在不同的视图控制器中打开 PDF的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Swift 3.0 中使用 keysSortedByValue?