PDF генерация в Swift (iOS/macOS): полное руководство
Создание PDF-документов — одна из ключевых задач при разработке приложений для iOS и macOS. Отчёты, счета, сертификаты, электронные книги — всё это требует надёжного и гибкого инструмента для генерации PDF. В экосистеме Swift существует несколько подходов: от встроенных фреймворков Apple до сторонних библиотек с расширенными возможностями. В этой статье мы разберём основные способы генерации PDF, их преимущества и недостатки, а также приведём рабочие примеры кода.
1. PDFKit — встроенный фреймворк Apple
PDFKit — это мощный фреймворк от Apple, доступный на iOS 11+ и macOS 10.13+. Он предоставляет высокоуровневый API для создания, отображения и редактирования PDF-документов. Основные возможности:
- Создание PDF из UIView, UIImage или текста
- Добавление аннотаций, форм и гиперссылок
- Работа с многостраничными документами
- Поддержка Core Graphics для кастомной отрисовки
Пример создания PDF из UIView:
import PDFKit
func generatePDF(from view: UIView) -> Data? {
let pdfData = NSMutableData()
UIGraphicsBeginPDFContextToData(pdfData, view.bounds, nil)
UIGraphicsBeginPDFPage()
guard let context = UIGraphicsGetCurrentContext() else { return nil }
view.layer.render(in: context)
UIGraphicsEndPDFContext()
return pdfData as Data
}
Этот метод подходит, если вам нужно быстро «сфотографировать» существующий интерфейс. Однако для сложной вёрстки (таблицы, колонтитулы, кастомные шрифты) лучше использовать Core Graphics напрямую.
2. Core Graphics (Quartz 2D) — низкоуровневое решение
Core Graphics даёт полный контроль над процессом отрисовки. Вы работаете с контекстом PDF, рисуете линии, текст, изображения, управляете страницами. Это наиболее гибкий, но и самый трудоёмкий способ.
Пример создания простого PDF с текстом:
import UIKit
func createPDFWithText() -> Data? {
let pageSize = CGRect(x: 0, y: 0, width: 612, height: 792) // A4
let data = NSMutableData()
UIGraphicsBeginPDFContextToData(data, pageSize, nil)
UIGraphicsBeginPDFPage()
guard let context = UIGraphicsGetCurrentContext() else { return nil }
let text = "Привет, мир PDF!"
let attributes: [NSAttributedString.Key: Any] = [
.font: UIFont.systemFont(ofSize: 24),
.foregroundColor: UIColor.black
]
text.draw(at: CGPoint(x: 50, y: 50), withAttributes: attributes)
UIGraphicsEndPDFContext()
return data as Data
}
Для сложных документов (таблицы, изображения, нумерация страниц) придётся писать много вспомогательного кода. Зато вы получаете максимальную производительность и минимальный размер файла.
3. TPPDF — сторонняя библиотека с открытым исходным кодом
TPPDF (GitHub: techprimate/TPPDF) — это Swift-библиотека для генерации PDF с декларативным синтаксисом. Она поддерживает:
- Текст, изображения, таблицы, списки
- Колонтитулы, нумерацию страниц
- Автоматический перенос контента между страницами
- Кастомные шрифты, цвета, границы
Установка через Swift Package Manager:
// Package.swift
dependencies: [
.package(url: "https://github.com/techprimate/TPPDF.git", from: "2.0.0")
]
Пример создания документа с таблицей:
import TPPDF
func generateInvoice() -> Data? {
let document = PDFDocument(format: .a4)
// Добавляем заголовок
document.add(text: "Счёт №123", style: PDFTextStyle.heading1)
// Создаём таблицу
let table = PDFTable(rows: 3, columns: 2)
table[0][0].content = "Товар"
table[0][1].content = "Цена"
table[1][0].content = "Ноутбук"
table[1][1].content = "1500$"
table[2][0].content = "Мышь"
table[2][1].content = "50$"
document.add(table: table)
// Экспортируем
let generator = PDFGenerator(document: document)
return try? generator.generateData()
}
TPPDF значительно упрощает вёрстку: не нужно вручную рассчитывать координаты. Библиотека сама распределяет контент по страницам и добавляет разрывы при необходимости.