如何在 UIDocumentInteractionController 中打开内存不足的文件?
How can I open a file out of memory in a UIDocumentInteractionController?
我们不允许永久存储文件,但允许客户自行决定是否要将其保存在其他 app/send 某处。听起来像是 UIDocumentInteractionController
的工作,但没有持久性部分。
Apple 在文档中指出:
"[…]you can use a document interaction controller with a file that was
synced to your app’s Documents/Shared directory."
是否可以直接打开文件而不将其作为文件存储在 UIDocumentInteractionController
中?
我们已经将 PDF/图像作为数据。有没有办法将数据编码为 URL 并使用它来打开交互控制器?
这个不行,只能分享本地资源。
您可以做的是将文件保存在临时文件夹中并访问它。以下是如何实现此目的的代码。查看说明的评论:
import UIKit
class ViewController: UIViewController {
let sharingController = UIDocumentInteractionController()
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
if let pdfURL = Bundle.main.url(forResource: "yourPDF", withExtension: "pdf") {
do {
let pdfData = try Data(contentsOf: pdfURL)
// create a destination url to save your pdf data
let destURL = FileManager.default.temporaryDirectory.appendingPathComponent("tempFile.pdf")
// write your pdf data to the destinastion url
do {
try pdfData.write(to: destURL)
// share your url using UIDocumentInteractionController
shareURL(url: destURL)
} catch {
print(error)
}
} catch {
print(error)
}
}
}
func shareURL(url: URL){
sharingController.url = url
sharingController.uti = "public.data, public.content"
sharingController.name = url.lastPathComponent
sharingController.presentOptionsMenu(from: view.frame, in: view, animated: true)
}
}
也没有必要删除该文件,因为它位于临时目录中。
尝试使用,
import UIKit
import QuickLook
class YourViewController:UIViewController,QLPreviewControllerDataSource, QLPreviewControllerDelegate {
func openFile(){
let objURL = "file URL "
let path = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] as String
let url = URL(fileURLWithPath: path)
let theFileName = (objURL as NSString).lastPathComponent
let filePath = url.appendingPathComponent("\(theFileName)").path
let fileManager = FileManager.default
if fileManager.fileExists(atPath: filePath) {
print("FILE AVAILABLE")
self.pathString = filePath
let viewPDF = QLPreviewController()
viewPDF.dataSource = self
viewPDF.delegate = self
self.item.previewItemTitle = self.previewFileTitle
self.item.previewItemURL = URL.init(fileURLWithPath: filePath)
self.present(viewPDF, animated: true, completion: nil)
} else {
print("FILE NOT AVAILABLE")
previewFileTitle = theFileName
self.downloadPDF(objURL)
}
}
func numberOfPreviewItems(in controller: QLPreviewController) -> Int {
return 1
}
func previewController(_ controller: QLPreviewController, previewItemAt index: Int) -> QLPreviewItem {
let url = URL(fileURLWithPath: pathString)
return item as QLPreviewItem
}
func previewController(_ controller: QLPreviewController, shouldOpen url: URL, for item: QLPreviewItem) -> Bool {
return true
}
func downloadPDF(_ url:String){
let requestURL: URL = URL(string: url)!
let urlRequest: URLRequest = URLRequest(url: requestURL)
let task = URLSession.shared.dataTask(with: urlRequest) { (data, response, error) in
if let httpResponse = response as? HTTPURLResponse {
let statusCode = httpResponse.statusCode
if (statusCode == 200) {
print("Downloaded Successfully")
let documentsDirectoryUrl = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first
let sourceUrl = URL(string:url)!
//Get the file name and create a destination URL
let fileName = sourceUrl.lastPathComponent
let destinationURL = documentsDirectoryUrl!.appendingPathComponent(fileName)
//Hold this file as an NSData and write it to the new location
if let fileData = try? Data(contentsOf: sourceUrl) {
try? fileData.write(to: destinationURL, options: []) // true
print(destinationURL.path)
self.pathString = destinationURL.path
let viewPDF = QLPreviewController()
viewPDF.dataSource = self
viewPDF.delegate = self
self.item.previewItemTitle = self.previewFileTitle
self.item.previewItemURL = destinationURL
self.present(viewPDF, animated: true, completion: nil)
}
}else{
}
}
}
task.resume()
}
}
class PreviewItem: NSObject, QLPreviewItem {
var previewItemURL: URL?
var previewItemTitle: String?
}
我们不允许永久存储文件,但允许客户自行决定是否要将其保存在其他 app/send 某处。听起来像是 UIDocumentInteractionController
的工作,但没有持久性部分。
Apple 在文档中指出:
"[…]you can use a document interaction controller with a file that was synced to your app’s Documents/Shared directory."
是否可以直接打开文件而不将其作为文件存储在 UIDocumentInteractionController
中?
我们已经将 PDF/图像作为数据。有没有办法将数据编码为 URL 并使用它来打开交互控制器?
这个不行,只能分享本地资源。
您可以做的是将文件保存在临时文件夹中并访问它。以下是如何实现此目的的代码。查看说明的评论:
import UIKit
class ViewController: UIViewController {
let sharingController = UIDocumentInteractionController()
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
if let pdfURL = Bundle.main.url(forResource: "yourPDF", withExtension: "pdf") {
do {
let pdfData = try Data(contentsOf: pdfURL)
// create a destination url to save your pdf data
let destURL = FileManager.default.temporaryDirectory.appendingPathComponent("tempFile.pdf")
// write your pdf data to the destinastion url
do {
try pdfData.write(to: destURL)
// share your url using UIDocumentInteractionController
shareURL(url: destURL)
} catch {
print(error)
}
} catch {
print(error)
}
}
}
func shareURL(url: URL){
sharingController.url = url
sharingController.uti = "public.data, public.content"
sharingController.name = url.lastPathComponent
sharingController.presentOptionsMenu(from: view.frame, in: view, animated: true)
}
}
也没有必要删除该文件,因为它位于临时目录中。
尝试使用,
import UIKit
import QuickLook
class YourViewController:UIViewController,QLPreviewControllerDataSource, QLPreviewControllerDelegate {
func openFile(){
let objURL = "file URL "
let path = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] as String
let url = URL(fileURLWithPath: path)
let theFileName = (objURL as NSString).lastPathComponent
let filePath = url.appendingPathComponent("\(theFileName)").path
let fileManager = FileManager.default
if fileManager.fileExists(atPath: filePath) {
print("FILE AVAILABLE")
self.pathString = filePath
let viewPDF = QLPreviewController()
viewPDF.dataSource = self
viewPDF.delegate = self
self.item.previewItemTitle = self.previewFileTitle
self.item.previewItemURL = URL.init(fileURLWithPath: filePath)
self.present(viewPDF, animated: true, completion: nil)
} else {
print("FILE NOT AVAILABLE")
previewFileTitle = theFileName
self.downloadPDF(objURL)
}
}
func numberOfPreviewItems(in controller: QLPreviewController) -> Int {
return 1
}
func previewController(_ controller: QLPreviewController, previewItemAt index: Int) -> QLPreviewItem {
let url = URL(fileURLWithPath: pathString)
return item as QLPreviewItem
}
func previewController(_ controller: QLPreviewController, shouldOpen url: URL, for item: QLPreviewItem) -> Bool {
return true
}
func downloadPDF(_ url:String){
let requestURL: URL = URL(string: url)!
let urlRequest: URLRequest = URLRequest(url: requestURL)
let task = URLSession.shared.dataTask(with: urlRequest) { (data, response, error) in
if let httpResponse = response as? HTTPURLResponse {
let statusCode = httpResponse.statusCode
if (statusCode == 200) {
print("Downloaded Successfully")
let documentsDirectoryUrl = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first
let sourceUrl = URL(string:url)!
//Get the file name and create a destination URL
let fileName = sourceUrl.lastPathComponent
let destinationURL = documentsDirectoryUrl!.appendingPathComponent(fileName)
//Hold this file as an NSData and write it to the new location
if let fileData = try? Data(contentsOf: sourceUrl) {
try? fileData.write(to: destinationURL, options: []) // true
print(destinationURL.path)
self.pathString = destinationURL.path
let viewPDF = QLPreviewController()
viewPDF.dataSource = self
viewPDF.delegate = self
self.item.previewItemTitle = self.previewFileTitle
self.item.previewItemURL = destinationURL
self.present(viewPDF, animated: true, completion: nil)
}
}else{
}
}
}
task.resume()
}
}
class PreviewItem: NSObject, QLPreviewItem {
var previewItemURL: URL?
var previewItemTitle: String?
}