A Swift package to extract text from images and PDFs using Apple's Vision framework.
This package provides both a command-line interface (CLI) for direct use and a core library (TextTractorCore) that can be easily integrated into larger macOS or iOS* GUI applications.
*Note: iOS compatibility is possible but the package is currently configured for macOS. See Package.swift.
- Extract text from various image formats (PNG, JPEG, etc.).
- Extract text from PDF documents (multi-page supported).
- Simple command-line interface.
- Lightweight, easy-to-integrate library for use in other Swift projects.
- macOS 13.0 or later.
- Swift 5.9 or later.
- Xcode 14 or later.
First, build the project from the root directory:
swift build -c releaseThe executable text-tractor will be located in .build/release/.
The CLI takes a single required argument: the path to the input file. It can either print the extracted text to the console or save it to a file.
Syntax:
.build/release/text-tractor <path-to-image-or-pdf> [options]Arguments:
inputPath: The path to the input image or PDF file.
Options:
-o, --output-path <path>: The path to save the output.txtfile. If omitted, text is printed to standard output.
Examples:
-
Extract text and print to console:
.build/release/text-tractor /path/to/my/image.png
-
Extract text and save to a file:
.build/release/text-tractor /path/to/my/document.pdf -o /path/to/output/extracted.txt
You can easily use TextTractorCore in your own Xcode project (e.g., a SwiftUI or AppKit app).
In Xcode, go to File > Add Packages... and enter the repository URL for this project.
https://github.com/inspirationull/texttractor
Xcode will fetch the package. When prompted to "Choose Package Products for TextTractor", select TextTractorCore and add it to your app's target.
Now you can import TextTractorCore and use the OCRService to process files.
import SwiftUI
import TextTractorCore
struct ContentView: View {
@State private var extractedText = "Loading..."
private let ocrService = OCRService()
var body: some View {
ScrollView {
Text(extractedText)
.padding()
}
.onAppear(perform: processFile)
}
private func processFile() {
// Get a URL to a local image or PDF file
guard let fileURL = Bundle.main.url(forResource: "my-document", withExtension: "pdf") else {
self.extractedText = "Error: File not found."
return
}
Task {
do {
let text = try await ocrService.processFile(at: fileURL)
DispatchQueue.main.async {
self.extractedText = text
}
} catch {
DispatchQueue.main.async {
self.extractedText = "An error occurred: \(error.localizedDescription)"
}
}
}
}
}The public API of the TextTractorCore library is simple and focused.
This is the main struct you will interact with.
public struct OCRService {
public init() {}
/// Main entry point: Process a file at a URL (Image or PDF)
public func processFile(at url: URL) async throws -> String
}init(): Creates a new instance of the service.processFile(at: URL): Asynchronously processes the file at the given URL. It automatically detects whether the file is an image or a PDF. It returns the extracted text as aStringor throws anOCRError.
A custom error enum for handling processing failures.
public enum OCRError: Error {
case invalidFile
case pdfConversionFailed
case processingFailed(Error) // Wraps an underlying system error
}