DFDavid FauciNetwork Engineer

Personal Projects

Building WrenchLog: A Practical iPhone App for Vehicle Service History

WrenchLog started as a way to reduce personal maintenance friction, but it turned into a useful example of the kind of software I care about most: grounded, practical, and shaped by real day-to-day use.

PublishedApril 19, 2026
Reading time9 min read
Tagsswiftui • ios • swiftdata • app-intents • ocr • product-design • personal-tools • mobile-development

Overview

I built WrenchLog to solve a simple problem I kept running into: maintenance information was scattered across receipts, notes, photos, and memory. What started as a personal tool for keeping vehicle service records in one place became a focused SwiftUI app with VIN lookup, photo attachments, quick service logging, export tools, and a workflow built around real maintenance tasks rather than generic CRUD screens.

The Problem I Actually Wanted to Solve

WrenchLog started from a very ordinary kind of friction.

I have multiple vehicles and machines to keep track of, and the information I actually need is never in one place when I want it. A receipt might be in my glove box, a mileage note might be in my phone, a torque spec might be written down somewhere else, and the date of the last oil change might live mostly in memory. That works until it does not. Once there are a few vehicles involved, or once enough time passes between service events, the system becomes less of a system and more of a collection of half-remembered details.

What I wanted was not a giant fleet-management platform or a bloated reminder app. I wanted something closer to a durable personal tool: a way to keep vehicle records, service history, photos, receipts, VIN information, and a few important specs together in one place. It needed to be fast enough that I would actually use it while standing in a garage, next to a truck, or after finishing a repair.

That constraint mattered more than anything else. If the app added too much overhead to logging work, it would fail its main purpose.

What the App Does

At its core, WrenchLog is an iPhone app for recording and organizing maintenance history per vehicle.

The app starts with a grid of vehicles. Each vehicle can be represented by a simple icon or a captured photo, which sounds minor but matters in daily use. It is faster to recognize “my truck” by an image than by scanning a list of names. From there, each vehicle has its own detail screen with maintenance history, quick-add actions for common service types, export options, and a separate service details area for storing specs like oil capacity, torque values, or any custom note that is worth keeping around.

The maintenance logging workflow supports both manual entry and quick entry. For a more complete record, I can log a title, date, mileage or engine hours, notes, cost, a service photo, and a receipt photo. For the fast path, I can use quick-add buttons for common service events like oil changes or brake work, then optionally attach a vehicle image or receipt. That split between full entry and fast entry was intentional. In practice, some service events deserve detailed records, and some just need to be captured quickly before I forget them.

One of the more useful pieces is VIN handling. When adding a vehicle, the app supports three paths: manual details entry, manual VIN entry, or taking a photo of the VIN for OCR. Once a VIN is available, the app can look up vehicle details through NHTSA’s VIN decoder and prefill information like year, make, and model. It can also open an in-app recall lookup flow tied to that VIN. The app stores the VIN as part of the vehicle record and surfaces it in the service details area, where it can be copied directly to the clipboard.

There are also export tools. Maintenance history can be exported as CSV, and photos can be exported separately with a manifest. That matters because service data often leaves the app at some point: for resale documentation, personal records, or just sharing a maintenance history with someone else.

How I Approached the Build

I treated this project less like a consumer startup concept and more like building a solid personal utility that could stand on its own.

The first step was defining the workflow, not the feature list. I thought about the exact moments when I would open the app: right after completing a repair, when checking what was last done on a vehicle, when trying to remember a torque value, or when I needed a VIN quickly. That helped shape the product into a set of practical interactions rather than a vague maintenance management concept.

From there, I kept the structure simple. The app is organized around vehicles first, records second. I did not try to build a global timeline, a complex scheduling engine, or a heavy system of recurring tasks. Those ideas are interesting, but they are also easy ways to overcomplicate version one. I wanted the app to be good at one thing first: being the place where completed work gets captured and retrieved.

That same bias guided the UI. I avoided forcing users into a rigid taxonomy of vehicle types. Icons help, but editable details matter more than formal classification. I also added quick-add buttons because entering common maintenance events should not feel like filling out a form every time. The best part of a tool like this is that it reduces friction instead of adding it.

At the same time, I tried not to hide complexity where it actually belongs. A maintenance record is not just a title and a date. Often there is a cost, a photo, a receipt, and some context that only matters months later. So I built the data model to support richer records early, even if the UI keeps that complexity optional.

Technical Decisions and Architecture

The app is built with SwiftUI and SwiftData. That combination made sense for this project because the data model is local, strongly structured, and tightly coupled to the UI. I did not need a backend to solve the problem I was targeting. Local persistence was enough, and keeping the system local-first reduced both implementation complexity and privacy concerns.

The main model is centered on three concepts: vehicles, maintenance records, and vehicle-specific service specs. Vehicles hold identity and metadata, including VIN, icons, and optional vehicle photos. Maintenance records store the actual service history, including cost, notes, usage values, and image attachments. Service specs act as editable reference data attached to a vehicle rather than to a specific event.

One design decision I was happy with was separating service photos from receipt photos. At first glance, one generic image field feels sufficient. In reality, those are different kinds of information. A picture of a filter or repair area is not the same as a shop invoice, and they tend to be used differently later. Modeling them separately made the record detail view clearer and gave the app room to support better export behavior.

VIN handling was another interesting area. For manual VIN entry, I integrated NHTSA’s VIN decoding service to populate core vehicle data. For VIN photos, I used Apple’s Vision framework for OCR. The naive approach to OCR is to extract all text and look for a 17-character string, but VIN plates often include surrounding text and noise. I ended up tightening the extraction logic to prefer labeled VIN patterns and then added a confirmation step so the user can edit the OCR result before lookup runs. That is a good example of where product and engineering meet: the technical feature worked, but the user experience needed one more step to become reliable enough.

I also added Siri and App Shortcuts support for common maintenance logging. That was partly an experiment in making the app more accessible from the lock screen or while multitasking, and partly an exercise in integrating App Intents into a small but useful workflow.

Finally, I built small operational pieces that matter when a project becomes real: export, support and privacy pages for GitHub Pages, App Store metadata, camera and photo permission handling, and the sort of review notes Apple actually expects from a new app submission.

Challenges, Tradeoffs, and the Less Glamorous Parts

The hard parts of this project were not the headline features. They were the edges.

Photo handling was one example. Camera capture, photo library access, privacy descriptions, and form flows all have to work together cleanly, especially on-device. It is easy to get something compiling and still have it fail in the practical path that matters. The same was true of App Store submission: the first submission involved more work around screenshots, support URLs, privacy policy URLs, and review context than around code.

OCR was another place where the first 80 percent was easy and the last 20 percent mattered. A technically successful OCR result is not always a usable result. If a photo includes too much surrounding text, or if a single character is wrong, VIN lookup fails. That pushed me toward a design that is more conservative and more honest: extract, present, confirm, then look up.

There were also deliberate omissions. I did not build reminders, scheduling, push notifications, multi-user support, cloud sync, or analytics. Some of those would be natural future additions, but each one expands the product and changes the trust boundary. For this version, I wanted the app to remain local, understandable, and fast.

That meant making peace with scope. I would rather have a smaller app that fits a real workflow than a bigger app that gestures at everything.

What I Learned and What's Next

This project reinforced something I already suspected: practical software gets better when it is anchored to a real operating context.

The most useful decisions came from thinking about when and where the app would actually be used. That led to quick-add service logging, VIN copy support, service specs, receipt attachments, and export functionality. Those are not flashy features, but they are the ones that turn an app from a demo into a tool.

On the engineering side, I was reminded that local-first is still a strong default for a certain class of apps. It reduces complexity, shortens the feedback loop, and makes it easier to get the product right before taking on infrastructure. I was also reminded that reliability often means adding one more explicit step, not removing one. The VIN confirmation flow is a good example of that.

If I continue building WrenchLog, the next improvements would likely be in three areas. First, record editing and deletion should become more complete. Second, VIN OCR can probably become even more robust with better heuristics around formatting and image capture. Third, I would revisit reminders or due-soon forecasting carefully, but only if I can add them without turning the app into a chore to maintain.

Overall, WrenchLog has been a good project because it sits at the intersection I care about most: clear product thinking, practical engineering, and small decisions that improve everyday use. It is not trying to be everything. It is trying to be reliable, useful, and well-considered. That is the kind of software I like building.

Closing Reflection

WrenchLog started as a way to reduce personal maintenance friction, but it became a strong example of the kind of project I value: grounded, iterative, and shaped by real use instead of abstract feature planning. It gave me room to work across product thinking, SwiftUI implementation, data modeling, OCR, platform integration, and App Store delivery without losing sight of the original goal. In the end, I think that restraint is part of what makes the project meaningful.

More Notes

Keep reading

Building TheFamHub: Shipping a Private Family Coordination App

TheFamHub is a private iPhone app for family coordination built around invite-only groups, shared lists, structured tasks, family events, trusted location sharing, and disciplined scope. This build log covers the product decisions, technical architecture, and tradeoffs involved in shipping something practical enough for real household use.

When the Manufacturing Certificates Quietly Expired: An ACI EOL Postmortem

A routine port-add on a Cisco ACI fabric exposed nine months of silent policy distribution failures, a seven-hour cluster time drift, and a fleet of expired manufacturer certificates on hardware past its support life. The right answer turned out to be the unsatisfying one.

Before You Read Anything Else

This is the one post on the site written directly by me. The stories, projects, and experiences here are real, but nearly all of the writing and presentation across the site is created with heavy AI assistance as part of a personal experiment in what these tools can help me build.