A lightweight OCR toolkit for iOS built with UIKit.
ATOCR provides reusable tools for document scanning workflows, including camera capture, image compression, and a simple OCRUseCase for processing OCR requests and retrieving results.
- 📷 Camera capture manager
- 🖼 Image compression before upload
- 🔄 Automatic OCR result polling
- ⚡ Combine-based OCR workflow
- 🎯 UIKit-first design
- 📱 iOS 13+ support
- iOS 13+
- Swift 5.9+
- UIKit
- Combine
Add the package dependency:
dependencies: [
.package(
url: "https://github.com/AyanTech/ATOCR-iOS",
from: "1.0.0"
)
]Or in Xcode:
File → Add Packages
ATOCRCameraManager provides a lightweight wrapper around UIImagePickerController.
let camera = ATOCRCameraManager()
camera.delegate = self
camera.openCamera(
from: self,
guid: "document-id"
)Receive captured image:
extension ViewController:
ATOCRCameraManagerDelegate {
func cameraManager(
_ manager: ATOCRCameraManager,
didCapture image: UIImage?,
guid: String?
) {
}
}Compress images before upload to reduce payload size.
let compressor =
ATOCRImageCompressor()
let data =
compressor.compress(image)let base64 =
compressor.compressBase64(image)let config =
ATOCRImageCompressor.Config(
maxSizeMB: 3,
minCompression: 0.2,
resizeStep: 0.9
)
let compressor =
ATOCRImageCompressor(
config: config
)OCRUseCase is the main interface for executing the OCR workflow.
It handles OCR result processing and automatically polls the OCR service while the result is in a pending state.
The polling logic is handled internally, so consumers do not need to implement timers or recursive requests.
let cancellable = useCase.execute(
url: url,
token: token,
input: input
)
.sink(
receiveCompletion: { completion in
switch completion {
case .finished:
break
case .failure(let error):
print(error)
}
},
receiveValue: { result in
print(result)
}
)The OCR result is returned as:
AnyPublisher<OCRResultModel, ATErrorV2>Handle the result using Combine:
cancellable = useCase.execute(
url: url,
token: token,
input: input
)
.receive(on: DispatchQueue.main)
.sink(
receiveCompletion: { completion in
if case .failure(let error) = completion {
print("OCR Error:", error)
}
},
receiveValue: { result in
print("OCR Result:", result)
}
)When the OCR service returns a pending status, OCRUseCase automatically waits for the specified NextCallInterval and requests the result again.
Execute OCR Request
↓
Receive OCR Response
↓
Is Pending?
/ \
Yes No
↓ ↓
Wait Return Result
↓
Request Again
↓
Repeat
The consumer does not need to manage polling, delays, or repeated network requests.
Select Document
↓
Open Camera
↓
Capture Image
↓
Compress Image
↓
Execute OCRUseCase
↓
Wait for OCR Result
↓
Poll While Pending
↓
Receive OCRResultModel
Add the following key to your Info.plist:
<key>NSCameraUsageDescription</key>
<string>Camera access is required for OCR scanning.</string>- AyanTechNetworkingLibrary
- Combine
MIT