在 iOS 中使用 Swift 保存 PDF 文件并显示它们

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/29479812/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 05:31:33  来源:igfitidea点击:

Saving PDF Files with Swift in iOS and display them

iosswiftpdf

提问by MkaysWork

I want to build an app which also includes the possibility to show and save PDFsinside the app and display them (as a FileSystem) within a tableview and open them when I tap on one PDF.

我想构建一个应用程序,其中还包括在应用程序中显示和保存 PDF并在表格视图中显示它们(作为文件系统)并在我点击一个 PDF 时打开它们的可能性。

Here are my important questions for that:

以下是我的重要问题:

1. How do I save a PDF local on my app ( for example if the user can enter a url) and where exactly will it save it ?

1. 如何在我的应用程序上本地保存 PDF(例如,如果用户可以输入一个 url)以及它究竟将保存在哪里?

2. When saved, how can I show all the local storaged files within a tableview to open them?

2.保存后,如何在tableview中显示所有本地存储的文件以打开它们?

回答by Satre

Since several people requested this, here is the equivalent to the first answer in Swift:

由于有几个人要求这样做,这里相当于 Swift 中的第一个答案:

//The URL to Save
let yourURL = NSURL(string: "http://somewebsite.com/somefile.pdf")
//Create a URL request
let urlRequest = NSURLRequest(URL: yourURL!)
//get the data
let theData = NSURLConnection.sendSynchronousRequest(urlRequest, returningResponse: nil, error: nil)

//Get the local docs directory and append your local filename.
var docURL = (NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)).last as? NSURL

docURL = docURL?.URLByAppendingPathComponent( "myFileName.pdf")

//Lastly, write your file to the disk.
theData?.writeToURL(docURL!, atomically: true)

Also, since this code uses a synchronous network request, I highly recommend dispatching it to a background queue:

此外,由于此代码使用同步网络请求,我强烈建议将其分派到后台队列:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), { () -> Void in
    //The URL to Save
    let yourURL = NSURL(string: "http://somewebsite.com/somefile.pdf")
    //Create a URL request
    let urlRequest = NSURLRequest(URL: yourURL!)
    //get the data
    let theData = NSURLConnection.sendSynchronousRequest(urlRequest, returningResponse: nil, error: nil)

    //Get the local docs directory and append your local filename.
    var docURL = (NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)).last as? NSURL

    docURL = docURL?.URLByAppendingPathComponent( "myFileName.pdf")

    //Lastly, write your file to the disk.
    theData?.writeToURL(docURL!, atomically: true)
})

And the answer to second question in Swift:

以及 Swift 中第二个问题的答案:

//Getting a list of the docs directory
let docURL = (NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask).last) as? NSURL

//put the contents in an array.
var contents = (NSFileManager.defaultManager().contentsOfDirectoryAtURL(docURL!, includingPropertiesForKeys: nil, options: NSDirectoryEnumerationOptions.SkipsHiddenFiles, error: nil))
//print the file listing to the console
println(contents)

回答by Alfi

Swift 4.1

斯威夫特 4.1

 func savePdf(urlString:String, fileName:String) {
        DispatchQueue.main.async {
            let url = URL(string: urlString)
            let pdfData = try? Data.init(contentsOf: url!)
            let resourceDocPath = (FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)).last! as URL
            let pdfNameFromUrl = "YourAppName-\(fileName).pdf"
            let actualPath = resourceDocPath.appendingPathComponent(pdfNameFromUrl)
            do {
                try pdfData?.write(to: actualPath, options: .atomic)
                print("pdf successfully saved!")
            } catch {
                print("Pdf could not be saved")
            }
        }
    }

    func showSavedPdf(url:String, fileName:String) {
        if #available(iOS 10.0, *) {
            do {
                let docURL = try FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false)
                let contents = try FileManager.default.contentsOfDirectory(at: docURL, includingPropertiesForKeys: [.fileResourceTypeKey], options: .skipsHiddenFiles)
                for url in contents {
                    if url.description.contains("\(fileName).pdf") {
                       // its your file! do what you want with it!

                }
            }
        } catch {
            print("could not locate pdf file !!!!!!!")
        }
    }
}

// check to avoid saving a file multiple times
func pdfFileAlreadySaved(url:String, fileName:String)-> Bool {
    var status = false
    if #available(iOS 10.0, *) {
        do {
            let docURL = try FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false)
            let contents = try FileManager.default.contentsOfDirectory(at: docURL, includingPropertiesForKeys: [.fileResourceTypeKey], options: .skipsHiddenFiles)
            for url in contents {
                if url.description.contains("YourAppName-\(fileName).pdf") {
                    status = true
                }
            }
        } catch {
            print("could not locate pdf file !!!!!!!")
        }
    }
    return status
}

回答by casillas

I am giving an example of storing and retrieving a pdf document in iOS. I hope that is what you are looking for.

我举了一个在 iOS 中存储和检索 pdf 文档的例子。我希望这就是你正在寻找的。

1. How do I save a PDF local on my app ( for example if the user can enter a url) and where exactly will it save it ?

1. 如何在我的应用程序上本地保存 PDF(例如,如果用户可以输入一个 url)以及它究竟将保存在哪里?

// the URL to save
NSURL *yourURL = [NSURL URLWithString:@"http://yourdomain.com/yourfile.pdf"];
// turn it into a request and use NSData to load its content
NSURLRequest *request = [NSURLRequest requestWithURL:result.link];
NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];

// find Documents directory and append your local filename
NSURL *documentsURL = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
documentsURL = [documentsURL URLByAppendingPathComponent:@"localFile.pdf"];

// and finally save the file
[data writeToURL:documentsURL atomically:YES];

2. When saved, how can I show all the local storaged files within a tableview to open them?

2.保存后,如何在tableview中显示所有本地存储的文件以打开它们?

You can check that the file has downloaded, or you can list the Documents directory like so:

您可以检查文件是否已下载,或者您可以像这样列出 Documents 目录:

// list contents of Documents Directory just to check
NSURL *documentsURL = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];

NSArray *contents = [[NSFileManager defaultManager]contentsOfDirectoryAtURL:documentsURL includingPropertiesForKeys:nil options:NSDirectoryEnumerationSkipsHiddenFiles error:nil];

NSLog(@"%@", [contents description]);

回答by BIJU C

Downloading and displaying PDF in Webview using Swift.

使用 Swift 在 Webview 中下载和显示 PDF。

let request = URLRequest(url:  URL(string: "http://<your pdf url>")!)
        let config = URLSessionConfiguration.default
        let session =  URLSession(configuration: config)
        let task = session.dataTask(with: request, completionHandler: {(data, response, error) in
            if error == nil{
                if let pdfData = data {
                   let pathURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0].appendingPathComponent("\(filename).pdf")
                    do {
                        try pdfData.write(to: pathURL, options: .atomic)
                    }catch{
                        print("Error while writting")
                    }

                    DispatchQueue.main.async {
                        self.webView.delegate = self
                        self.webView.scalesPageToFit = true
                        self.webView.loadRequest(URLRequest(url: pathURL))
                    }
                }
            }else{
                print(error?.localizedDescription ?? "")
            }
        }); task.resume()

回答by Gev

If you want to store file in Filesapp add`

如果您想在Files应用程序中存储文件,请添加`

NSURL *url = [NSURL URLWithString:@"PATH TO PDF"];
UIDocumentPickerViewController *documentPicker = [[UIDocumentPickerViewController alloc] initWithURL:url inMode:UIDocumentPickerModeExportToService];
[documentPicker setDelegate:self];
[self presentViewController:documentPicker animated:YES completion:nil];

And here are delegate methods

这是委托方法

- (void)documentPickerWasCancelled:(UIDocumentPickerViewController *)controller {
}

- (void)documentPicker:(UIDocumentPickerViewController *)controller didPickDocumentsAtURLs:(NSArray<NSURL *> *)urls {

}

It will open a DocumentPickerViewController where you can choose a folder to store the file.

它将打开一个 DocumentPickerViewController,您可以在其中选择一个文件夹来存储文件。

Requires iOS11 or later.

需要 iOS11 或更高版本。

回答by Bruno Camargos

        //savePdf(urlString:url, fileName:fileName)
        let urlString = "here String with your URL"
        let url = URL(string: urlString)
        let fileName = String((url!.lastPathComponent)) as NSString
        // Create destination URL
        let documentsUrl:URL =  FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first as URL!
        let destinationFileUrl = documentsUrl.appendingPathComponent("\(fileName)")
        //Create URL to the source file you want to download
        let fileURL = URL(string: urlString)
        let sessionConfig = URLSessionConfiguration.default
        let session = URLSession(configuration: sessionConfig)
        let request = URLRequest(url:fileURL!)
        let task = session.downloadTask(with: request) { (tempLocalUrl, response, error) in
            if let tempLocalUrl = tempLocalUrl, error == nil {
                // Success
                if let statusCode = (response as? HTTPURLResponse)?.statusCode {
                    print("Successfully downloaded. Status code: \(statusCode)")
                }
                do {
                    try FileManager.default.copyItem(at: tempLocalUrl, to: destinationFileUrl)
                    do {
                        //Show UIActivityViewController to save the downloaded file
                        let contents  = try FileManager.default.contentsOfDirectory(at: documentsUrl, includingPropertiesForKeys: nil, options: .skipsHiddenFiles)
                        for indexx in 0..<contents.count {
                            if contents[indexx].lastPathComponent == destinationFileUrl.lastPathComponent {
                                let activityViewController = UIActivityViewController(activityItems: [contents[indexx]], applicationActivities: nil)
                                self.present(activityViewController, animated: true, completion: nil)
                            }
                        }
                    }
                    catch (let err) {
                        print("error: \(err)")
                    }
                } catch (let writeError) {
                    print("Error creating a file \(destinationFileUrl) : \(writeError)")
                }
            } else {
                print("Error took place while downloading a file. Error description: \(error?.localizedDescription ?? "")")
            }
        }
        task.resume()
    }

回答by Osman

if you want to print the PDF data wich is in the directoryURL then use :

如果要打印 directoryURL 中的 PDF 数据,请使用:

let printInfo = NSPrintInfo.shared
        let manager = FileManager.default
        do{
            let directoryURL = try manager.url(for: .documentDirectory, in:.userDomainMask, appropriateFor:nil, create:true)
            let docURL = NSURL(string:"LadetagMahlzeiten.pdf", relativeTo:directoryURL)

            let pdfDoc =  PDFDocument.init(url: docURL! as URL)

            let page = CGRect(x: 0, y: 0, width: 595.2, height: 1841.8) // A4, 72 dpi

            let pdfView : PDFView = PDFView.init(frame: page)

            pdfView.document = pdfDoc

            let operation: NSPrintOperation = NSPrintOperation(view: pdfView, printInfo: printInfo)
            operation.printPanel.options.insert(NSPrintPanel.Options.showsPaperSize)
            operation.printPanel.options.insert(NSPrintPanel.Options.showsOrientation)

            operation.run()
        }catch{

        }