00:19:34
As SwiftUI matures, development patterns that worked in its early days are increasingly proving inefficient. New approaches to architecture, testing, and feature implementation are emerging while foundational concepts are evolving. Here's an analysis of what's changing and how to adapt your iOS development practices.
MVVM served as a natural transition pattern when SwiftUI launched, helping UIKit developers adapt their mental model to the new declarative framework. However, Thomas Ricard (developer behind Icy Sky and the Medium iOS app) argues that MVVM is increasingly mismatched with SwiftUI's modern data flow and architecture.
The core issue is that MVVM introduces unnecessary complexity. SwiftUI views are designed as lightweight, disposable structs—not classes—yet view models often create a one-to-one relationship with each view, introducing bloat and additional objects that must be kept in sync.
Pure State Expressions
Keep views small and focused as pure state expressions rather than splitting logic between view and view model.
Environment Injection
Use environment objects for services (networking, authentication, routing) rather than manual dependency injection through view models. All views can access these globally without complex setup.
In-View Logic
Small, focused functions that change state can live directly on the view itself rather than being outsourced to view models.
Testing Consideration:
Rather than testing views (which should be so simple that bugs are immediately visible), focus on testing your business logic, network clients, and data models—all of which exist independently from the UI layer in this approach.
Projects like Icy Sky (Mastodon client) and Medium's Swift UI implementation demonstrate this pattern working effectively for complex applications—not just simple demo apps. The core principle: trust SwiftUI's powerful primitives (state, environment, observable, binding) rather than forcing patterns designed for a different framework.
Apple has introduced a pre-release retention messaging API that gives developers control over the subscription cancellation flow—a moment previously beyond developer influence. After requesting early access, developers can now customize what users see when attempting to cancel subscriptions.
Highlight lost benefits ("You'll lose your 42-day streak") to create emotional impact at cancellation point.
Visual reinforcement of value proposition with compelling imagery that aligns with brand identity.
"Save 23% by switching to annual billing" with direct conversion path within the cancellation flow.
"Three months free at $4.99/month" with immediate redemption—turning potential churn into renewed engagement.
While not yet broadly available, this API represents a critical opportunity for reducing churn. Even a 1% reduction in cancellations could translate to significant revenue impact for applications with large subscriber bases. Early access should be prioritized as this feature becomes available.
Selecting between VStack, LazyVStack, and List impacts performance significantly—especially for scrolling interfaces. The wrong choice creates unnecessary memory load and UI jank.
VStack
Loads all child views immediately. Avoid for lists with more than 5-10 items as performance degrades rapidly with larger datasets.
LazyVStack
Only loads visible views and a small buffer. Ideal when you need custom scrolling behavior or specific animations not available in List. Combine with ScrollView for full control.
List
Use when you need standard iOS list behavior—built-in swipe to delete, navigation chevrons, and platform-adaptive presentation (Mac, iOS, watchOS, visionOS).
Practical Recommendation:
For standard settings-like interfaces, use List. For custom scroll behaviors, immersive experiences, or when you need complete control over rendering, LazyVStack within a ScrollView delivers the best results without performance overhead.
Effective data visualization requires thoughtful design to communicate information clearly while maintaining aesthetic appeal. Rather than defaulting to standard chart libraries, consider these approaches:
The key isn't copying designs exactly but understanding the principles behind effective data presentation. Consider context: a fitness app's dashboard needs different visualization strategies than a financial tracking tool. Study these patterns to understand how shape, color, and hierarchy influence data comprehension.
Ivan Campos' Foundation Models playground collection offers 140 practical implementation ideas—not for complex code, but for strategic application. The real value lies in the conceptual approaches rather than technical complexity.
The implementation pattern is relatively consistent: create a language model session, define context and prompt parameters, then process the response. The strategic value comes from identifying where these capabilities solve genuine user problems rather than adding AI for its own sake. Consider both standalone apps built around specific Foundation Model capabilities and targeted integrations within existing applications.
"Vibe coding"—relying heavily on AI to generate code without deep engagement with problem-solving—is eroding critical development skills, particularly for early-career developers. This isn't about AI's usefulness; it's about how we integrate these tools without sacrificing essential growth.
Domain Expertise Erosion
Technical skills can be replicated, but deep business understanding—the knowledge of edge cases, workflows, and organizational history—cannot. AI generates generic code; human developers with domain expertise create solutions that address real business needs. Without cultivating this knowledge, developers become replaceable for increasingly routine tasks.
Stalled Growth Through Disengagement
Solving mundane problems builds foundational skills. When developers consistently offload these challenges to AI, they miss opportunities to develop pattern recognition, debugging intuition, and system-level understanding. Seasoned developers may maintain competence despite some skill atrophy, but early-career developers risk becoming permanently junior-level without these essential building blocks.
Strategic Approach:
Use AI for productivity boost and learning new techniques, but engage deeply with problems that stretch your understanding. Prioritize critical thinking for business logic and architecture decisions, not just the "boring" implementation details. Set boundaries for when AI assists versus when you solve problems yourself.
Jordan Morgan (creator of Elite Hoops and Spend Stack) presents a sustainable model for indie developers: maintaining two distinct types of applications with different purposes and development philosophies.
Business App (Elite Hoops)
Boutique App (Alex Caffeine Tracker)
This approach creates balance: the business app generates sustainable income without constant pressure to implement flashy but non-revenue-generating features, while the boutique app satisfies the developer's creative impulses and keeps skills current with the latest platform capabilities. For indie developers, separating these concerns prevents the common pitfall of chasing new technologies in the primary revenue-generating app at the expense of business growth.