Delivered remotely for a business based in Chicago, United States. Names withheld by agreement.
Project Overview
Industry: Agricultural technology — livestock and herd management.
Type of solution: A native iOS application built on augmented reality, with an offline-first local database, native in-app subscriptions, and a REST API and administrative back office behind it.
Business context: For anyone breeding or trading livestock, measurements are not an incidental detail — they track growth, inform breeding decisions and are quoted when animals change hands. Their value comes from being comparable over time, which means each reading needs a date, an animal it belongs to and a record that survives. In practice the measurement is taken with a physical tape, which is slow, needs two people, and puts a person close to a large animal that has not agreed to any of this. The number then goes into a notebook, a phone note, or nowhere.
General users: Livestock owners and breeders working outdoors, often without reliable mobile signal, plus platform administrators managing content, plans, device compatibility and user records.
General purpose: To let one person measure an animal accurately with the device already in their pocket, and to turn each reading into a dated, photographed entry in that animal's history rather than a figure that is quoted once and lost.
The Business Challenge
A living animal is a difficult thing to measure. It is not flat, it is not still, and it does not stay where it is put. Augmented reality measurement tools are generally built for surfaces and rooms, where a plane can be detected and relied upon. Here there is no such plane, the two points of interest can be well apart, and the operator is holding the device one-handed.
The measurement is only useful if it is comparable. A single reading answers very little. The value is in the series — the same animal, measured repeatedly, with dates attached. That means the application is a record-keeping product as much as a measurement one.
There is frequently no signal. The work happens outdoors, away from coverage. An application that requires connectivity to save a measurement will lose measurements, and losing one is worse than never having offered the feature.
Not every device can do this. The augmented reality capability the product depends on is available only on certain hardware, and the set changes with every device generation. Getting this wrong in either direction is costly: block a capable device and you lose a paying user, allow an incapable one and you take payment for something that will not work.
The purchase lifecycle belongs to the platform, not the business. Renewals, lapses, cancellations, resubscriptions and billing retries all happen on the app store's terms and timetable. Access has to reflect that accurately, and the client cannot be the source of truth about what it has paid for.
The product had to be worth paying for on its own. This is a single-purpose tool sold by subscription, with tiers that scale to the size of the user's herd. There is no adjacent revenue and no advertising to fall back on — the measurement has to be good enough that someone renews for it.
Our Approach
Build the measurement interaction around how a tape measure actually feels. The user anchors a start point, then moves the device; a preview line and a live reading update continuously as they go, until they commit the second point. The number moves while they move, which is what makes a camera feel like a measuring instrument rather than a form to fill in.
Solve the legibility problem before the accuracy problem. Markers sized for a point one metre away disappear at four. We scale marker geometry in discrete bands according to its distance from the camera, inside an animated transition — banded rather than continuous, so the markers stay steady instead of jittering with tracking noise. A measurement the user cannot see clearly is not a measurement they will trust.
Guide the session instead of assuming it will work. The application uses the platform's coaching overlay to get the user to a usable tracking state, and responds to tracking-state changes — too much movement, not enough surface detail, still initialising — rather than silently producing a poor reading.
Make the device decide, then make the server decide what the device can do. The application detects its own hardware identifier, but the judgement about whether that hardware is capable lives in a server-side list with a capability flag, managed from the back office. New hardware becomes supported by adding a record — no app release, no review cycle, no user stuck on a device that would have worked.
Assume there is no signal. Every write is local first. When the network is reachable the record is also sent and the server's identifier written back; when it is not, the record is stored with a flag saying so. Nothing is blocked on connectivity, and nothing waits for it either.
Reconcile rather than overwrite. On load, the application fetches the server's view and reconciles it against the local store record by record — updating what has changed, creating what is missing, and honouring deletions made offline through a local soft-delete flag rather than removing rows that have not yet been transmitted.
Attach evidence to every reading. The augmented reality scene is captured at the moment of measurement and stored with the record. A number that will later be quoted has a photograph behind it.
Verify entitlement on the server, and keep verifying it. Purchases are validated server-side against the store rather than trusted from the client, with the documented fallback between validation environments so that review and test purchases behave correctly. Store server notifications update entitlement as billing events occur, raw payloads are retained before processing, and a scheduled command independently re-verifies active subscriptions as a backstop for any notification that never arrives.
The Solution
Augmented reality measurement. A world-tracking session with plane detection, a guided start, an on-screen reticle, hit-testing against detected feature points, a live preview line and a continuously updating reading — with haptic and audio feedback on capture and reset.
Readable measurement geometry. Custom line geometry with orientation constraints between the two points, and marker nodes that resize in bands with camera distance so they remain legible across the working range.
Orientation-aware capture. The measurement interface works in both portrait and landscape, with the reticle position and controls following the device.
Per-animal records. Each animal has its own record with a name, notes and a photograph, and carries a running count of the measurements taken against it. Records with measurement history are protected from accidental deletion.
Measurement history. Readings can be reviewed per animal or across the whole herd, each with its date and its captured image.
Full offline operation. Measurements and records are written to a local database whether or not there is connectivity, with the interface reading from local storage so lists render immediately in either state.
Automatic reconciliation. Unsynchronised records are transmitted when the network returns and matched to their server identifiers; the server's view is reconciled against local data on load, with offline deletions preserved until they can be sent.
Server-managed device compatibility. The application checks its own hardware against a server-held capability list before a user is asked to subscribe, so compatibility rules can be corrected or extended without an app release.
Subscription with herd-size tiers. Native in-app purchase with plan tiers banded by herd size, purchase restoration, server-side receipt validation and entitlement gating on the measurement feature.
Entitlement lifecycle handling. Store server notifications drive expiry, resubscription and auto-renewal changes; payloads are retained; a scheduled command re-verifies active subscriptions independently.
Account management. Registration, sign-in, password recovery through a web-hosted reset flow, email and password changes, profile management and account deletion.
Editable help and legal content. FAQs, terms and privacy content are served from the back office and rendered inside the application, so changes ship without a release.
In-app feedback. Users can send free-text feedback from the menu, collected for administrative review.
Administrative back office. Management of users and administrators, animal and measurement records, subscription plans and subscription status, the device compatibility list, help and legal content, application settings and feedback — with spreadsheet export of user records including derived subscription band and per-user record counts, and log inspection.
Key Features
Augmented reality distance measurement on a non-flat, moving subject A guided world-tracking session with feature-point hit testing, a live preview line and a continuously updating reading, built for a subject that offers no reliable reference plane.
Distance-banded marker scaling Measurement markers resize in discrete bands according to their distance from the camera, staying legible from close range to several metres without jittering as tracking noise fluctuates.
Tracking-state guidance The application responds to the session's tracking state — excessive movement, insufficient surface detail, initialisation — and coaches the user toward a usable state rather than quietly producing an unreliable reading.
Offline-first capture with automatic reconciliation Every measurement and record is written locally first and synchronised when connectivity allows, with per-record synchronisation and soft-delete flags so nothing is lost and offline deletions survive until they can be transmitted.
Photographic evidence attached to every reading The augmented reality scene is captured at the moment of measurement and stored with the record, giving each figure visual provenance.
Per-animal measurement history Readings are grouped under the animal they belong to with dates and imagery, turning individual measurements into a comparable series.
Server-managed device capability gating Hardware compatibility is a managed data set rather than compiled logic, so newly released devices are supported by a back-office change instead of an app release.
Herd-size subscription tiers with server-side validation Plans banded by herd size, with purchases validated against the store server-side, correct handling of the production-to-sandbox validation fallback, and entitlement enforced rather than assumed.
Billing lifecycle handling with a scheduled backstop Store server notifications drive expiry, resubscription and auto-renewal changes, raw payloads are retained for later inspection, and a scheduled re-verification pass independently confirms active subscriptions.
Administratively editable in-app content Help and legal content is served from the back office and rendered in the application, so policy and FAQ changes do not require a release.
Technical Architecture
Mobile client. A native iOS application built on UIKit with a custom slide-menu container and tab controller. The measurement module composes an augmented reality scene view with a world-tracking configuration, plane detection and a coaching overlay; measurement geometry is built from custom scene nodes with orientation constraints, and node scale is updated per frame in distance bands from the camera. Distance is computed on-device and converted for display. Scene capture, image handling and remote image caching are handled on the client, along with reachability detection, haptics and audio feedback.
Local persistence layer. An on-device relational store mirroring the two core record types, with synchronisation and soft-delete flags on every row. All list views read from this store, so the application behaves identically online and offline.
Synchronisation layer. Client-driven rather than server-orchestrated. Writes check reachability and either transmit immediately — writing the server identifier back into the local row — or persist locally with a pending flag. A reconciliation pass on load compares the server's view against local records and updates, creates or removes accordingly.
API layer. A token-authenticated REST API over OAuth2 bearer tokens, with a shared base controller standardising response and validation-error shaping, and list endpoints scoped to the authenticated user.
Entitlement layer. Server-side receipt validation against the store with the documented environment fallback, a webhook receiving store server notifications that persists raw payloads before acting on them, and a scheduled console command re-verifying active subscriptions independently of notification delivery.
Administrative layer. A server-rendered back office behind a session guard, separated from the API by user type, covering records, plans, subscriptions, device compatibility, content, settings and feedback, with spreadsheet export and log inspection.
Data layer. A relational database with an explicit indexing pass applied across every table, and model-level query caching on the read-heavy models.
Storage and delivery. Uploaded imagery is written to cloud object storage rather than served from the application tier, and rendered on the client through a caching image layer.
Delivery pipeline. Deployment is automated from a continuous integration pipeline through a release-and-symlink deployment tool with custom tasks for dependency installation, cache clearing and process restart.
Flow: AR session and on-device computation → local database (always) → reachability check → token-authenticated REST API → relational database and cloud object storage → store validation and server notifications → administrative back office and export
Technology Stack
| Category | Technology |
|---|---|
| Mobile platform | Native iOS, Swift, UIKit |
| Augmented reality | ARKit — world tracking, plane detection, feature-point hit testing, coaching overlay |
| 3D rendering | SceneKit — custom node geometry, orientation constraints, per-frame updates |
| Local database | CoreData, with synchronisation and soft-delete flags per record |
| In-app purchases | StoreKit — auto-renewable subscriptions, restore, transaction observation |
| Mobile networking | Alamofire with reachability detection |
| Mobile imagery | Remote image loading and caching, photo browsing and slideshow components |
| Backend language | PHP |
| Backend framework | Laravel |
| Database | MySQL with Doctrine DBAL, migration-managed schema and a full indexing pass |
| API authentication | Laravel Passport (OAuth2 bearer tokens); session guard for the back office |
| Query caching | Model-level caching on read-heavy models |
| Object storage | Google Cloud Storage |
| Payments verification | Server-side app store receipt validation and store server notifications |
| Export & reporting | Spreadsheet export of user and usage records |
| Image processing | Server-side image handling |
| Back office | Server-rendered administrative interface with data tables |
| SMTP delivery for account and recovery flows | |
| Scheduled work | Console command for subscription re-verification |
| Deployment | Continuous integration pipeline driving automated release-based deployment |
Technical Challenges & Solutions
| Challenge | Our Approach |
|---|---|
| Measuring a subject that is neither flat nor still, with no reliable reference plane | A world-tracking session with both horizontal and vertical plane detection, point selection by hit-testing against detected feature points at a fixed on-screen reticle, and a live preview line that updates continuously so the operator can see the reading settle before committing it. |
| Measurement markers becoming invisible at range and overwhelming up close | Marker geometry scaled in discrete bands by camera distance inside an animated transition — banded rather than continuous, so markers stay readable across the working range without jittering as tracking estimates fluctuate. |
| Users producing poor readings without realising it | Guided session start through the platform's coaching overlay, with tracking-state changes handled explicitly so the interface reflects excessive movement, insufficient surface detail or an initialising session rather than presenting an unreliable number as a good one. |
| Hardware capability varying by device generation and changing with every release | Compatibility held as a server-side data set with a capability flag, checked by the application at runtime against its own detected hardware. Supporting a newly released device is a back-office record, not an app release. |
| No connectivity in the field, and a measurement that must not be lost | Local-first writes to an on-device database in all cases, with reachability determining only whether the record is also transmitted immediately. The interface reads from local storage, so it behaves identically in both states. |
| Two copies of the same records diverging between device and server | Per-record synchronisation and soft-delete flags, with pending records transmitted on reconnect and server identifiers written back, plus a reconciliation pass that updates, creates or removes local rows against the server's view while honouring deletions made offline. |
| Entitlement governed by a billing lifecycle outside the application | Server-side receipt validation rather than trusting client-reported purchase state, store server notifications driving expiry, resubscription and renewal changes, and an independent scheduled re-verification pass as a backstop for undelivered notifications. |
| Purchases behaving differently between test, review and production environments | Validation performed against the production endpoint with the documented automatic fallback to the test environment on the specific status code that indicates an environment mismatch, so review and sandbox purchases validate correctly without special-casing. |
| Help and legal content needing to change faster than app releases | FAQ, terms and privacy content served from the back office and rendered inside the application, so content changes take effect without a release or review cycle. |
Security & Reliability
Token-based API authentication. The application authenticates over OAuth2 bearer tokens, with registration, sign-in, sign-out and password recovery flows and hashed credential storage.
Separated audiences. The administrative back office runs behind a session guard with middleware protection, and is separated from the application audience by user type, enforced at authentication.
Entitlement verified, not asserted. Purchase state is validated server-side against the app store rather than accepted from the client, so access to the paid feature does not depend on what the device claims.
Billing events retained. Incoming store notification payloads are persisted before they are processed, so a billing event can be re-examined afterwards rather than inferred from the resulting application state.
Independent re-verification. A scheduled pass re-validates active subscriptions without relying on notification delivery, so a missed event does not leave entitlement permanently wrong in either direction.
User-scoped data access. Record listings are scoped to the authenticated user, and account deletion and deactivation states are enforced at authentication.
Data durability in the field. Local-first persistence means a measurement survives loss of signal, application termination and device restart, and offline deletions are preserved as flags until they can be transmitted rather than being lost or silently reapplied.
Operational visibility. Administrative log inspection is available from the back office, and deployment runs through an automated pipeline with a release-based layout that supports rapid rollback.
Scalability & Performance
The expensive work happens on the device. Augmented reality tracking, geometry, distance computation and image capture all run locally and consume no server capacity. Server load scales with record-keeping and billing traffic, not with measurement activity.
Reads served from local storage. Because the client keeps its own copy, list and detail views render immediately without a network round trip, and the interface performs identically with or without connectivity.
Per-frame work kept bounded. Marker scaling is applied in discrete distance bands rather than recomputed continuously, keeping the render loop predictable during an active session.
Indexed schema and cached reads. An explicit indexing pass was applied across every table, and model-level caching covers the models read on nearly every request and written rarely.
Imagery offloaded. Uploaded photographs are stored and delivered from cloud object storage rather than the application tier, and cached on the client, which matters in a product where every record carries an image.
Stateless application tier. Token authentication and externalised storage keep application instances free of request-scoped state, so capacity can be added horizontally.
Billing verification kept off the request path. Subscription re-verification runs as scheduled batch work rather than inline, so store round trips never affect a user-facing response.
Business Outcomes
- One person can now take a measurement that previously needed two, using the device already in their hand rather than a physical tape.
- Measurements became a record rather than a moment, with each reading attached to a specific animal, dated, and stored with a photograph taken as it was captured.
- The application works where the work happens, with no connectivity required to capture or review anything and automatic reconciliation when signal returns.
- Compatibility can be corrected without shipping an app, because the device capability rules are managed data rather than compiled logic.
- Users are told whether their device will work before they are asked to pay, avoiding subscriptions sold against a capability the hardware does not have.
- Access reflects billing reality, with entitlement verified server-side, driven by store notifications and independently re-checked on a schedule.
- Help and legal content stays current, editable from the back office without a release cycle.
- The business has visibility of its own usage, through administrative record management and exportable user reporting.
Why it worked
Augmented reality demos are easy and augmented reality products are not. The gap between the two is entirely in the cases the demo skips: the subject that will not hold still, the marker that vanishes at four metres, the tracking state that has quietly degraded, the device that cannot run the feature at all, and the user standing in a field with no signal who has just taken a measurement they cannot afford to lose. Every one of those is a reason a user deletes the app, and none of them is visible in a prototype.
Our team builds for those cases. We made the measurement interaction feel like the instrument it replaces, with a live reading that moves as the user moves. We solved legibility before precision, because a reading nobody can read clearly is not trusted regardless of its accuracy. We made every write local first, so that connectivity determines when a record is transmitted and never whether it survives. We moved the hardware compatibility decision to the server, so that a device released next year does not require an app release to support. And we verified entitlement server-side and kept re-verifying it, because in a subscription product the billing lifecycle belongs to the platform and getting it wrong costs either revenue or a user.
Our teams work across native iOS and augmented reality, offline-first mobile architecture and synchronisation, in-app subscription and entitlement lifecycles, and Laravel API and administrative platform development — with the product judgement to know which of a feature's edge cases are genuinely edges and which are simply the conditions the product will actually be used in.
Final Summary
Measuring livestock is a small, specific, stubbornly manual task. It takes a tape, two people and a cooperative animal, and the number it produces usually ends up in a notebook where it cannot be compared with anything.
Our team built an iOS application that replaces the tape with the phone camera. Augmented reality tracking, feature-point selection and a live preview line let one person take a reading on a subject that is neither flat nor still, with markers that stay legible across the working range and coaching that steers the user away from a poor capture rather than letting them make one. Every reading is stored against the specific animal it belongs to, with a date and a photograph captured from the augmented reality scene at the moment of measurement, so a figure that will later be quoted has a history and evidence behind it.
Because the work happens outdoors and away from coverage, the application is offline-first throughout: records are written locally in every case, transmitted when the network allows, and reconciled against the server's view on load, with deletions made offline preserved until they can be sent. Hardware compatibility is held server-side as managed data, so a newly released device is supported by a back-office change rather than an app release — and users learn whether their device can run the feature before they are asked to subscribe. The subscription itself is tiered by herd size, validated server-side against the app store, updated by store server notifications and independently re-verified on a schedule, so access reflects what has actually been paid for rather than what the device reports.
Behind it sits a Laravel API and administrative back office covering records, plans, subscription status, device compatibility, editable in-app content and exportable reporting. It is a focused product rather than a large platform, and its value lies in a single task done properly — which, for a tool someone chooses to renew, is the test that matters.