lang-download¶
Fetches .traineddata at runtime instead of shipping it, for consumers who cannot afford 3.8–4.1 MB per language in their download size.
Features¶
- No HTTP dependency. It uses
HttpURLConnection, which both targets already have — a networking library inside an SDK is a version conflict waiting to happen, and this module makes exactly one kind of request. - Checksums are part of the source, not an afterthought: a
.traineddatagoes straight into a native library, so a mismatch is fatal rather than a warning. - Cached on disk, with partial downloads written to
.partfiles and the cache guarded by a mutex. - Targets: android + jvm, with the whole download implementation shared through a
jvmAndAndroidintermediate source set. iOS needs no language data at all. - Depends on
core(api) only.
Core Components¶
DownloadingLanguageDataProvider¶
A LanguageDataProvider with three additions:
isCached(language): Boolean— whether a model is already on disk, so no network call is needed.suspend prefetch(languages): List<OcrLanguage>— downloads now so the first extraction does not pay for it. Best-effort: failures are logged, not thrown.suspend clearCache(): Int— deletes cached models and any.partfiles a killed download left behind, and returns how many files were removed. Suspending because it takes the same lock the download path does.
Created with downloadingLanguageDataProvider(source, cacheDirectoryPath, logger). The default cache directory is filesDir/uncial-tessdata on Android — deliberately filesDir and not cacheDir, because re-downloading several MB after the OS reclaimed 4 MB is the worse trade — and a per-user directory under the system temp dir on the JVM.
TessDataSource¶
baseUrl: required to behttps://and to end in/. Defaults toTESSDATA_FAST_BASE_URL, the sametessdata_fastrepository theuncial-lang-*artifacts are built from;TESSDATA_BASE_URLpoints at the full models (12 MB forukr, 23 MB foreng).checksums: language to hex SHA-256, defaulting toTessDataSource.DEFAULT_CHECKSUMS, which pins Ukrainian and English. Case and surrounding whitespace are ignored, so a hash pasted out ofsha256sumor a CI log works as-is.urlFor(language),checksumFor(language).
Usage¶
Chain it behind a bundled or system provider to prefer what is already there:
It will not ask the user first
No progress reporting, no background scheduling, no retry policy. Downloading several MB
silently on a metered connection is a product decision, not a library one — check
isCached and drive prefetch yourself if your users should be asked.
An unpinned language is trusted on HTTPS alone
Leaving a language out of checksums is allowed — some consumers genuinely cannot pin a
hash for a model chosen at runtime — but the provider says so through its logger, and a
pinned checksum that does not match throws OcrError.NoLanguageData rather than letting
the bytes reach the native layer.