DevPortfolio — Interview Talking Points
The 30-second pitch
“DevPortfolio is an interactive developer business card. You upload a resume PDF, Vision extracts the text, an on-device CoreML classifier tags each paragraph as experience / skill / education / project, and the app builds a structured portfolio you can share via QR code. The AR mode lets you drop your projects as 3D cards onto a detected horizontal plane that a recruiter can walk around. The whole app is built in TCA — every action flows through a deterministic reducer tree, which made the resume parser end-to-end testable without spinning up a real PDF in tests.”
The 3-minute deep dive (ML pipeline)
“The ML side is more of a systems story than a model story. The model is small — a Create ML text classifier with five classes — but getting it production-ready was instructive.
Data was the bottleneck. Open resume datasets exist but are noisy. I curated ~500 paragraphs across the five classes from anonymized sources, hand-corrected the labels, held out 20% for evaluation. First pass hit 72% accuracy. The 28% errors were almost entirely between ‘experience’ and ‘project’ — paragraphs like ‘Built a payments service for Acme’ look like both. Adding a contextual feature — ‘is this paragraph in a list with a date range?’ — pushed it to 84%.
Inference is sub-millisecond per paragraph on Neural Engine. A 1-page resume yields about 20 paragraphs, so classification overhead is 20ms. The end-to-end time is dominated by Vision’s
VNRecognizeTextRequestat about 2 seconds for a page rasterized to 1200×1500.The integration was clean because I wrapped the model in an actor that exposes a single
asyncclassify method. The TCA reducer dispatches an effect that runs classification in aTaskGroupfor parallelism across paragraphs. Result drops back into state as a.classified(...)action. Tests can swap the actor for a fake that returns canned results — no model loading required in test, which keeps test time under a second.The honest limitation: 84% accuracy means roughly 3 paragraphs per resume are mislabeled. So the UI presents the classification as a draft — the user reviews and corrects. That UX choice — ‘AI assists, human confirms’ — is more important than the model’s accuracy for this product.“
12 interview questions
1. “Walk me through TCA.”
The Composable Architecture is Point-Free’s redux-style framework for Swift. Every feature has a State, an Action, and a Reducer that maps (State, Action) -> State + Effects. Views observe state and dispatch actions. Effects (async work, side effects) are described declaratively and executed by the store. The win: deterministic. Same actions produce same state. Tests are pure-function assertions. The cost: more boilerplate than MV — you write Action cases for every interaction. For an app with 4+ flows and shared state, it’s worth it.
2. “Why TCA over MV?”
MV (Model-View, the post-MVVM SwiftUI default) is great when your state is small and local. DevPortfolio has resume parsing producing state consumed by portfolio editing, then by AR rendering, then by sharing — that’s a state tree, not isolated views. TCA gives me a single source of truth for the whole tree, child reducers per feature, and Scope to compose them. The deterministic property also helps debugging — I can serialize an action sequence from a crash report and replay it locally.
3. “How did you train the CoreML model?”
Create ML’s Text Classifier template. Trained on ~500 labeled paragraphs in a .csv. Iterated on the training set when accuracy plateaued — added contextual examples for the experience/project boundary, which were the hardest class pair. Final model is ~600 KB, sub-millisecond inference on Neural Engine. Could improve further with a transformer model, but the marginal accuracy isn’t worth the model size jump for this product.
4. “Why on-device ML and not a server call?”
Resumes are private. Sending them to a server — even mine — is a worse privacy story than running a slightly less accurate model locally. Modern iPhones run CoreML text models with imperceptible latency. The accuracy ceiling for this task on-device is high enough; for a more complex task (e.g., extracting nested entities) I might reach for a server with a larger model, with explicit user consent.
5. “How does the AR mode work?”
ARWorldTrackingConfiguration with horizontal plane detection. ARView is wrapped in UIViewRepresentable and driven by an ARSessionController actor. On plane detection delegate callback, I instantiate AnchorEntity(plane: .horizontal) and add card ModelEntitys. Cards are flat planes with the project image texture-mapped. Gestures (tap to expand, pinch to scale) are RealityKit’s built-in gesture recognizers attached to entities.
6. “What about people occlusion?”
ARWorldTrackingConfiguration.frameSemantics = [.personSegmentationWithDepth]. Enables on iPhone XS or later. When a person walks in front of the card, the card is correctly occluded. I added this in v1.1 after a user reported it looked fake without occlusion. Small change, big perceived-quality lift.
7. “How do you handle AR not being available?”
Gate AR entry on ARWorldTrackingConfiguration.isSupported. If false, show an alert: ‘AR requires an A12 or newer device’ and offer a list-mode view of the same projects. No crash, no dead UI.
8. “How do you test TCA?”
The TestStore from TCA. Send an action, assert the state change, assert effects. Effects can be stubbed with withDependencies { ... }. For DevPortfolio’s resume parser feature, my test sends .start, asserts isProcessing flips, the extractor and classifier dependencies are swapped for fakes returning canned text and labels, and the final state matches the expected Portfolio. End-to-end deterministic test, runs in milliseconds.
9. “What’s the App Store submission journey like?”
First submission was rejected for two reasons. One: my NSCameraUsageDescription was ‘Used for AR.’ Too vague — the reviewer flagged it. I rewrote to ‘Used for AR mode to place your portfolio’s project cards in the physical space around you.’ Two: my screenshots didn’t show the AR mode prominently; the reviewer couldn’t see why the camera permission was needed. I added an AR-mode screenshot and an App Preview video. Approved on resubmission.
10. “Why CoreML over a hosted LLM API?”
Cost, latency, privacy. A hosted LLM call costs cents per call, adds 500–2000 ms latency, and ships the user’s resume to a third party. CoreML costs nothing, completes in <100 ms, never leaves the device. For a paragraph-classification task, CoreML is the strictly better choice. If I wanted to generate portfolio summaries from the resume — a creative task — then a hosted LLM with consent makes sense.
11. “How would you scale the model to non-English resumes?”
The current model is English-only. Two paths: (1) train language-specific models, ship them all bundled — works for ~10 languages before app size becomes a problem. (2) train a single multilingual model on a combined corpus — harder but scales better. I’d start with (1) for the top 5 languages, evaluate accuracy, then decide if (2) is worth the training effort.
12. “Tell me about a bug.”
AR mode would freeze for 2-3 seconds after returning from background. The session was being paused on background and resumed on foreground, but the render loop wasn’t waking up cleanly. Took half a day. Fix: explicitly call arView.session.run(config) on scenePhase change to .active, not relying on RealityKit’s automatic handling. Lesson: ARKit’s lifecycle assumptions don’t always match SwiftUI scene phase changes — be explicit.
Red-flag answers
If asked “is your model better than ChatGPT,” don’t say “yes.” Say: “No, but it doesn’t need to be. GPT-4 would classify these paragraphs more accurately than my model, but at the cost of latency, money, and shipping the user’s resume to a third party. For an 80%-accuracy ‘draft for human review’ UI, on-device is the better product decision.”
If asked “did you write the TCA library yourself,” don’t be vague. Say: “No, it’s Point-Free’s open-source TCA. I use it because the deterministic reducer model fits this app’s state complexity. I could roll my own redux-style store, but TCA has refined ergonomics — Scope, _printChanges, TestStore — that I’d just be reinventing.”
Next: Capstone 6 — PlanBoard.