PDF генерация в Swift (iOS/macOS): обзор инструментов и примеры

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

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 значительно упрощает вёрстку: не нужно вручную рассчитывать координаты. Библиотека сама распределяет контент по страницам и добавляет разрывы при необходимости.

4. SwiftUI + PDF

Рекомендаций