Geração de PDF em Swift (iOS/macOS): do simples ao complexo
Criar documentos PDF é uma das tarefas comuns no desenvolvimento móvel e desktop. Nas plataformas Apple (iOS/macOS), as ferramentas integradas permitem gerar PDFs de qualidade sem bibliotecas de terceiros. Neste artigo, abordaremos três abordagens principais: UIGraphicsPDFRenderer (moderno e simples), PDFKit (para trabalhar com PDFs existentes) e Core Graphics (para controle total). Todos os exemplos são escritos em Swift e funcionam tanto para iOS quanto para macOS (com alterações mínimas).
1. UIGraphicsPDFRenderer — o padrão moderno
UIGraphicsPDFRenderer foi introduzido no iOS 10 e macOS 10.12. Ele fornece uma API de alto nível para criar PDFs com várias páginas. As principais vantagens: gerenciamento automático de contexto, suporte a metadados e facilidade de uso.
Exemplo básico: criar um PDF com texto
import UIKit
func generateSimplePDF() -> Data? { let pageWidth: CGFloat = 612 // A4 let pageHeight: CGFloat = 792 let renderer = UIGraphicsPDFRenderer(bounds: CGRect(x: 0, y: 0, width: pageWidth, height: pageHeight)) let data = renderer.pdfData { context in // Primeira página context.beginPage() let text = "Olá, mundo PDF!" let attributes: [NSAttributedString.Key: Any] = [ .font: UIFont.systemFont(ofSize: 24), .foregroundColor: UIColor.black ] text.draw(at: CGPoint(x: 50, y: 50), withAttributes: attributes) // Segunda página context.beginPage() let secondText = "Esta é a segunda página" secondText.draw(at: CGPoint(x: 50, y: 50), withAttributes: attributes) } return data}
// Salvar em arquivoif let pdfData = generateSimplePDF() { let documentsPath = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0] let pdfURL = documentsPath.appendingPathComponent("sample.pdf") try? pdfData.write(to: pdfURL) print("PDF salvo: \\(pdfURL)")}Exemplo avançado: tabela e imagem
func generateInvoicePDF() -> Data { let renderer = UIGraphicsPDFRenderer(bounds: CGRect(x: 0, y: 0, width: 612, height: 792)) return renderer.pdfData { context in context.beginPage() // Desenhar logotipo (se houver) if let logo = UIImage(named: "logo") { logo.draw(in: CGRect(x: 50, y: 50, width: 100, height: 50)) } // Título let titleAttributes: [NSAttributedString.Key: Any] = [ .font: UIFont.boldSystemFont(ofSize: 28), .foregroundColor: UIColor.darkGray ] "FATURA Nº123".draw(at: CGPoint(x: 400, y: 50), withAttributes: titleAttributes) // Tabela let items = [("Produto", "Preço"), ("Notebook", "1200$"), ("Mouse", "25$")] var yPosition: CGFloat = 200 for (name, price) in items { let nameAttributes: [NSAttributedString.Key: Any] = [ .font: UIFont.systemFont(ofSize: 14), .foregroundColor: UIColor.black ] name.draw(at: CGPoint(x: 100, y: yPosition), withAttributes: nameAttributes) price.draw(at: CGPoint(x: 400, y: yPosition), withAttributes: nameAttributes) yPosition += 30 } // Total let totalAttributes: [NSAttributedString.Key: Any] = [ .font: UIFont.boldSystemFont(ofSize: 18), .foregroundColor: UIColor.red ] "Total: 1225$".draw(at: CGPoint(x: 350, y: yPosition + 20), withAttributes: totalAttributes) }}2. PDFKit — trabalhando com PDFs existentes e anotações
PDFKit é um framework mais poderoso, que
Também na biblioteca
Migrações de banco de dados em TypeScript: TypeORM, Prisma e Drizzle
ErrorOr para C# (.NET): guia completo com exemplos práticos
Trabalhando com XML em JavaScript (Node.js): bibliotecas e exemplos