Primeiros Passos com o PDF Oxide (Objective-C)
O PDF Oxide oferece bindings idiomáticos de Objective-C sobre seu núcleo em Rust — média de 0,8 ms na extração de texto e 100% de aprovação em 3.830 PDFs. Os wrappers NSObject (POXDocument, POXPdf) são donos dos handles nativos e os liberam sob ARC, as strings retornadas chegam como NSString e qualquer código de erro da C-ABI aparece como um NSError no POXErrorDomain. Novidade na v0.3.69.
Instalação
O binding de Objective-C faz o link com o cdylib de features padrão e compila com clang sob ARC. Compile a biblioteca nativa e, em seguida, execute make build contra ela:
# 1. compile a biblioteca nativa (conjunto de features do binding distribuído)
cargo build --release --lib --features ocr,rendering,signatures,barcodes,tsa-client,system-fonts
# 2. compile o binding de Objective-C (clang, ARC)
cd objc
make build PDF_OXIDE_LIB_DIR="$PWD/../target/release"
DYLD_LIBRARY_PATH="$PWD/../target/release" ./basic_extraction
Importe o único header público nos seus arquivos-fonte:
#import "POXPdfOxide.h"
Início Rápido
Abra um PDF, inspecione seus metadados e extraia texto da primeira página. Toda chamada passível de falha recebe um NSError** no final.
#import "POXPdfOxide.h"
NSError *err = nil;
POXDocument *doc = [POXDocument openPath:@"research-paper.pdf" error:&err];
if (!doc) {
NSLog(@"open failed: %@", err.localizedDescription);
return;
}
NSInteger pages = [doc pageCountError:&err];
POXVersion ver = [doc version];
NSLog(@"pages: %ld version: %d.%d", (long)pages, ver.major, ver.minor);
NSString *text = [doc extractText:0 error:&err];
NSLog(@"%@", text);
Você também pode abrir a partir de bytes em memória — útil quando o PDF chega pela rede ou de um banco de dados — e abrir arquivos protegidos por senha:
POXDocument *doc = [POXDocument openFromBytes:pdfData error:&err];
// Documento criptografado, com a senha fornecida de antemão:
POXDocument *enc = [POXDocument openWithPassword:@"confidential.pdf"
password:@"secret"
error:&err];
// Ou autentique depois de abrir:
BOOL ok = [doc authenticate:@"secret" error:&err];
Extração de Texto
Texto puro é o caminho mais rápido. Extraia uma única página pelo seu índice começando em zero, ou puxe o documento inteiro de uma vez.
// Uma página
NSString *text = [doc extractText:0 error:&err];
// Documento inteiro, concatenado
NSString *all = [doc toPlainTextAllWithError:&err];
// Página por página
NSInteger count = [doc pageCountError:&err];
for (NSInteger i = 0; i < count; i++) {
NSLog(@"--- page %ld ---\n%@", (long)i, [doc extractText:i error:&err]);
}
Palavras e Linhas
extractWords: e extractTextLines: retornam arrays de objetos de elemento com bounding boxes e metadados de fonte, todos em pontos do espaço do usuário do PDF.
NSArray<POXWord *> *words = [doc extractWords:0 error:&err];
for (POXWord *w in words) {
POXBbox box = w.bbox;
NSLog(@"'%@' at (%.1f, %.1f) %.1fx%.1f font=%@ size=%.1f bold=%d",
w.text, box.x, box.y, box.width, box.height,
w.fontName, w.fontSize, w.bold);
}
NSArray<POXTextLine *> *lines = [doc extractTextLines:0 error:&err];
for (POXTextLine *line in lines) {
NSLog(@"%@ (%ld words)", line.text, (long)line.wordCount);
}
POXChar (de extractChars:) expõe a mesma estrutura na granularidade de caractere — character, bbox, fontName e fontSize.
Markdown e HTML
Converta uma página — ou o documento inteiro — para Markdown ou HTML.
// Página única
NSString *md = [doc toMarkdown:0 error:&err];
NSString *html = [doc toHtml:0 error:&err];
// Documento inteiro
NSString *mdAll = [doc toMarkdownAllWithError:&err];
NSString *htmlAll = [doc toHtmlAllWithError:&err];
Busca
Busque em uma única página com search:term:caseSensitive:error:, ou no documento inteiro com searchAll:caseSensitive:error:. Ambos retornam arrays de POXSearchResult contendo o texto correspondente, o índice da página e a bounding box.
NSArray<POXSearchResult *> *hits =
[doc searchAll:@"configuration" caseSensitive:NO error:&err];
for (POXSearchResult *r in hits) {
POXBbox b = r.bbox;
NSLog(@"page %ld: '%@' at (%.0f, %.0f)", (long)r.page, r.text, b.x, b.y);
}
// Variante de página única:
NSArray<POXSearchResult *> *pageHits =
[doc search:0 term:@"configuration" caseSensitive:NO error:&err];
Criando PDFs
O builder POXPdf produz PDFs a partir de Markdown, HTML ou texto puro. Salve em um caminho ou receba os bytes de volta como NSData.
POXPdf *pdf = [POXPdf fromMarkdown:@"# Hello World\n\nThis is a PDF.\n"
error:&err];
[pdf saveToPath:@"output.pdf" error:&err];
// Ou mantenha os bytes em memória
NSData *bytes = [pdf toBytesWithError:&err];
// Também existem construtores para HTML e texto puro
POXPdf *invoice = [POXPdf fromHtml:@"<h1>Invoice</h1><p>Amount: $42</p>"
error:&err];
POXPdf *notes = [POXPdf fromText:@"Plain text content." error:&err];
Faça o round-trip direto de um builder para um documento, pronto para extração:
POXPdf *pdf = [POXPdf fromMarkdown:@"# Report\n\nBody text.\n" error:&err];
POXDocument *doc = [POXDocument openFromBytes:[pdf toBytesWithError:&err]
error:&err];
NSLog(@"%@", [doc extractText:0 error:&err]);
Tratamento de Erros
Todo método passível de falha escreve no NSError** final e retorna nil / um valor sentinela em caso de falha. Os erros caem no POXErrorDomain.
NSError *err = nil;
POXDocument *doc = [POXDocument openPath:@"document.pdf" error:&err];
if (!doc) {
if ([err.domain isEqualToString:POXErrorDomain]) {
NSLog(@"PDF error: %@", err.localizedDescription);
}
return;
}
NSString *text = [doc extractText:0 error:&err];
if (!text) {
NSLog(@"extract failed: %@", err.localizedDescription);
}
Os handles se liberam sozinhos sob ARC, mas você pode liberar o handle nativo antecipadamente com -close (idempotente):
[doc close];
Próximos Passos
- Primeiros Passos com Rust — usando o PDF Oxide a partir de Rust
- Primeiros Passos com Python — usando o PDF Oxide a partir de Python
- Extração de Texto — opções e receitas detalhadas de extração
- Criação de PDF — criação avançada com a API do builder
- Edição — modificando PDFs existentes, anotações e campos de formulário