On-Device OCR Reader
Build an iPhone app that reads text from photos, such as book pages, receipts, signs or handwritten notes, entirely on the device with Apple's Vision framework, then saves the text with SwiftData so it can be searched later, offline. Photos can come from the camera, the photo library, or a web link downloaded with URLSession. Recognition runs in the background with progress, can be cancelled, and survives the app being closed; long documents are processed page by page. You can correct recognized text, and search highlights matches across all your scans. You'll learn Vision text recognition, handling images and orientation, Swift concurrency with tasks and cancellation, SwiftData models and queries, and building a reliable processing pipeline.
- Estimate
- ~14.5h
- Steps
- 7
- Completed by
- 0
- Proposed by
- codeseed.app
Vision · SwiftData · URLSession
Project roadmap
- 01
Design the app
~2hWrite DESIGN.md: a document has a title, created date, and pages; a page has an image file, recognized text with its lines and positions, the recognition language and a status (pending, processing, done or failed with a reason). Describe the flow from import to searchable text, how interrupted processing resumes, where images are stored, and the limits (image size and pages per document). Done when: DESIGN.md covers the data, flow and recovery.
- 02
Import images
~2hLet users take photos (with the camera), pick several from the library (PhotosPicker), or paste an image link downloaded with URLSession (checking it's really an image and not too large). Copy images into the app's storage, fix orientation, and downscale very large images. Create pending pages in SwiftData. Done when: images from all three sources become pending pages.
- 03
Recognize text
~3hProcess pending pages one by one with a VNRecognizeTextRequest (accurate level, language correction, and the user's languages) in a background Task, saving each page's text and line positions to SwiftData as soon as it's done. Show progress and allow cancelling (checking Task.isCancelled). On launch, resume pages left pending or processing. Done when: a multi-page document is recognized with progress, and killing the app midway resumes where it stopped.
- 04
Review and correct
~2hBuild a page view showing the image with recognized lines outlined on top, the text below, and editing to fix mistakes (the correction replaces the searchable text). Let users copy or share the text, and re-run recognition with a different language. Done when: users can see, correct and share each page's text.
- 05
Search offline
~2hAdd search across all documents with #Predicate queries on the text (ignoring case and accents), showing matching documents with a snippet around the match and highlighting matches on the page image using the saved line positions. Keep search fast with many documents. Done when: searching finds words in any scan, instantly and offline.
- 06
Handle errors and limits
~1.5hHandle images with no text (a clear message, not an error), unreadable files, low storage, and very large documents (process in batches). Deleting a document deletes its image files. Log processing time per page and note typical times in README.md. Done when: each problem case shows a helpful message, and nothing is left behind after deletes.
- 07
Test it
~2hPut recognition behind a protocol so tests can use a fake recognizer. Test the processing queue (resume after interruption, cancellation and failures), SwiftData queries with an in-memory container, search and snippets, and image import validation. Run the real recognizer on a few bundled test images. Done when: all tests pass.
Ready to build this?
Get a GitHub repo and start building. Your AI reviewer checks each step as you go.
Tech stack