在WKWebView中加载Microsoft Office文档 [英] Loading Microsoft Office documents in WKWebView

查看:1801
本文介绍了在WKWebView中加载Microsoft Office文档的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

一段时间以来,我一直在使用UIWebView在应用程序中显示Microsoft Office文档(Word,PowerPoint,Excel),但是Apple最近不赞成使用UIWebView类.我正在尝试切换到WKWebView,但是Word,Excel和Powerpoint文档无法在WKWebView中正确呈现.

I have been using UIWebView to display Microsoft Office documents (Word, PowerPoint, Excel) in my application for a while but Apple has recently deprecated the UIWebView class. I am trying to switch to WKWebView but Word, Excel, and Powerpoint documents are not rendering properly in WKWebView.

使用UIWebView显示Excel文档(效果很好):

Using UIWebView to display an Excel document (worked great):

let data: Data
//data is assigned bytes of Excel file
let webView = UIWebView()
webView.load(data, mimeType: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", textEncodingName: "UTF-8", baseURL: Bundle.main.bundleURL)

尝试使用WKWebView做同样的事情(显示一堆废话而不是Excel文件):

Attempting to use WKWebView to do the same thing (displays a bunch of nonsense characters instead of the Excel file):

let data: Data
//data is assigned bytes of Excel file
let webView = WKWebView.init()
webView.load(data, mimeType: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", characterEncodingName: "UTF-8", baseURL: Bundle.main.bundleURL)

由于用例的性质,出于安全原因,我无法将数据保存到磁盘,因此无法使用以下方法:

Due to the nature of my use case, I cannot save the data to disk for security reasons so I cannot use methods like this:

webView.loadFileURL(<#T##URL: URL##URL#>, allowingReadAccessTo: <#T##URL#>)

我也不能使用QuickLook(QLPreviewController),因为它再次需要一个URL.

I also cannot use QuickLook (QLPreviewController) because it again requires a URL.

--------------------------------------------------- - - - - - - - - 编辑 - - - - - - - - - - - - - - - - - ------------------------

---------------------------------------------------------------EDIT---------------------------------------------------------

我也知道这种通过字符串URL传递数据的方法,但是除非有人能证明数据从未写入磁盘,否则我不能接受它作为答案:

I am also aware of this method of passing the data in via a string URL but unless someone can prove that the data is never written to disk, I cannot accept it as an answer:

let data: Data
//data is assigned bytes of Excel file
let webView = WKWebView.init()
let urlStr = "data:\(fileTypeInfo.mimeType);base64," + data.base64EncodedString()
let url = URL(string: urlStr)!
let request = URLRequest(url: url)
webView.load(request)

推荐答案

这就像WKWebView.load(_ data:Data,mimeType MIMEType:String,characterEncodingName:String,baseURL:URL)-> WKNavigation中的错误.它应该以我们尝试使用它的方式工作,但以下是我们解决该问题的方法:

This feels like a bug in WKWebView.load(_ data: Data, mimeType MIMEType: String, characterEncodingName: String, baseURL: URL) -> WKNavigation?. It should work in the way we were trying to use it but here is how we got around the issue:

声明您的WKWebView和自定义方案名称

Declare your WKWebView and a custom scheme name

let webView: WKWebView
let customSchemeName = "custom-scheme-name"

创建WKURLSchemeHandler的子类.我们正在使用webView在webView的整个生命周期内显示单个文档(PDF,Word,PowerPoint或Excel),因此我们将该文档作为Data和FileTypeInfo传入,这是我们制作的自定义类,具有文件的MIME类型除其他外,在WKURLSchemeHandler的初始化中.

Create a subclass of WKURLSchemeHandler. We are using the webView to display a single document (PDF, Word, PowerPoint, or Excel) for the life of the webView so we pass in that document as Data and the FileTypeInfo which is a custom class we made that has the file's MIME type among other things, in the init of the WKURLSchemeHandler.

private class ExampleWKURLSchemeHandler: NSObject, WKURLSchemeHandler {

private let data: Data
private let fileTypeInfo: FileTypeInfo

init(data: Data, fileTypeInfo: FileTypeInfo) {
    self.data = data
    self.fileTypeInfo = fileTypeInfo
    super.init()
}

func webView(_ webView: WKWebView, start urlSchemeTask: WKURLSchemeTask) {
    if let url = urlSchemeTask.request.url, let scheme = url.scheme, scheme == customSchemeName {
        let response = URLResponse.init(url: url, mimeType: fileTypeInfo.mimeType, expectedContentLength: data.count, textEncodingName: nil)

        urlSchemeTask.didReceive(response)
        urlSchemeTask.didReceive(data)
        urlSchemeTask.didFinish()
    }
}

func webView(_ webView: WKWebView, stop urlSchemeTask: WKURLSchemeTask) {
    //any teardown code you may need
}

}

使用您刚创建的自定义方案处理程序类来实例化您的webView:

Instantiate your webView with the custom scheme handler class you just made:

let webViewConfiguration = WKWebViewConfiguration()
let webViewSchemeHandler = ExampleWKURLSchemeHandler.init(data: data, fileTypeInfo: fileTypeInfo)
webViewConfiguration.setURLSchemeHandler(webViewSchemeHandler, forURLScheme: customSchemeName)
self.webView = WKWebView.init(frame: .zero, configuration: webViewConfiguration)

告诉webView使用与您的自定义方案匹配的URL加载文档.您可以在customSchemeName前缀之后的url中传递所需的任何内容,但是对于我们的用例,我们不需要这样做,因为我们已经传递了要显示在WKSchemeHandler的初始化程序中的文档:

Tell the webView to load the document using a URL that matches your custom scheme. You can pass whatever you want in the url after the customSchemeName prefix but for our use case we didn't need to because we already passed the document that we wanted to display in the initializer of the WKSchemeHandler:

guard let url = URL.init(string: "\(customSchemeName):/123") else {
            fatalError()
        }
webView.load(URLRequest.init(url: url))

这篇关于在WKWebView中加载Microsoft Office文档的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆