Добрый день, представляю вашему вниманию перевод статьи о работе 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 в следующей статье.
Комментарии (3)
Adnako
26.11.2018 06:48Сохраненные файлы должны храниться в Documents.
Нет, не должны. Потому что это не “user-generated content”. Файлы, которые всегда можно скачать ещё раз лучше хранить в подкаталоге Library, который не синхронизируется в iCloud, а если файл нужен только один раз сразу же после скачивания — в tmp.
chuikoffru
Вот бы про работу с ePub побольше узнать. Но спасибо и за PDF.
kosyakus Автор
Если найду годный туториал, то можно сделать статью, почему бы и нет.