Back to walidsassi.com

Mobile System Design Interview

Swift Academy Podcast · Series A mock-interview series with Artem Mirzabekian, Lead iOS Engineer. Real mobile system design problems, solved out loud the way a senior interview actually runs, with the roles swapping between episodes. Two episodes published. 🎧 Swift Academy Podcast · Series · 2 episodes · Requirements • APIs • Domain • Architecture “Most system design conversations stop at the box diagram. The interesting part starts after: what happens when the cursor is stale, the receipt URL has expired, and the user is on a train with no signal.” The premise of this series What This Series Is Mobile system design is usually taught as a whiteboard ritual, or reduced to an argument about architectural acronyms. This series does the opposite. Each episode takes one realistic feature and designs it properly, out loud, with the trade-offs left visible instead of tidied away. Episode 1 tackles an e-commerce home page; episode 2, broken down below, tackles the transaction history of a banking app. The feature is deliberately unglamorous and deliberately hard. A transaction list looks trivial until you hold it to production standards: thousands of records, a server that keeps changing beneath you, a search field, filters, receipts behind expiring URLs, and a security team with a firm opinion about what may be written to disk. Every decision in it has a cost, and the point of the series is to name that cost rather than hide it. Inside Episode 2: Designing a Transaction History Paging Through a List That Will Not Sit Still Offset pagination breaks the moment records are inserted while the user scrolls: rows repeat, rows vanish, and nobody notices until it reaches production. Cursor-based pagination is the answer, and the design work is in the details around it. Why offset paging is unsafe against a mutating dataset, and what the user actually sees when it fails Cursor design: opaque tokens, stability guarantees, and what to do when the server invalidates one mid-scroll Prefetch thresholds, in-flight request de-duplication, and cancelling work the user has scrolled past Where the cursor lives, and why it does not belong in the view Search and Filter Without Fighting the Pagination Search and filters are where a clean pagination design usually falls apart, because each one produces a different result set with its own cursor and its own lifecycle. Server-side versus client-side filtering, and the point where the dataset makes the choice for you Debouncing, cancellation, and keeping the visible list coherent while a query is in flight Composing filters, date ranges, categories, amounts, without a combinatorial explosion of endpoints Resetting or preserving scroll position when the query changes States and Freshness “Loading, loaded, error” is not a state model, it is a placeholder for one. Real screens are simultaneously stale, refreshing, partially loaded, and partially failed. Modelling loading, empty, partial, stale, refreshing and failed as a type the compiler can check Distinguishing an empty list from a list that has not loaded, the single most common bug in this feature Freshness policy: what to show immediately from cache, what to revalidate, and what to block on Error recovery that does not discard the data the user is already reading The Offline Versus Security Debate This is the part of the series with no clean answer, which is exactly why it is worth recording. Offline access argues for caching transactions on device. The security posture of a banking app argues against writing financial history to disk at all. The real threat model: device theft, backups, jailbreak, shared devices, and what each one actually exposes What a partial answer looks like, caching metadata but not amounts, or encrypting with a key held in the Secure Enclave Cache lifetime tied to session lifetime, and what must be destroyed at logout Why this decision belongs to the product and the security team, and what the architecture must do to keep it reversible Expiring Receipt URLs Receipts are served behind short-lived signed URLs. That single constraint reaches surprisingly far into the design. Why a signed URL must never be persisted, and what to persist instead Fetching the URL lazily at the moment of use, and handling expiry between tap and load Retry and re-signing flows that do not strand the user on a broken screen What this implies for share sheets, deep links, and anything that outlives the session SwiftUI, UIKit, and the Layers Underneath The UI framework is the least interesting decision on this list, and the one people argue about most. We treat it as an implementation detail and spend the time on the layering that survives either choice. Where SwiftUI is a clear win for this screen, and where UIKit still holds an advantage on large lists Interoperating deliberately rather than accidentally, and keeping the boundary in one place ViewModel, Presenter, Service, UseCase: what each layer owns, and the concrete test you apply to decide where a piece of logic belongs Keeping the pagination, freshness and caching policy testable without a running UI What This Series Deliberately Avoids No MVVM versus VIPER debate. It is a distraction from system design. We talk about responsibilities and boundaries; name the resulting pattern whatever your team already calls it. No whiteboard theatre. Every decision is tied to a failure mode you can actually observe in a shipped app. No single right answer. Where the trade-off is genuine, it is left as a trade-off, with the cost of each side stated plainly. About the Guest Artem Mirzabekian Lead iOS Engineer at Sovcombank • 10+ years scaling mobile platforms Artem leads iOS engineering at Sovcombank, where transaction history is not a hypothetical exercise but a screen used by millions of customers under real regulatory and security constraints. His work spans iOS architecture, Swift, SwiftUI, system design and technical leadership, with a decade of experience scaling mobile platforms and the teams that build them. Watch the Series Episode 1, Designing an E-Commerce Home Page The opening episode takes one of the most common mobile engineering scenarios and runs it as a real interview: clarifying requirements, defining the APIs and data models, and arriving at an architecture that scales. Artem published a companion repository with a working implementation of the ideas discussed, typed backend-driven sections, defensive DTO mapping, cache-first loading, visibility-based analytics, optimistic add-to-cart, and an image pipeline with downsampling and request de-duplication. 🎥 Watch episode 1 · 95 min 📦 Companion repository Episode 2, Designing a Banking Transactions Screen The second episode swaps the roles: this time Walid is the candidate and Artem the interviewer. It is the session the breakdown below is drawn from, working through the transaction history of a mobile banking application from requirements to architecture. 🎥 Watch episode 2 🎬 Full playlist on YouTube 🎧 Follow on Apple Podcasts Go Deeper: AI-Driven Swift Architecture The layering this series relies on, use cases, services, and the boundaries that keep a feature testable, is the subject of the book. If the sessions leave you wanting the full treatment of Clean Architecture, TDD and modular Swift on production codebases, that is where to continue. 📘 Read about the book

September 5, 2026 · 6 min · Walid Sassi

Swift Academy Podcast, Season 1

September 5, 2026 · 0 min · Walid Sassi

Swift Academy Podcast, Season 2

September 5, 2026 · 0 min · Walid Sassi

Swift Academy Podcast, Season 3

September 5, 2026 · 0 min · Walid Sassi

Performance Is More Than Just Speed with Artem Mirzabekian and Bogdan Poplauschi

Swift Academy Podcast, Episode 2, Season 3 Performance Is More Than Just Speed Part two with Artem Mirzabekian and Bogdan Poplauschi, going underneath the abstractions: Swift Concurrency migration, the cost of the tools we use daily, and why application launch is an architecture problem. August 23, 2026 🎧 Swift Academy Podcast · Episode 2, Season 3 • Part 2 of 2 · Concurrency • Abstraction • App Launch Watch the Episode The Hidden Cost of the Tools We Use Daily Part one challenged the myths. This one goes underneath them, into Swift Concurrency, abstractions, architecture, application launch, frameworks and dependencies. The connecting idea is that performance work rarely starts with performance. Migrating an existing codebase to Swift Concurrency tends to expose architectural weaknesses that were always there, and a dependency graph that grew quietly for two years turns into a launch time nobody can explain. What We Go Through Migrating an existing codebase to Swift Concurrency The migration is where most teams meet the model properly for the first time, and where the wrong mental model gets expensive. Migration pitfalls, and the mental models that cause them What async/await really means for execution, as opposed to what people assume Common Swift Concurrency anti-patterns that survive a migration The impact of @MainActor on CPU-heavy work When Task.detached becomes a problem rather than a solution Why blocking asynchronous work leads to deadlocks How adopting concurrency exposes architectural weaknesses that predate it Abstraction versus performance Abstraction makes code easier to read, test and maintain. It also hides what the application is actually doing, and at some point that stops being a good trade. Balancing clarity, maintainability, abstraction and performance rather than picking one Why understanding what sits underneath an abstraction is part of using it well Where protocols help the architecture and where they quietly cost something Application launch and the dependency graph Why a complex dependency graph slows down launch, and how that happens gradually The hidden cost of frameworks and of the tools used every day Treating launch time as an architectural property rather than a metric to optimise at the end About the Guests Artem Mirzabekian & Bogdan Poplauschi Lead iOS Engineer at Sovcombank • Staff Engineer, iOS Architecture & CI/CD Artem co-hosts the Mobile System Design Interview series. Bogdan appeared twice in Season 1, on taming legacy code and on refactoring in practice, and both reviewed AI Driven Swift Architecture. Key Takeaways A concurrency migration is an architecture review in disguise. The warnings you cannot silence are usually pointing at a real design problem. @MainActor is not a safety blanket. Putting CPU-heavy work behind it moves the cost onto the frame budget. Task.detached is rarely the answer. Reach for it deliberately, not to make a warning disappear. Abstractions have a price. Use them, but know what they are doing underneath before they become the bottleneck. Launch time is architectural. A dependency graph that grew unchecked cannot be optimised away at the end. Resources & Links 🎥 Season 3 Episode 2, Watch on YouTube 🎧 Part 1, Modern iOS Performance Myths 🧵 Swift Concurrency Explained with Matt Massicotte Listen & Subscribe If your team is midway through a Swift 6 migration and the warnings are multiplying, this pair of episodes is the one to share. 🎥 Watch on YouTube 🎧 Listen on Apple Podcasts ☕ Support the Podcast

August 23, 2026 · 3 min · Walid Sassi

Modern iOS Performance Myths with Artem Mirzabekian and Bogdan Poplauschi

Swift Academy Podcast, Episode 1, Season 3 Modern iOS Performance Myths Season 3 opens with a two-part conversation on performance, with Artem Mirzabekian and Bogdan Poplauschi. Part one is about the dogmas: what a fast app actually is, and why so many of them still feel slow. July 5, 2026 🎧 Swift Academy Podcast · Episode 1, Season 3 • Part 1 of 2 · Performance • SwiftUI • Concurrency Watch the Episode Fast Is Not the Same as Feeling Fast An application can be technically fast and still feel slow. That gap, between what a benchmark measures and what a user perceives, is where this episode spends most of its time. This is not a conversation about micro-optimisations or benchmark numbers. Artem and Bogdan have both spent years on high-performance iOS applications in production, and the discussion is about what actually happens under the hood once an app grows past the size where intuition still works. Several popular beliefs get challenged along the way, including a few that have hardened into dogma since SwiftUI arrived. The Myths We Take Apart Did SwiftUI simplify performance, or hide its cost? The framework removed a great deal of boilerplate. Whether it removed the underlying cost, or simply moved it somewhere harder to see, is the more interesting question. Which SwiftUI patterns turn dangerous once an application scales Is Environment quietly becoming the new Service Locator? When SwiftUI diffing stops being free and becomes a real bottleneck What actually consumes the 16.67 ms frame budget Is UIKit deprecated? Short answer in the episode, and it is not the one the discourse suggests. The longer answer is about where each framework still earns its place. Investigating what Instruments will not tell you How experienced engineers approach a performance problem the profiler does not immediately explain Concurrency versus parallelism, and why the confusion between the two produces bad fixes What a “performant” iOS app means in 2026, stated plainly About the Guests Artem Mirzabekian & Bogdan Poplauschi Lead iOS Engineer at Sovcombank • Staff Engineer, iOS Architecture & CI/CD Both are recognised in the Apple community for their technical depth and their years building high-performance iOS applications. Artem also co-hosts the Mobile System Design Interview series on this podcast; Bogdan appeared twice in Season 1 on refactoring and legacy code. Key Takeaways Perceived speed is the metric that matters. Users do not experience your benchmark, they experience the frame that arrived late. SwiftUI moved the cost, it did not remove it. The patterns that feel harmless in a small app are the ones that hurt at scale. Watch the 16.67 ms budget. Knowing what consumes it is more useful than any single optimisation technique. Concurrency is not parallelism. Confusing them leads to fixes that add complexity without adding speed. Instruments is a starting point, not an answer. The hard problems require a mental model of what the framework is doing beneath the abstraction. Resources & Links 🎥 Season 3 Episode 1, Watch on YouTube 🎧 Part 2, Performance is more than just speed 🧩 Mobile System Design Interview, with Artem Listen & Subscribe Part two goes underneath the abstractions, into Swift Concurrency migration, application launch and dependency graphs. 🎥 Watch on YouTube 🎧 Listen on Apple Podcasts ☕ Support the Podcast

July 5, 2026 · 3 min · Walid Sassi

Modern iOS Security: Attacks, Defenses & AI with Dave Poirier and Deya Elkhawaldeh

Swift Academy Podcast, Episode 12, Season 2 Modern iOS Security: Attacks, Defenses & AI Dave Poirier and Deya Elkhawaldeh on iOS security as an engineering culture problem rather than a tooling one, and on what AI has already changed for the people attacking your app. May 31, 2026 🎧 Swift Academy Podcast · Episode 12, Season 2 · Mobile Security • Attacker Mindset • AI Watch the Episode Why This One Matters “Apple handles security for us” is, according to both guests, the single most expensive misconception in iOS development. The platform gives you good defaults. It does not give you a threat model. This is not a conversation about theoretical vulnerabilities or hacker theatre. It is about engineering culture, architecture, and the gap between what developers assume the OS protects and what it actually protects. The uncomfortable part is how small the mistakes are that open the largest attack surfaces. The second half looks at what AI has changed. Work that used to demand deep expertise can now be automated and scaled, which moves the floor for attackers rather than the ceiling. That reframes when security has to enter a project: not before shipping, but on day one. The Conversation How small mistakes become large surfaces The implementation errors that show up again and again in shipped iOS apps What developers assume the device protects, and where that assumption fails Why the responsibility sits with the engineering team, not with a security review at the end Thinking like the attacker How attackers actually choose targets, and why they start with the low-hanging fruit Where jailbreaking stands today, and whether it still deserves the attention it gets What defending an app realistically looks like in 2026 Why a defensive culture beats any individual tool What AI moved How AI-driven tooling accelerates offensive work, and what that does to the economics of an attack The same tooling on the defensive side, and where it genuinely helps How far to trust AI inside a development workflow that has security consequences Which security myths survive, and which best practices actually hold up About the Guests Dave Poirier & Deya Elkhawaldeh iOS security specialists • Runtime protection, application hardening, defensive security Dave Poirier and Deya Elkhawaldeh work on runtime protection, application hardening and defensive security techniques for Apple platforms. Dave is also the co-author, with Walid Sassi, of AI Driven Swift Architecture (Packt), and a recurring voice on the security thread that ran through the first season of this podcast. Key Takeaways The platform is not your threat model. Apple's defaults are good and they are not a substitute for deciding what you are protecting and from whom. Attackers start with the easy wins. Most breaches do not need a sophisticated exploit, they need one careless implementation detail. Culture beats tooling. A team that reasons about security during design will outperform one that buys a scanner and runs it at the end. AI raised the floor for attackers, not the ceiling. Work that once required an expert is now automated, so the volume of competent attacks goes up. Security belongs on day one. Retrofitting it after the architecture is set is where the cost explodes. Resources & Links 🎥 Episode 12, Watch on YouTube 🎧 The Season 1 security series with Dave Poirier 📘 AI Driven Swift Architecture, co-authored with Dave Poirier Listen & Subscribe If your team still treats security as something that happens after the feature is built, this is the episode to send them. 🎥 Watch on YouTube 🎧 Listen on Apple Podcasts ☕ Support the Podcast

May 31, 2026 · 3 min · Walid Sassi

MLX Swift & On-Device AI with Adrien Grondin

Swift Academy Podcast, Episode 11, Season 2 MLX Swift & On-Device AI Adrien Grondin, iOS developer at LM Studio and creator of Locally AI, on why Apple Silicon changes the economics of running language models locally, and where that stops being true. May 17, 2026 🎧 Swift Academy Podcast · Episode 11, Season 2 · MLX Swift • Local LLMs • Apple Silicon Watch the Episode Why This One Matters Most teams shipping AI features today send everything to a cloud API. That works until you look at the bill, the latency, or the privacy review. Meanwhile Apple has been quietly building the other path: a framework designed from the start for unified memory on Apple Silicon. Adrien Grondin is unusually well placed to talk about it. He works on LM Studio and built Locally AI, so he spends his days with models running on hardware people actually own. This conversation is about what that is really like once you leave the demo behind. Where MLX Fits Not Core ML, and not Foundation Models Three Apple-adjacent ways to run a model on device, three different jobs. The distinctions matter the moment you have to pick one. How MLX differs from Core ML, and why the difference is about who owns the training and conversion pipeline Where Apple Foundation Models stop and MLX starts Which model families MLX actually supports, Mistral, Qwen and Gemma among them Fine-tuning with MLX, and when it is worth the trouble The limits nobody puts in the demo The honest part of the episode. Running a model locally is a set of trade-offs, not a free win. Memory constraints on Apple Silicon, and what unified memory buys you GPU usage, battery consumption, and what sustained inference costs a phone Real latency on real devices, not on a plugged-in Mac Studio Device compatibility, and where the floor currently sits Building something with it The practical half: what it takes to put MLX behind a SwiftUI app today. Streaming responses and how inference behaves in a real UI Tool calling with MLX, and what that unlocks Pulling models from Hugging Face, and where quantization fits Why small language models may matter more than the frontier ones for shipping apps About the Guest Adrien Grondin iOS Developer at LM Studio • Creator of Locally AI Adrien moved from traditional iOS development into AI engineering, and now works on LM Studio while maintaining Locally AI. His view, argued in this episode, is that on-device AI is not a passing trend but the direction the Apple platform is heading, and that the developers who understand the constraints early will build the better products. Key Takeaways MLX is not a Core ML replacement. It is a different tool for a different job. Choose based on who owns the model pipeline, not on which is newer. Unified memory is the reason this works at all. Apple Silicon removes the copy between CPU and GPU memory, which is what makes local inference practical on a phone. Memory is the real ceiling, not compute. Model size and quantization decide what ships, long before performance does. Small language models deserve more attention. For most app features, a well-chosen SLM running locally beats a frontier model behind a network call. Test on device, early. Latency and battery behaviour on a real iPhone bear little relation to what you see on a Mac. Resources & Links 🎥 Episode 11, Watch on YouTube 💻 LM Studio 📦 MLX Swift on GitHub 📝 Running an on-device LLM with MLX Swift Listen & Subscribe If you are weighing on-device inference against a cloud API for your next feature, share this with whoever owns that decision. 🎥 Watch on YouTube 🎧 Listen on Apple Podcasts ☕ Support the Podcast

May 17, 2026 · 3 min · Walid Sassi

Beyond the Prompt: Foundation Models as an Architectural Layer in iOS with Mohammad Azam

Swift Academy Podcast, Episode 10, Season 2 Beyond the Prompt: Foundation Models as an Architectural Layer in iOS Mohammad Azam on why Apple’s on-device LLM is less an AI feature and more a redefinition of where intelligence lives in your app, @Generable, @Guide, instructions, tools, and adapter-based fine-tuning, viewed through the lens of iOS layered architecture. May 3, 2026 🎧 Swift Academy Podcast · Episode 10, Season 2 · Foundation Models • On-Device LLM • iOS Architecture “Foundation Models is not a chat surface. It is a typed, on-device, structured capability you wire into your architecture, the way you wire in URLSession or SwiftData. Treat it like a chatbot and you will build bad apps. Treat it like a layer and you will build defensible ones.” Editorial framing of the conversation with Mohammad Azam Watch the Episode About This Episode Mohammad Azam has been writing iOS code since Objective-C 3.2 in 2010. Since then he has led mobile teams, shipped multiple App Store apps, taught iOS bootcamps, and, for the last several years, split his time between Swift and a Python/AI bootcamp. That dual perspective matters. When Apple introduced the Foundation Models framework, Azam was not reacting as someone discovering LLMs; he was reacting as someone who had already built CreateML pipelines, trained models in scikit-learn, and exported them through CoreML tools. The headline of this episode is not that Apple shipped an LLM. It is that Apple shipped an architectural primitive. Foundation Models is not a chat product; it is a typed, on-device, deterministic-ish capability that you wire into your app the way you wire in URLSession or SwiftData. This conversation reframes the framework from that altitude: where on-device intelligence belongs in a layered iOS architecture, why instructions outweigh prompts, how @Generable turns probabilistic text into typed Swift, and what adapter-based fine-tuning means for long-lived products. 📖 The themes of this episode are covered in depth in Chapter 6 of AI-Driven Swift Architecture, which is dedicated to designing production-grade integrations of Apple’s Foundation Models inside a Clean Architecture iOS codebase. An Architectural Deep-Dive into Apple’s Foundation Models Framework AI Is Not a Feature, It Is a Layer The most common failure mode in the current AI moment is the “Ask AI” button. Azam describes it bluntly: tools that used to work with a single click now demand a prompt. The friction is up, the affordance is down, and the user experience is worse. Forcing an LLM into a workflow that did not need one is a product mistake disguised as a technology investment. Foundation Models pushes back on that framing precisely because it is so cheap to invoke, no API key, no per-token cost, no network call. When the marginal cost approaches zero, the right question stops being “can we add AI?” and becomes where does intelligence belong in our architecture? That shift, from feature to layer, is the real paradigm change. The model becomes a service the domain layer can call when its rules genuinely benefit from inference, not a UI surface bolted onto the side of the app. Understanding Apple’s Foundation Models from a Developer Perspective For an iOS engineer with no LLM background, the framework is best described as a heavily structured subset of ChatGPT, running entirely on the Neural Engine, addressable through Swift. There is no inference server, no token billing, no conversation history leaving the device. The model is small, a few billion parameters at best, and ships with the OS. That single sentence contains the entire trade-off matrix: Privacy and offline come for free. Health data, journal entries, and personal contracts never leave the phone. Latency is dominated by the Neural Engine, not by network round-trips, which makes streaming UI viable for most prompts. The capability ceiling is real. The model has no knowledge of last week’s events, will not answer broad world-knowledge questions reliably, and is not competitive with frontier cloud LLMs for open-ended reasoning. Hardware gating is a constraint you must design around. Pre–iPhone 15 Pro devices will not run it at all, so any feature that depends on it needs an explicit non-AI fallback path. Azam’s expectation, which mirrors where the platform is clearly heading, is that the on-device model will eventually be paired with an Apple-hosted private inference tier, a hybrid where the device tries first and escalates only when needed. Architect today for that future: do not let “Foundation Models is here” become “Foundation Models is everywhere in our codebase.” Tools, Instructions, and Determinism: The Real Surface Area of the Framework The part of the framework that deserves the most architectural attention is the one developers tend to skip past: @Generable, @Guide, and instructions. Structured generation is the contract. A @Generable struct is not a convenience, it is the boundary between non-deterministic text generation and deterministic Swift code. The model is constrained to populate the schema; your app receives a typed value. @Guide tightens that contract per-property: a numeric range, a description, a constraint. Done well, the model becomes a function with a typed return value rather than a string firehose you have to parse. Instructions are system design, not prompts. Azam is emphatic on this point: instructions matter more than the prompt itself. The prompt is the request; the instructions define the agent, its role, its tone, its decision boundaries, when it should reach for tools, when it should refuse. In a layered architecture, instructions belong with the service that owns the capability, versioned alongside the schema. Treat them as configuration of a domain service, not as ad-hoc strings near the call site. Tools are controlled escape hatches. A tool is a Swift type the model can invoke, a weather lookup, a database query, an HTTP client. Conceptually it is the same idea as MCP, scoped to a single app: a typed interface that lets the model reach beyond its training data without losing the structured-output guarantee. The interesting design decision is not whether to expose a tool; it is how narrowly to scope it. Azam’s recipe-app example is instructive: a tool that fires only when rice is among the ingredients, deferring to a curated rice-dish API rather than the model’s general knowledge. That kind of fine-grained gating is where instruction quality and tool design meet. Integrating Foundation Models into iOS Layered Architecture The framework is well-behaved precisely because it does not push itself onto your architecture. It slots into the data and service layer like any other capability. Generables are DTOs. The model is a service. Your domain types remain the source of truth. The boundary that matters is persistence. A @Generable struct cannot wear @Model, it is not a SwiftData entity, and conflating the two is a category error. If a generated recipe needs to survive past the session, your service layer maps the generable into a SwiftData model and persists that. If the output is ephemeral, a one-shot summary, a transient suggestion, a view can consume the generable directly. The rule is the same as with any DTO/entity split: do not let an external schema bleed into your storage layer. This is also why the framework composes cleanly with existing apps. Adding Foundation Models to a Clean-ish architecture does not force a rewrite. It adds a new service implementation. The view models do not change shape; the domain does not learn about Apple Intelligence; the persistence layer keeps owning its types. If introducing the framework is invasive in your codebase, the framework is not the problem, your layering is. Models That Evolve: Adapter-Based Fine-Tuning The piece that gets less airtime than @Generable but matters more for long-lived products is adapters. Apple exposes an adapter-based fine-tuning path: you take the shipped foundation model and train a small delta on your own data, rental agreements, medical claim formats, your particular domain vocabulary. The base model stays Apple’s; the specialization is yours. The architectural implication is significant. Adapters give you a knob between “general-purpose model” and “model that understands my product,” without operating an inference cluster and without your data leaving the device. They also introduce a new kind of artifact in your release pipeline: an adapter is versioned, tested, and shipped alongside your binary. Teams that take Foundation Models seriously will end up with a model-evaluation workflow next to their unit tests, regression suites for generables, golden outputs for instruction changes, drift detection between adapter versions. That is a maturity step many iOS teams have not taken yet. Real-World Patterns from the Episode Strip the demos down to their architectural shape and a small set of reusable patterns emerges: Constrained recommendation. The Yummy recipe demo, Azam’s gardening app, both are the same pattern: user supplies a constrained input set, the model returns a @Generable list scoped by @Guide ranges, the view streams it. Use this whenever the answer space is open-ended but the shape of the answer is fixed. On-device summarization over private data. Health metrics, journal entries, transaction history. Cloud LLMs are non-starters here for compliance reasons; on-device LLMs are not. The pattern: summarize locally, persist the summary, surface in widgets or live activities. Structured matching against a user document. The resume vs. job description example. Two unstructured inputs, one structured diff out. This generalizes to contract review, code review, spec compliance, anywhere the value is in structured comparison rather than free-form prose. Tool-routed inference. The rice-recipe escape hatch. The model handles the general case; a tool handles the specific case where you have authoritative data. Use this whenever your product has curated content the model should not try to reinvent. Glanceable AI on wearables. Live Activities and widgets are a natural fit because Foundation Models’ latency is low and its outputs are short. A run summary, a hydration nudge, a weather-aware recommendation, all viable without ever lighting up the network. The common thread: every good use case has a clear input shape, a clear output schema, and a fallback for devices and contexts where the model cannot run. Vibe Coding, Domain Knowledge, and the Limits of LLM-Generated Architecture The conversation closes on a point that is easy to dismiss as a generic AI critique but is in fact an architectural observation. Azam ships several “vibe-coded” small apps and is candid that he could not point at any line in them and explain it. For single-purpose utilities and throwaway tools, that is acceptable. For anything that lives inside a meaningful domain, finance, healthcare, anything with regulatory weight, it is not. The reason is not that LLMs write bad functions. They write fine functions. The reason is that architecture is not a function-level concern. Where a calculation belongs, how a domain rule should be expressed, what should and should not be coupled, these are decisions that require understanding the business, and understanding the business is precisely what gets skipped when you outsource the code. Use LLMs as an accelerator for the parts you understand; do not let them become the reason you stopped understanding. Resources & Links 🌐 Mohammad Azam, Personal Website (azamsharp.com) 💼 Mohammad Azam, LinkedIn 🎥 Episode 10, Watch on YouTube About the Guest Mohammad Azam Senior iOS Engineer • Educator • Author Mohammad Azam has been working in the Apple ecosystem since 2010, starting with Objective-C and moving through every major shift in the platform since. He has led mobile teams at large organizations, taught iOS, web, and AI/ML bootcamps, and authored extensive course material on Udemy and his own platform on SwiftUI, UIKit, iOS architecture, and most recently Foundation Models. He is the developer behind My Veggie Garden, a gardening app on the App Store that uses Apple’s on-device LLM to recommend plantings based on location, weather, and USDA hardness zone, a concrete example of the architectural patterns discussed in this episode. His perspective on Foundation Models is informed by years of pre-LLM machine-learning work with CreateML, CoreML, scikit-learn, and Pandas, which gives his commentary on the framework an unusually grounded shape. Go Deeper, Chapter 6 of AI-Driven Swift Architecture If the framing of this episode resonates, treating Foundation Models as a typed capability inside a layered architecture rather than as a UI feature, the natural next step is Chapter 6 of AI-Driven Swift Architecture, which is dedicated entirely to Apple’s on-device LLM stack. The chapter takes the patterns discussed here and turns them into production-grade scaffolding: how to design @Generable schemas as service contracts, how to version and test instructions alongside the rest of your domain code, how to scope tool boundaries narrowly, where Foundation Models sits in a Clean Architecture module graph, and how to plan adapter-based fine-tuning as a first-class artifact in your release pipeline. It is the architectural reference companion to the conversation you just watched. The book itself (530 pages, published by Packt, foreword by Jon Reid) covers the broader picture: Swift 6 concurrency, Clean Architecture for iOS, AI-assisted development with Claude Code, MCP integration, and the engineering practices that make AI-augmented Swift codebases maintainable rather than brittle. 📖 Learn More, AI-Driven Swift Architecture 📚 Buy on Packt 🛒 Get It on Amazon Key Takeaways Foundation Models is an architectural layer, not a UI feature. Place it in your service tier, not your views. @Generable is the contract between probabilistic text and typed Swift. Design schemas as carefully as you would design API responses. Instructions outweigh prompts. Version them, test them, treat them as configuration of a service. Tools are how you keep the model from making things up about your domain. Scope them narrowly. Generables are DTOs, not entities. Map to SwiftData explicitly when you need persistence. Plan for hardware gating from day one. A feature that requires Foundation Models needs a non-AI alternate path. Adapters are how the model becomes yours. Treat them as shippable artifacts with their own evaluation pipeline. Do not add AI because it is available. Add it where the architecture genuinely benefits. The Real Shift The shift Apple is making with Foundation Models is quieter than the cloud-LLM narrative but more consequential for the people who build apps. Intelligence becomes a typed, local, composable capability, something you architect with, not something you bolt on. The teams that will get the most out of it are not the ones racing to ship a chat surface; they are the ones rethinking which parts of their domain logic could be expressed as a constrained generation, which workflows could be summarized on-device, where a tool boundary belongs. That is the right altitude for this conversation. Not how do I prompt it? but where does it live in my system? Foundation Models rewards architectural thinking and punishes experimentation-as-strategy. Treat it accordingly. Listen & Subscribe If this episode changed how you think about on-device AI and the place of Foundation Models in iOS architecture, share it with a colleague building in the Apple ecosystem, particularly anyone exploring SwiftUI, layered architecture, or the practical side of Apple Intelligence integration. Subscribe to the Swift Academy podcast for weekly deep-dives into iOS development, Swift engineering, and the craft of building software on Apple platforms. 🎥 Watch on YouTube 🎧 Listen on Apple Podcasts ☕ Support the Podcast

May 3, 2026 · 12 min · Walid Sassi

Cupertino MCP: Local AI Tooling for Swift and iOS Development with Mihaela Mihaljević

Swift Academy Podcast, Episode 9, Season 2 Cupertino MCP: Local AI Tooling for Swift Developers How the Cupertino MCP server gives AI agents offline access to 302,000+ pages across 307 frameworks, a technical deep-dive into Model Context Protocol, local-first Swift AI development tooling, and the architecture behind a new generation of AI iOS development tools with Mihaela Mihaljević, Senior iOS Architect. April 19, 2026 🎧 Swift Academy Podcast · Episode 9, Season 2 · Model Context Protocol • Swift AI • Local Tooling “Giving an AI agent access to your full Apple documentation stack, offline, locally, without rate limits, is not a convenience. It changes the quality of what the agent can reason about. That’s the real unlock of local-first AI tooling.” Mihaela Mihaljević, Senior iOS Architect Watch the Episode About This Episode AI is reshaping how software gets built, but most AI-powered developer tools are only as good as the context they can access. For Swift AI development, that context is Apple’s documentation: hundreds of frameworks, tens of thousands of APIs, platform-specific behaviors. When an AI agent cannot reach that documentation reliably, its suggestions become generic. When it can, the quality of the assistance changes fundamentally. This episode explores exactly that problem and a concrete, technical solution to it. We are joined by Mihaela Mihaljević, a Senior iOS Architect and developer focused on building AI-powered tools for the Apple ecosystem. She is the author of Cupertino, a local MCP server (built on the Model Context Protocol) that gives AI agents offline access to 302,000+ pages across 307 frameworks, without a network call, without rate limits, and without sending your codebase to a remote API. We cover the mechanics of how MCP works in practice, how client-server communication is structured in the protocol, and why local-first AI tooling is not just a privacy choice but a capability choice. Mihaela walks through the architecture behind Cupertino, shares a live practical session, and discusses what is next for AI-assisted development in Swift. If you are building with AI agents, working on Swift developer AI tools, or thinking about the future of the Apple developer experience, this is the episode to watch. A Technical Deep-Dive into MCP and AI-Powered Swift Tooling What Is the Model Context Protocol and Why Does It Matter for Swift AI Development? The Model Context Protocol (MCP) is an open standard that defines how AI agents communicate with external tools and data sources. Think of it as a structured contract between a language model client (your AI coding assistant) and a server that exposes capabilities: documentation lookup, code search, build system introspection, or anything else a developer agent might need. Before MCP, integrating an AI assistant with real development context required bespoke, fragile glue code. Every tool had its own API, its own authentication model, its own response format. The Model Context Protocol standardizes that surface: a conforming client can talk to any conforming server using the same wire protocol, and a server built for one client works with any other. That composability is what makes MCP worth paying attention to as a foundational layer for Swift developer AI tools. The protocol design: how MCP structures capability discovery, tool invocation, and response handling between client and server Why a standardized protocol matters more than any individual tool, and how it enables an ecosystem of composable AI iOS development tools The difference between MCP and raw API calls to a language model: context is structured, not embedded in a prompt How MCP positions itself relative to other agent frameworks and why the local-first deployment model is architecturally significant Cupertino: An MCP Server Built for the Apple Ecosystem Cupertino MCP is a local MCP server purpose-built for Apple platform development. Its core function is straightforward but powerful: index Apple’s developer documentation, 302,000+ pages across 307 frameworks spanning iOS, macOS, visionOS, watchOS, and Swift, and expose that index as a set of structured tools that any MCP-compatible AI agent can query. The result is an AI coding assistant that can answer questions about SwiftUI layout behavior, Swift Concurrency APIs, StoreKit edge cases, or any other Apple platform topic with the precision of someone who has read the documentation. Because the agent has read it, locally, without any network dependency. What the Cupertino index contains: the scope of Apple documentation covered, the framework coverage, and how the documentation is structured for agent consumption How Cupertino exposes search, symbol lookup, framework listing, and documentation retrieval as discrete MCP tools The offline-first design: why running the MCP server locally eliminates latency, rate limits, and data-sharing concerns How a developer configures and connects Cupertino to an MCP-compatible client in their existing workflow Beyond MCP: Cupertino as a Standalone CLI Tool Although Cupertino is designed primarily as an MCP server, the same binary exposes a standalone CLI. Commands like cupertino search "NavigationStack", cupertino list-frameworks, and cupertino list-samples return structured JSON output directly to the terminal, which makes Cupertino useful even for developers who do not run an AI agent: fast offline Apple documentation search, scriptable framework discovery, and sample code lookup from the command line. MCP Client-Server Architecture: How the Protocol Works in Practice Understanding how Model Context Protocol works at the wire level is essential for anyone building or integrating AI iOS development tools. MCP separates concerns cleanly: the client (your AI agent or IDE extension) is responsible for orchestrating tasks and interpreting results; the server (Cupertino, in this case) is responsible for exposing capabilities and returning structured data. Neither side needs to know the implementation details of the other. Mihaela walks through this communication model concretely, showing how an agent discovers available tools, forms a request, and processes a structured response. That transparency is one of MCP’s strongest properties: the protocol is inspectable, debuggable, and easy to reason about compared to opaque API integrations. The capability handshake: how an MCP client discovers what tools a server exposes and their input/output schemas The request-response cycle: how tool invocations are structured, dispatched, and returned across the protocol boundary Error handling and graceful degradation: what happens when a tool call fails and how agents are expected to recover Streaming responses: how MCP supports progressive results for tools that return large or incremental data sets Security boundaries: what an MCP server Swift implementation controls and what it deliberately does not expose Local-First AI Tooling: A Capability Argument, Not Just a Privacy Argument The default assumption about local AI tooling is that it is a compromise: you choose it when you cannot or will not send data to a remote service. Mihaela inverts that framing. Local-first is often the architecturally superior choice for developer tooling, independent of privacy concerns. A local MCP server can index your proprietary codebases, your internal documentation, and your team’s accumulated knowledge, content that no cloud service can access. It responds at filesystem speeds. It does not fail when your internet connection drops during a live coding session. And it gives you full control over what the agent sees, enabling a level of precision that generic cloud-hosted context cannot match. Why latency matters for AI agent loops: the practical impact of local versus remote documentation lookups in an agentic workflow Extending Cupertino with private content: how the local-first model enables indexing of internal documentation alongside Apple’s public docs The composability advantage: combining multiple local MCP servers (documentation, codebase index, build system) into a unified agent context What “offline access to Apple documentation AI” enables that a web-scraped prompt cannot: structure, precision, and completeness Architecture Behind Cupertino: Swift Server, OpenAPI, and Modular Design Cupertino is not just a documentation wrapper. It is a production-quality Swift server application, and its architecture reflects Mihaela’s broader engineering philosophy: type-safe APIs, modular structure, and Swift concurrency architecture for thread-safe system design. The server backend leverages Swift’s server ecosystem, using OpenAPI-driven development to generate type-safe client and server interfaces from a single specification. The modular architecture separates indexing, search, protocol handling, and tool dispatch into distinct layers, making each independently testable and replaceable. The technology stack: Swift server backend, OpenAPI code generation, and the MCP protocol layer How Swift concurrency architecture is applied in Cupertino to handle concurrent documentation queries safely and efficiently The indexing pipeline: how Apple documentation is parsed, structured, and stored for low-latency agent queries Modular architecture decisions: why Cupertino separates protocol concerns from domain logic, and what that enables for extensibility The Swift Concurrency patterns used to handle agent request concurrency without introducing data races Live Practical Session: AI Agents Querying Apple Documentation One of the most valuable parts of this episode is Mihaela’s live demonstration of Cupertino in action. Watching an AI agent query a local MCP server for SwiftUI API details, resolve framework-specific behaviors, and return structured, citation-grounded answers is a concrete illustration of why this approach to Swift AI development is qualitatively different from asking a general-purpose model to recall what it knows about Apple APIs. The demo setup: how Cupertino is connected to an MCP client and what the agent sees as available tools A live query walkthrough: from agent prompt to MCP tool invocation to structured documentation response How the agent uses Cupertino’s framework search and symbol lookup tools to navigate across documentation sections The difference in answer quality between a general model and a model augmented with precise, local Apple documentation AI access What Is Next for AI Agents in iOS Development Cupertino is a foundation, not a finished product. Mihaela discusses the evolution of the project: expanding framework coverage, improving the search and ranking algorithms, and exploring how AI agents for iOS can move beyond documentation lookup toward active participation in the development workflow. The broader question this episode raises is about the trajectory of Swift developer AI tools over the next few years. The combination of a standardized protocol like MCP, a rich local documentation corpus, and Swift’s growing server and agent ecosystem points toward a near-term future where AI assistance in Xcode is not a chat window but a first-class, context-aware collaborator. Planned expansions to the Cupertino documentation index: additional frameworks, sample code, and WWDC session transcripts How the Cupertino map, the structured knowledge graph of Apple frameworks, is evolving The path from documentation access to active agent participation: code generation, API migration, and deprecation detection What the AI iOS development tools landscape looks like in two to three years, and where the highest-leverage opportunities are for Swift developers building in this space Resources & Links 📦 Cupertino MCP, GitHub Repository 🌐 Mihaela Mihaljević, Personal Website 💼 Mihaela Mihaljević, LinkedIn 🎥 Episode 9, Watch on YouTube About the Guest Mihaela Mihaljević Senior iOS Architect • AI Developer Tooling • Swift Server Engineer Mihaela Mihaljević is a Senior iOS Architect and developer focused on building AI-powered developer tools for the Apple ecosystem. She works across the full stack, from iOS and macOS applications to Swift server backends, with a strong emphasis on enabling AI agents to interact meaningfully with real development environments. Her areas of expertise span AI developer tooling (MCP servers, agent orchestration, documentation access), Apple ecosystem development (iOS, macOS, visionOS, Swift server), OpenAPI-driven development with type-safe Swift clients and servers, modular architectures for scalable Swift projects, and Swift Concurrency and thread-safe system design. Cupertino is her most visible contribution to the Swift AI development ecosystem: an open-source, local MCP server that gives AI agents structured offline access to Apple’s developer documentation and the broader Swift documentation corpus. Go Deeper: AI-Driven Swift Architecture This episode sits at the intersection of two fast-moving fields: AI agent tooling and Swift architecture. If you want to move from understanding these concepts to applying them in production, structuring Swift projects that are ready for AI-assisted workflows, integrating agent tooling cleanly into your architecture, and reasoning about the design trade-offs that Swift AI development introduces, the book AI-Driven Swift Architecture is the natural next step. It covers the architectural foundations you need to build maintainable, testable Swift codebases that work with AI agents rather than around them: clean module boundaries, type-safe API layers, concurrency patterns for agent integration, and the mental models that separate robust AI-augmented systems from brittle ones. 📖 Learn More, AI-Driven Swift Architecture 🛒 Get It on Amazon Key Takeaway The most important thing this episode makes concrete is that AI iOS development tools are not a monolith. The quality of AI assistance in a developer workflow is a direct function of the quality of the context the agent can access. Cupertino MCP is a precise, local, structured answer to the question of how to give an AI agent genuine competence with Apple platform APIs: not broad familiarity, but the kind of depth that comes from having 302,000+ pages across 307 frameworks available at query time. The Model Context Protocol as an infrastructure layer, and Cupertino as an implementation of that layer for the Apple ecosystem, represent a pattern worth studying: take the domain your agents need to reason about, index it precisely, and expose it through a standardized protocol. That approach scales to proprietary codebases, internal documentation, and any other context that general-purpose models cannot access. It is how Swift developer AI tools move from impressive demos to reliable engineering tools. Listen & Subscribe If this episode changed how you think about local AI tooling and the possibilities for Swift AI development, share it with a colleague building in the Apple ecosystem, particularly anyone exploring AI agents, developer tooling, or the practical side of Model Context Protocol integration. Subscribe to the Swift Academy podcast for weekly deep-dives into iOS development, Swift engineering, and the craft of building software on Apple platforms. 🎥 Watch on YouTube 🎧 Listen on Apple Podcasts ☕ Support the Podcast

April 19, 2026 · 11 min · Walid Sassi