最近在写聊天相关的项目,其中涉及到文档的打开,这里总结下文档的打开方式和遇到的坑。
一、WebView 打开文档
打开文档,首先想到的是万能的 WebView,啥也不说了,先上代码:
class DocumentViewController: UIViewController {
var filePath: String!
var fileType: String!
var fileData: Data!
override func viewDidLoad() {
super.viewDidLoad()
_init()
}
fileprivate lazy var webView: UIWebView = {
var webView = UIWebView(frame: .zero)
webView.delegate = self
webView.backgroundColor = .white
webView.scrollView.isDirectionalLockEnabled = true
webView.scrollView.showsHorizontalScrollIndicator = false
return webView
}()
private var fileUrl: URL?
private func _init() {
view.addSubview(webView)
let url = URL(fileURLWithPath: filePath)
let fileName = url.lastPathComponent
let path = "\(NSHomeDirectory())/tmp/" + fileName + "." + fileType
if FileManager.saveFileToLocal(data: fileData, savaPath: path) {
fileUrl = URL(fileURLWithPath: path)
do {
let string = try String(contentsOf: fileUrl!, encoding: .utf8)
webView.loadHTMLString(string, baseURL: nil)
} catch {
let request = URLRequest(url: fileUrl!)
webView.loadRequest(request)
}
}
}
}
extension DocumentViewController: UIWebViewDelegate {
func webViewDidFinishLoad(_ webView: UIWebView) {
print("webViewDidFinishLoad")
}
func webView(_ webView: UIWebView, didFailLoadWithError error: Error) {
print(error.localizedDescription)
}
}
看上面的代码,肯定会觉得有点奇葩,为什么这么说呢,因为上面明明给出文件的路径了,但为什么还要把该文档再转存到 tmp 目录下呢,这里是因为 WebView 里面有个坑,如果文件没有后缀,它打开时就会报错,错误如下:
Error Domain=WebKitErrorDomain Code=102 "帧框加载已中断" UserInfo={NSErrorFailingURLStringKey
这个什么 "帧框加载已中断" 的错误提示我也是醉了,完全不知道是啥意思,后来查了好久,才发现原来文档后面得加后缀,要不 WebView 识别不出来。其实不单单 WebView,像 AVPlay 等,传的路径也必须要指明后缀,否则也会打开失败的。
二、UIDocumentInteractionController 打开文档
UIDocumentInteractionController 其实就是选择设备内的其实软件来打开,用法很简单,直接上代码说好:
class DocumentViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
private lazy var documentInteractionController = UIDocumentInteractionController()
func _openFile() {
guard let url = fileUrl else {
return
}
documentInteractionController.url = url
documentInteractionController.delegate = self
documentInteractionController.presentOptionsMenu(from: .zero, in: self.view, animated: true)
}
}
extension DocumentViewController: UIDocumentInteractionControllerDelegate {
func documentInteractionControllerViewControllerForPreview(_ controller: UIDocumentInteractionController) -> UIViewController {
return self
}
func documentInteractionControllerViewForPreview(_ controller: UIDocumentInteractionController) -> UIView? {
return self.view
}
func documentInteractionControllerRectForPreview(_ controller: UIDocumentInteractionController) -> CGRect {
return self.view.frame
}
}
小结
"帧框加载已中断" 这个错误我 google 好久都没有发现正确的答案,后来才在一个相关的问题中找到了需要添加后缀的关键字,所以在这里记录下。
网友评论