我想知道如何在iOS中使用turbolinks-ios框架打开链接的pdf文件。
目前,我遇到issue当turbolinks页面链接到pdf或其他文件时,该链接将在safari而不是嵌入视图中打开。
turbolinks-5库与turbolinks-ios framework一起提供了一种将Web应用程序连接到相应移动应用程序的本机导航控制器的方法。
屏幕截图取自turbolinks README。
当点击引用pdf的链接时,应将seaparate视图控制器推送到当前导航控制器,以便用户可以阅读pdf并轻松导航回文档索引。
链接的pdf在safari中打开,而不是在app中打开。不幸的是,safari再次请求身份验证。此外,用户必须离开该应用程序。
答案 0 :(得分:3)
对于pdf文件的链接,不会为会话委托触发didProposeVisitToURL
mechanism。因此,无法从那里决定如何处理链接的pdf。
相反,可以通过成为turbolinks的网络视图导航委托shown in the README来拦截点击链接:
extension NavigationController: SessionDelegate {
// ...
func sessionDidLoadWebView(session: Session) {
session.webView.navigationDelegate = self
}
}
extension NavigationController: WKNavigationDelegate {
func webView(webView: WKWebView,
decidePolicyForNavigationAction navigationAction: WKNavigationAction,
decisionHandler: (WKNavigationActionPolicy) -> ()) {
// This method is called whenever the webView within the
// visitableView attempts a navigation action. By default, the
// navigation has to be cancelled, since when clicking a
// turbolinks link, the content is shown in a **new**
// visitableView.
//
// But there are exceptions: When clicking on a PDF, which
// is not handled by turbolinks, we have to handle showing
// the pdf manually.
//
// We can't just allow the navigation since this would not
// create a new visitable controller, i.e. there would be
// no back button to the documents index. Therefore, we have
// to create a new view controller manually.
let url = navigationAction.request.URL!
if url.pathExtension == "pdf" {
presentPdfViewController(url)
}
decisionHandler(WKNavigationActionPolicy.Cancel)
}
}
与将可访问视图显示为shown in the turbolinks-ios demo application类似,提供pdf视图控制器:
extension NavigationController {
func presentPdfViewController(url: NSURL) {
let pdfViewController = PdfViewController(URL: url)
pushViewController(pdfViewController, animated: true)
}
}
或者,如果您还要显示其他文件类型,请将其命名为fileViewController
而不是pdfViewController
。
新的视图控制器继承了turbolinks'VisitableViewController,以便通过url使用初始化。
class PdfViewController: FileViewController {
}
class FileViewController: Turbolinks.VisitableViewController {
lazy var fileView: WKWebView = {
return WKWebView(frame: CGRectZero)
}()
lazy var filename: String? = {
return self.visitableURL?.pathComponents?.last
}()
override func viewDidLoad() {
view.addSubview(fileView)
fileView.bindFrameToSuperviewBounds() // https://stackoverflow.com/a/32824659/2066546
self.title = filename // https://stackoverflow.com/a/39022302/2066546
fileView.loadRequest(NSURLRequest(URL: visitableURL))
}
}
为了使网页视图的大小正确,我使用了bindFrameToSuperviewBounds
as shown in this stackoverflow answer,但我确定还有其他方法。
如果加载pdf需要身份验证,则可以方便地将cookies与turbolinks-ios webview共享为described in the README。
例如,创建一个webViewConfiguration
,可以将其传递给pdfViewController
:
extension NavigationController {
let webViewProcessPool = WKProcessPool()
lazy var webViewConfiguration: WKWebViewConfiguration = {
let configuration = WKWebViewConfiguration()
configuration.processPool = self.webViewProcessPool
// ...
return configuration
}()
lazy var session: Session = {
let session = Session(webViewConfiguration: self.webViewConfiguration)
session.delegate = self
return session
}()
}
需要将webViewConfiguration
传递给session
(如上所示)以及新的pdf视图控制器。
extension NavigationController {
func presentPdfViewController(url: NSURL) {
let pdfViewController = PdfViewController(URL: url)
pdfViewController.webViewConfiguration = self.webViewConfiguration
pushViewController(pdfViewController, animated: true)
}
}
class FileViewController: Turbolinks.VisitableViewController {
var webViewConfiguration: WKWebViewConfiguration
lazy var fileView: WKWebView = {
return WKWebView(frame: CGRectZero, configuration: self.webViewConfiguration)
}()
// ...
}