AI sceptic in LLM adventure land
I have been calling and treating AI/LLM tools as bullshit generators. It helps to test your own assumptions from time to time, head-first.
Ever since ChatGPT and its gen-AI ilk arrived, I have been very vocal and adamant that these are bullshit generators: they try to guess what you want and will continually hallucinate things until you say it’s OK. Depending on the body of existing knowledge they were trained on, they’ve becoming ever more successful in that endeavour. In the span of just few years and after countless energy spent on their development and training, those tools have become quite capable delivering amazing, believable results in certain areas.
I have deeply ingrained disdain of someone’s creativity being blatantly ripped off thus countless Studio Ghibli-like image generators make me sick. What I want people to do — what I consider useful and pragmatic use of time and engineering prowess — is building tools that help me create something new, tools that help me automate boring & tedious. To paraphrase an old tweet (I sadly long lost the link to it):
I don’t want AI that copies existing work of art. I want the AI that clean my dishes and iron my clothes so I can spend my time imagining new work of art.
I am an app developer. In my line of work, knowledge how to craft good Swift code and how to use iOS frameworks is (sometimes, not always) the tedious part of the job. Learning, testing, trying, reading documentation, trying, testing, reading more docs…rinse and repeat.
The final output, the app experience presented to people, that is the creation.
In the last several months, I have seen quite a few effusive posts from peers I respect about various AI/LLM tools in day to day work. People I personally know and those I know from Mastodon and general Apple-related blogs, conferences and podcasts. I don’t know will I ever be ready to live dangerously as Peter did but his gushing posts about usage of Claude Code and Gemini tipped me over to try it out.
I prepared. I read suggestions and recommendations from Peter, Philipp, Atharva, Rob, Thomas, I watched few presentations from Anthropic people.
Thus I installed NodeJS, installed Claude Code and paid $5 in credits to test the waters.
First thing Anthropic recommends to do is just ask Claude to analyze the existing project and tell you what it finds. It will use this analysis to create CLAUDE.md in project root and use it as initial context.
❶ Start by initializing Claude in the current folder
/init
and it goes chugging along. After few minutes, this was the result (slightly redacted by me):
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Development Commands
### Building and Running
- **Build**: Use Xcode (`⌘+B`) or `xcodebuild -scheme THE-APP-scheme -project THE-APP.xcodeproj build`
- **Run**: Use Xcode (`⌘+R`) or run from simulator
- **Target**: The app target is named "THE-APP" (internal name) but the scheme is "THE-APP-scheme"
### Testing
- No test files are currently present in the project
- Tests would typically be run via Xcode (`⌘+U`) or `xcodebuild test`
## Architecture Overview
### App Structure
This is a **SwiftUI-based iOS health and fitness app** with the following architectural layers:
1. **App Entry Point**: `THE-APPApp.swift` - Main app struct with dependency injection setup
2. **Navigation Flow**: `RootView.swift` → `AppState` manages flows (splash → onboarding → main app)
3. **Main Features**: Home tab, Progress tab, Settings tab, Store tab (Shopify integration)
### Key Architecture Patterns
**Observable Pattern**: The app uses Swift's `@Observable` macro extensively for state management:
- `DataStorage` - Central data store for model types
- `HealthKitService` - Manages HealthKit integration and background processing
- `AppState` - Handles app navigation flow states
- `ShopifyStore` - Manages e-commerce product data
**Dependency Injection**: Dependencies are injected through SwiftUI's environment system:
- `AppService` - API service layer (protocol with HTTP implementation)
- `DataStorage` - Observable data layer
- `HealthKitService` - Health data integration
- `PushNotificationService` - Firebase messaging
### Core Domains
**Health Data Integration**:
- `HealthKitService.swift` - HealthKit read/write operations
- `THE-APPHealthKit` package - Local SPM package for health data extraction
- Background processing tasks for health data sync
- Local notifications for workout detection
**Data Models** (in `Domain/`):
- [...redacted...] - Core domain events
- [...redacted...] - User interaction models
- DTOs in `NetworkEncoding/` for API communication
**UI Structure**:
- `UI/Main/` - Tab-based main interface (Home, Progress, Settings)
- `UI/Onboarding/` - User onboarding flow with coordinator pattern
- `UI/Components/` - Reusable SwiftUI components (cards, pickers, camera)
### External Dependencies
**Local Packages**:
- `THE-APPHealthKit` - Custom HealthKit wrapper
- `THE-APPMacros` - Swift macros for code generation
**Third-Party Libraries**:
- **Firebase**: Auth, Analytics, Crashlytics, Messaging (push notifications)
- **Shopify Mobile Buy SDK**: E-commerce integration
- **Pulse + Sentinel**: Network debugging and developer tools
- **Nuke/NukeUI**: Image loading and caching
- **SlidingRuler**: Custom UI component for weight/height selection
### Key Services
**Network Layer**:
- `HttpAppService` - Main API client with authorized requests
- `AuthorizedHttpClient` - Firebase token-based authentication
- Base URL configurable in `EnvironmentConfiguration`
**Background Processing**:
- Background app refresh for HealthKit sync
- Background processing tasks registered in Info.plist
- Local notifications for new event detection
### Configuration Notes
- **Bundle ID**: App uses `$(PRODUCT_BUNDLE_IDENTIFIER)` placeholder
- **Entitlements**: HealthKit, Background App Refresh, Push Notifications
- **Privacy**: Camera, Photo Library, HealthKit usage descriptions in Info.plist
- **Firebase**: Configured via `GoogleService-Info.plist`
### Development Notes
- Uses iOS 17+ minimum deployment target
- SwiftUI with iOS-only target (no watchOS/macOS)
- Supports both iPhone and iPad orientations
- Uses Firebase for backend services and Shopify for commerce
This floored me. 🤯
It is objectively good analysis, which cost me ~30 cents in API credits.
Think about onboarding new developers to the team and having to explain the structure of the project. Instead, you could just place them at the claude >
prompt and let them ask whatever they want about the project, its structure, specific modules and files.
❷ Next, I wanted to see what code it can generate.
I had a product details screen in the Store tab that I barely started with. ShopifyStore.swift
(@Observable
data store file) fetches minimal set of product attributes through GraphQL that Shopify’s Buy SDK uses and SwiftUI displays the data. This project was my first time using GraphQL thus I had just proof of concept that read product’s id
, title
, price
and featured_image
.
I prompted with
look into ProductDetails.swift and plan improvements to show multiple images in horizontal scroller and full product description
I did not save the actual output it gave me here but it was the most elaborate and detailed plan I have seen in my professional career. A screen and a half of step-by-step changes in several files it thinks it should do, including implementing local cache for the loaded product instances.
Thus the next prompt:
sounds good. now implement it.
It added necessary nodes in the GraphQL query, implemented caching in ShopifyStore file, wrote almost perfect SwiftUI with horizontal scroller using TabView with page control dots below. It wrote internal description view and added read more button to it if the text was longer than 500 chars, using @State
and @Binding
as it should. It also updated Storefront.Product
dummy init in #Preview
.
Outside of few minor stylistic code style finesse, this was utterly perfect.
❸ I originally had product price fixed in bottom right corner and for some reason Claude rewrote that to be inline, above the product description. So
make the product-price view to be fixed and slightly inset from bottom right screen edge, so it stays visible as content is scrolled
It implemented the requested changes and wrote this report:
👏🏻 The code compiled and was pretty much perfect.
❹ OK, now was the time for real test. Since I had product listing and details working, I needed cart / checkout / payment.
This is serious task.
It starts with simple UI code to add cart toolbar item but then also need add/remove/clear/pay cart management methods, decide where to keep the Cart instance, how to model it + write entire Cart UI from scratch to use all that data and functionality. As developer, you need to read Shopify docs, understand what you need to build cart / cart items, what to call to continue with payout.
My prompt:
create Cart View in Store tab. add toolbar item to access cart. Use Shopify Buy SDK to make the cart, add/remove items to it, include basic management functionality, prepare payment checkout.
Note that that I did not tell it exact cart management functionality to implement as I wanted to see what it would do.
The output here was far from ideal. UI part of the task was really good, I did not see any problematic SwiftUI code. It chose 22pt body-font tall SFSymbol item for cart which was too large but other than that, all was fine.
It modeled CartItem
on its own, using productVariantId
as its id
which is fine.
All the add/remove/clear stuff was good. It added +
/−
to adjust quantities, summary and total price calculations and button to Pay.
It placed transient cart instances in the ShopifyStore and used Observable framework in the View to access it.
But then completely borked by writing the code that uses Storefront.Checkout
model type which does not exists. Buy V3 SDK uses Cart
, not Checkout
, not sure if Checkout
exists in V2. Hence 20+ compilation errors across everything it generated.
this code is not good, there is no Checkout type in Buy SDK, you should use Cart. look up this URL as docs: https://github.com/Shopify/mobile-buy-sdk-ios
It asked for permission to access that URL and went to correct its mistakes. This time it used all the correct types. It also adjusted GraphQL product fetching queries to load product variant nodes and populate the CartItem it wrote.
There were still issues though: the GraphQL handling code is horrible closure in closure in closure in… mess. This confused it pretty much and it took several prompts to fix almost all of it where I would prompt it with:
these code lines {pasted code directly} yield this error: {paste compiler err}
One by one, this was slowly resolved and one particularly nasty bit I fixed by hand.
There was several deprecation warnings which it did not manage to resolve so I manually did those too. Eventually it all compiled and worked perfectly. Products were added to cart, called correct API to generate payment checkout URL which lead to typical Shopify payment screen you have probably seen online.
Somewhere near the end of this whole back and forth I was close to zeroing out the initial $5 worth of credits. But it was enough to convince me that this is worthwhile tool to pay for. Despite errors and shortcomings, it confirmed what many have wrote: this is an amplifier. You need to know the domain in order to validate what it did and guide it towards good result. But it speeds things up immensely and does away quite a lot with the tedious parts of the work I do.
I have never been happier to pay $200/month subscription for anything.
p.s. I also used Claude to build me proper blog archives on this very blog. This is based on Hugo generator where I never had time to read the docs and figure out proper incantations to create archives per year. It did that perfectly, with very little input from me. I was just describing what I need and gave it a link to Hugo docs. It also found a source of the annoying problem when archives/index.html
would display Jackyll code. I mean…seriously — get this tool.