Добрый день, представляю вашему вниманию перевод статьи о работе PDF в Swift.
Всем заинтересовавшимся, добро пожаловать под кат.
Я работаю над приложением, которое должно уметь скачивать PDF файлы, сохранять их и открывать. Для этой задачи, нужно выполнить 3 шага:
Шаг 1. DownloadTask
Чтобы скачать файл через URL, надо использовать downloadTask. Так же надо отслеживать, куда переместились наши файлы, поэтому наблюдатель, которым в моём случае является ViewController, должен поддерживать URLSessionDownloadDelegate.
Для того, чтобы понять куда сохранился файл, достаточно просто распечатать в консоли Xcode вывод переменной location.
После того как я нажал кнопку “Скачать”, файл загрузился менее, чем за секунду и затем был убит системой. Такое поведение повторяется как на симуляторе, так и на реальном устройстве.

Шаг 2. File Management
Каждое приложение в iOS имеет свою собственную тестовую среду. Внутри неё выделяют 3 компонента, которые должен знать каждый iOS разработчик: Bundle Container, Data Container, и iCloud Container. В данной статье мы подробнее рассмотрим только Data Container, так как он нам будет нужен для нашей задачи – загрузки PDF файла.

С помощью Data container мы можем управлять сохраненными из интернета файлами. Ниже я перечислю важные свойства:
Отсюда следует, что нашим следующим шагом будет сохранение файла из tmp в Documents. Вот что я сделал:

Шаг 3. PDFView
Итак, мы переместили PDF файл, и теперь пользователь имеет доступ к нему. Давайте теперь разберемся как его открыть, используя PDFView, встроенный в PDFKit – удобный фреймворк от Apple, доступный с iOS 11.
Несмотря на то, что многие обучающие руководства по PDFKit используют storyboard для создания PDFView с помощью свойства UIView, через Xibs этого сделать нельзя. Поэтому я создам его через код.

Вуаля! Мы извлекли и открыли PDF файл. Я знаю, что формат книги немного не тот, именно поэтому мы рассмотрим подробнее PDFKit в следующей статье.
Всем заинтересовавшимся, добро пожаловать под кат.
Я работаю над приложением, которое должно уметь скачивать PDF файлы, сохранять их и открывать. Для этой задачи, нужно выполнить 3 шага:
- DownloadTask
- File Management
- PDFView
Шаг 1. DownloadTask
Чтобы скачать файл через URL, надо использовать downloadTask. Так же надо отслеживать, куда переместились наши файлы, поэтому наблюдатель, которым в моём случае является ViewController, должен поддерживать URLSessionDownloadDelegate.
import UIKit class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() } @IBAction func downloadButtonPressed(_ sender: Any) { guard let url = URL(string: "https://www.tutorialspoint.com/swift/swift_tutorial.pdf") else { return } let urlSession = URLSession(configuration: .default, delegate: self, delegateQueue: OperationQueue()) let downloadTask = urlSession.downloadTask(with: url) downloadTask.resume() } } extension ViewController: URLSessionDownloadDelegate { func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL) { print("downloadLocation:", location) } }
Для того, чтобы понять куда сохранился файл, достаточно просто распечатать в консоли Xcode вывод переменной location.
После того как я нажал кнопку “Скачать”, файл загрузился менее, чем за секунду и затем был убит системой. Такое поведение повторяется как на симуляторе, так и на реальном устройстве.

Шаг 2. File Management
Каждое приложение в iOS имеет свою собственную тестовую среду. Внутри неё выделяют 3 компонента, которые должен знать каждый iOS разработчик: Bundle Container, Data Container, и iCloud Container. В данной статье мы подробнее рассмотрим только Data Container, так как он нам будет нужен для нашей задачи – загрузки PDF файла.

С помощью Data container мы можем управлять сохраненными из интернета файлами. Ниже я перечислю важные свойства:
- Файлы внутри Library, а также tmp файлы будут автоматически удалены
- iTunes делает бэкап всех файлов, кроме Caches, tmp и файлов, обозначенных как .isExcludedFromBackup = true. В ходе App review, если Apple обнаружит в iTines сохраненные файлы, которые там не должны быть, скорее всего приложение будет отклонено.
- Сохраненные файлы должны храниться в Documents.
Отсюда следует, что нашим следующим шагом будет сохранение файла из tmp в Documents. Вот что я сделал:
- Скопировал название pdf файла
- Создал url в Documents
- Удалил файл с таким же названием чтобы избежать ошибки копирования: “CFNetworkDownload_mdrFNb.tmp” couldn’t be copied to “Documents” because an item with the same name already exists.
- Скопировал файл в Documents.
extension ViewController: URLSessionDownloadDelegate { func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL) { print("downloadLocation:", location) // create destination URL with the original pdf name guard let url = downloadTask.originalRequest?.url else { return } let documentsPath = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0] let destinationURL = documentsPath.appendingPathComponent(url.lastPathComponent) // delete original copy try? FileManager.default.removeItem(at: destinationURL) // copy from temp to Document do { try FileManager.default.copyItem(at: location, to: destinationURL) self.pdfURL = destinationURL } catch let error { print("Copy Error: \(error.localizedDescription)") } } }

Шаг 3. PDFView
Итак, мы переместили PDF файл, и теперь пользователь имеет доступ к нему. Давайте теперь разберемся как его открыть, используя PDFView, встроенный в PDFKit – удобный фреймворк от Apple, доступный с iOS 11.
Несмотря на то, что многие обучающие руководства по PDFKit используют storyboard для создания PDFView с помощью свойства UIView, через Xibs этого сделать нельзя. Поэтому я создам его через код.
@IBAction func openPDFButtonPressed(_ sender: Any) { let pdfViewController = PDFViewController() pdfViewController.pdfURL = self.pdfURL present(pdfViewController, animated: false, completion: nil) }
import UIKit import PDFKit class PDFViewController: UIViewController { var pdfView = PDFView() var pdfURL: URL! override func viewDidLoad() { super.viewDidLoad() view.addSubview(pdfView) if let document = PDFDocument(url: pdfURL) { pdfView.document = document } DispatchQueue.main.asyncAfter(deadline: .now()+3) { self.dismiss(animated: true, completion: nil) } } override func viewDidLayoutSubviews() { pdfView.frame = view.frame } }

Вуаля! Мы извлекли и открыли PDF файл. Я знаю, что формат книги немного не тот, именно поэтому мы рассмотрим подробнее PDFKit в следующей статье.
