Tworzenie aplikacji iOS z wykorzystaniem agentów AI: przewodnik praktyka
# Szybsze tworzenie aplikacji iOS z agentami AI. Claude Code, Codex CLI, natywne funkcje Xcode 26.3, MCP, wzorce CLAUDE.md, hooki, wnioski z 8 aplikacji.
TL;DR: Trzy środowiska uruchomieniowe agentów potrafią dziś tworzyć kod dla iOS: Claude Code CLI z MCP, Codex CLI z MCP oraz natywne agenty Intelligence w Xcode 26.3. Dwa serwery MCP (XcodeBuildMCP z 59 narzędziami oraz apple’owy
xcrun mcpbridgez 20 narzędziami) dają agentom ustrukturyzowany dostęp do buildów, testów, symulatorów i debugowania. Ten przewodnik omawia rzeczywiste wzorce CLAUDE.md, konfiguracje hooków oraz uczciwe oceny tego, co działa, a co się psuje — na podstawie 8 produkcyjnych aplikacji iOS obejmujących łącznie 293 pliki Swift.17 Agenty świetnie radzą sobie z widokami SwiftUI, modelami SwiftData, refaktoryzacją i diagnozowaniem błędów builda. Zawodzą przy modyfikacjach .pbxproj, podpisywaniu kodu i debugowaniu wizualnym. Lukę między „agent pisze Swift” a „agent wydaje aplikację iOS” zamyka konfiguracja, nie promptowanie.
Zbudowałem 8 aplikacji iOS z użyciem agentów kodujących AI. Nie prototypów — aplikacji w App Store, z integracjami HealthKit, shaderami Metal, fizyką SpriteKit, synchronizacją iCloud, Live Activities, rankingami Game Center oraz wieloplatformowymi targetami obejmującymi iOS, watchOS i tvOS. Każda linia Swift w tych aplikacjach została albo napisana przez agenta i przejrzana przeze mnie, albo napisana przeze mnie i zrefaktoryzowana przez agenta. Według moich szacunków agenty wykonały większość autorstwa na poziomie linii kodu; ja odpowiadałem za review, zakres oraz części wymagające ludzkiej oceny (wizualne dopracowanie, podpisywanie, strojenie wydajności, zgłoszenie do App Store).
Ten przewodnik jest punktem odniesienia, którego brakowało mi na początku. Obejmuje pełny stos: którego środowiska uruchomieniowego agenta używać, jak skonfigurować serwery MCP do ustrukturyzowanego dostępu do buildów, co umieścić w CLAUDE.md, które hooki zapobiegają zniszczeniu projektu Xcode przez agenta oraz — co kluczowe — gdzie agenty zawodzą i trzeba przejąć ster.
Najważniejsze wnioski
Dla programistów iOS, którzy dopiero zaczynają pracę z agentami AI:
- Warto zacząć od Claude Code CLI + XcodeBuildMCP. To najbardziej dojrzałe środowisko uruchomieniowe z najgłębszym pokryciem narzędzi MCP. Wystarczy zainstalować dwa polecenia, dodać CLAUDE.md do projektu, a agent może budować, testować i debugować bez kopiowania komunikatów o błędach.
- Nigdy nie należy pozwalać agentowi modyfikować .pbxproj. To najważniejsza zasada. Hook PreToolUse blokujący zapisy do
.pbxproji.xcodeproj/oszczędzi godziny odzyskiwania projektu. - CLAUDE.md jest dokumentem onboardingowym agenta. Godziny poświęcone na jego przygotowanie zwracają się w każdej sesji agenta pracującej z projektem.
Dla doświadczonych użytkowników agentów, którzy dodają iOS do swojego workflow:
- MCP zmienia pętlę buildów iOS. Przed MCP agenty pisały Swift, ale nie mogły sprawdzić, czy kod się kompiluje. Dzięki XcodeBuildMCP agent pisze kod, buduje go, odczytuje ustrukturyzowane błędy, naprawia je i uruchamia testy — autonomicznie.
- Trzy środowiska uruchomieniowe odpowiadają na różne potrzeby. Claude Code CLI do głębokich sesji agentowych, Codex CLI do bezgłowej pracy wsadowej, natywne agenty Xcode 26.3 do szybkich poprawek inline bez opuszczania IDE.
- Infrastruktura hooków przenosi się bez problemu. Istniejące formatery PostToolUse, blokady PreToolUse i hooki uruchamiające testy działają identycznie w projektach iOS po drobnych korektach ścieżek.
Dla liderów zespołów oceniających rozwój iOS wspierany przez AI:
- Skuteczność agentów skaluje się wraz z dokumentacją projektu, nie jego rozmiarem. Aplikacja z 63 plikami i szczegółowym CLAUDE.md daje lepszy wynik pracy agenta niż aplikacja z 14 plikami bez żadnej dokumentacji.
- Granica .pbxproj jest nienegocjowalna. Agenty nie potrafią niezawodnie edytować plików projektów Xcode. Workflow musi uwzględniać ręczne dodawanie plików do targetów Xcode.
- Uczciwe ROI: agenty wykonują większość implementacji w dobrze udokumentowanych projektach — widać to w 15-plikowej aplikacji TV wydanej w 3 godziny pracy wspieranej przez agenta (studium przypadku poniżej). Pozostała praca — wizualne dopracowanie, podpisywanie, strojenie wydajności, zgłoszenie do App Store — wymaga ludzkiej oceny.
Wybór ścieżki
| Czego potrzeba | Dokąd przejść |
|---|---|
| Pierwsza konfiguracja MCP | Konfiguracja MCP: kompletna konfiguracja — instalacja obu serwerów, weryfikacja, konfiguracja agentów |
| Napisanie CLAUDE.md dla projektu iOS | Wzorce CLAUDE.md dla projektów iOS — prawdziwe przykłady z 8 aplikacji |
| Porównanie trzech środowisk uruchomieniowych agentów | Trzy środowiska uruchomieniowe agentów dla iOS — Claude Code kontra Codex kontra natywne Xcode |
| Zrozumienie, co agenty potrafią, a czego nie | W czym agenty są dobre i W czym agenty są słabe |
| Konfiguracja hooków do rozwoju iOS | Hooki dla rozwoju iOS — formatowanie przy zapisie, ochrona .pbxproj, uruchamianie testów |
| Głębokie odniesienie (ta strona) | Proszę czytać dalej — wszystko od konfiguracji po zaawansowane wzorce |
Jak korzystać z tego przewodnika
To ponad 3000 linii materiału referencyjnego. Najlepiej zacząć od miejsca pasującego do poziomu doświadczenia:
| Doświadczenie | Zacząć tutaj | Potem sprawdzić |
|---|---|---|
| Nowość w iOS + agentach | Wymagania wstępne → Konfiguracja MCP → Pierwsza sesja agenta | Wzorce CLAUDE.md, Co działa / co nie działa |
| Programista iOS, nowy w agentach | Trzy środowiska uruchomieniowe → Konfiguracja MCP → CLAUDE.md | Hooki, Wzorce architektury |
| Użytkownik agentów, nowy w iOS | Wzorce architektury → W czym agenty są słabe → CLAUDE.md | Kontekst specyficzny dla frameworków, Zaawansowane workflow |
| Doświadczenie w obu obszarach | Zaawansowane workflow → Hooki → Wzorce wieloplatformowe | Macierz porównania środowisk uruchomieniowych, Portfolio |
Spis treści
- Portfolio: 8 aplikacji, 293 pliki
- Wymagania wstępne
- Trzy środowiska uruchomieniowe agentów dla iOS
- Konfiguracja MCP: kompletna konfiguracja
- Wzorce CLAUDE.md dla projektów iOS
- Pierwsza sesja agenta
- W czym agenty są dobre w iOS
- W czym agenty są słabe w iOS
- Hooki dla rozwoju iOS
- Wzorce architektury działające z agentami
- Kontekst specyficzny dla frameworków
- Wzorce wieloplatformowe
- Zaawansowane workflow
- Studia przypadków z praktyki
- Cykl życia projektu z agentami
- Konfigurowanie definicji agentów
- Wzorce testowania dla iOS wspieranego przez agentów
- Zarządzanie oknem kontekstu w projektach iOS
- Rozwiązywanie problemów
- Typowe błędy agentów w iOS
- Uczciwa ocena
- FAQ
- Skrócona karta referencyjna
- Źródła
Powiązane zasoby
| Temat | Zasób |
|---|---|
| Konfiguracja MCP dla Xcode (krótszy wpis na blogu) | Dwa serwery MCP zmieniły Claude Code w system buildów iOS |
| Pełne odniesienie Claude Code CLI | Claude Code CLI: kompletny przewodnik |
| Odniesienie Codex CLI | Codex CLI: kompletny przewodnik |
| Dogłębne omówienie systemu hooków | Anatomia pazura: 84 hooki jako warstwa orkiestracji |
| Wzorce architektury agentów | Przewodnik po architekturze agentów |
| Aplikacja desktopowa Mac + Remote Control | Claude Code Mac Desktop + Remote Control: przewodnik użytkownika CLI |
Seria Apple Ecosystem. 21 produkcyjnych wpisów o aplikacjach SwiftUI integrujących się z Apple Intelligence, MCP, Foundation Models, Vision, Core ML i stosem frameworków iOS 26. Na podstawie Water, Get Bananas, Return oraz reszty portfolio 941:
Centrum serii: Seria Apple Ecosystem
Agentic Apple (E4):
| Temat | Zasób |
|---|---|
| Powierzchnia intencji Apple Intelligence | App Intents to nowe API Apple do aplikacji |
| Serwer MCP obok aplikacji iOS | Dwa ekosystemy agentów, jedna lista zakupów |
| Kiedy używać którego | App Intents kontra narzędzia MCP: pytanie o routing |
| Urządzeniowy LLM jako funkcja runtime kontra tooling | Foundation Models + agentowy workflow |
| Hooki dla rozwoju Apple | Hooki dla rozwoju Apple |
| Stan między procesami | Jedno źródło prawdy: SwiftData + MCP + iCloud |
Frameworki (E2/E3):
| Temat | Zasób |
|---|---|
| Urządzeniowy LLM w Foundation Models | Foundation Models — urządzeniowy LLM |
| Framework Vision (prymitywy CV) | Framework Vision: co jest wbudowane |
| Wzorce inferencji Core ML | Urządzeniowa inferencja Core ML |
| Przestrzenny model mentalny RealityKit | RealityKit i przestrzenny model mentalny |
| Wewnętrzna budowa SwiftUI | Z czego składa się SwiftUI |
| Słownik animacji Symbol Effects | Symbol Effects: wbudowany słownik animacji SwiftUI |
| Liquid Glass w iOS 26+ | Liquid Glass w SwiftUI: trzy wzorce |
Wydany kod (E1):
| Temat | Zasób |
|---|---|
| Maszyna stanów Live Activities | Maszyna stanów Live Activities |
| Kontrakt runtime watchOS | Kontrakt runtime watchOS |
| Dyscyplina schematu SwiftData | Dyscyplina schematu SwiftData |
| Wzorce HealthKit + SwiftUI | HealthKit + SwiftUI na iOS 26 |
| Wieloplatformowe SwiftUI | Pięć platform Apple, trzy współdzielone pliki |
| Integracja XcodeBuildMCP | Dwa serwery MCP, jeden projekt Xcode |
Synteza (E5):
| Temat | Zasób |
|---|---|
| Trzy powierzchnie aplikacji iOS | Trzy powierzchnie aplikacji iOS |
| Decyzje dotyczące targetów platform | Macierz platform Apple |
| O czym odmawiam pisania | O czym odmawiam pisania |
Portfolio: 8 aplikacji, 293 plików
Przed przejściem do konfiguracji warto przedstawić, na czym opiera się ten przewodnik. Nie są to projekty zabawkowe — obejmują pięć frameworków Apple, trzy platformy oraz pełen zakres złożoności iOS, od 14-plikowego trackera treningów po 63-plikowy wieloplatformowy timer medytacyjny.
| Aplikacja | Stack | Pliki | Złożoność |
|---|---|---|---|
| Banana List | SwiftUI + SwiftData + synchronizacja iCloud Drive + serwer MCP dla Claude Desktop | 53 | Pełne CRUD, synchronizacja iCloud, niestandardowy serwer MCP udostępniający dane aplikacji do Claude Desktop |
| Ace Citizenship | Aplikacja edukacyjna SwiftUI + backend FastAPI | 26 | Klient-serwer, integracja REST API, silnik quizowy |
| TappyColor | Gra dopasowywania kolorów w SpriteKit | 30 | Pętla gry, fizyka, obsługa dotyku, efekty cząsteczkowe |
| Return | Zen-owy timer medytacyjny — iOS 26+, watchOS, tvOS | 63 | HealthKit, Live Activities, rozszerzony czas działania na Watch, nawigacja focus na TV, synchronizacja sesji przez iCloud |
| amp97 | Shadery Metal + wizualizacja dźwięku | 41 | Niestandardowy potok renderujący Metal, analiza audio, obliczenia GPU w czasie rzeczywistym |
| Reps | Śledzenie treningów SwiftUI + SwiftData | 14 | Minimalna działająca aplikacja, czyste wzorce SwiftData |
| Water | Śledzenie nawodnienia SwiftUI + SwiftData + Metal + HealthKit | 34 | Symulacja płynów w Metal, rejestrowanie spożycia wody w HealthKit, widżet |
| Starfield Destroyer | Strzelanka kosmiczna SpriteKit + Metal | 32 | 99 poziomów, 8 statków, tablice wyników Game Center, post-processing w Metal |
Dlaczego liczba plików ma znaczenie: skuteczność agenta koreluje z czytelnością projektu, a nie z jego rozmiarem. Return (63 pliki) daje lepsze rezultaty pracy agenta niż amp97 (41 plików), ponieważ Return ma szczegółowy plik CLAUDE.md z adnotacjami plików, diagramami architektury i jawnymi wzorcami. Shadery Metal w amp97 są z natury trudniejsze do analizy dla agentów, niezależnie od jakości dokumentacji.
Wymagania wstępne
Przed skonfigurowaniem jakiegokolwiek środowiska uruchomieniowego agenta do programowania iOS:
Termin App Store Connect: od 2026-04-28 przesyłanie aplikacji do App Store Connect musi odbywać się z buildów stworzonych w Xcode 26 lub nowszym z użyciem SDKs dla iOS 26, iPadOS 26, tvOS 26, visionOS 26 lub watchOS 26.12 (Wysyłki macOS nie podlegają temu wymogowi.) Jeśli zespół wciąż używa Xcode 16.x, łańcuch narzędzi wspomagany przez agenta opisany w tym przewodniku staje się również czynnikiem wymuszającym aktualizację — żaden z poniższych serwerów MCP i tak nie działa bez Xcode 26.3+.
Wymagane:
- macOS 15+ (Sequoia) lub macOS Tahoe
- Zainstalowany i skonfigurowany Xcode 26.3+ (minimum dla xcrun mcpbridge); zalecany Xcode 26.4+ ze względu na załączniki obrazów w Swift Testing, poziomy ważności zarejestrowanych problemów, ostrzeżenia o awariach UI-test z crashlogami oraz usprawnienia edytora String Catalog.13 Xcode 26.4.1 (2026-04-16, build 17E202) to najnowsza stabilna wersja — wyłącznie poprawki błędów.14
- Co najmniej jedno zainstalowane środowisko uruchomieniowe iOS Simulator
- Konto Anthropic API (dla Claude Code) lub konto OpenAI (dla Codex)
Zalecane:
- Zainstalowany SwiftFormat (brew install swiftformat) — używany przez hooki format-on-save
- Zainstalowany SwiftLint (brew install swiftlint) — opcjonalnie, ale przydatny do egzekwowania stylu
- Znajomość terminala — wszystkie trzy środowiska uruchomieniowe działają z poziomu wiersza poleceń lub się z nim integrują
Weryfikacja instalacji Xcode:
# Check Xcode version
xcodebuild -version
# Expected: Xcode 26.3 or later (26.4+ recommended)
# Check available simulators
xcrun simctl list devices available
# Expected: at least one iPhone simulator
# Verify xcrun mcpbridge is available
xcrun mcpbridge --help
# Expected: usage information (not "command not found")
Jeśli xcrun mcpbridge zwróci „command not found”, konieczny jest Xcode 26.3 lub nowszy. Należy zainstalować lub zaktualizować Xcode poprzez App Store albo stronę developer.apple.com. Uwaga: xcode-select --install instaluje wyłącznie Command Line Tools, które nie zawierają mcpbridge — wymagana jest pełna aplikacja Xcode.app.
Trzy środowiska uruchomieniowe agentów dla iOS
Trzy odrębne środowiska uruchomieniowe są w stanie pisać, budować i testować kod iOS. Nie są one wymienne — każde z nich ma inne mocne strony, inne wzorce integracji MCP oraz inne idealne przypadki użycia.
1. Claude Code CLI
Czym jest: Asystent kodowania agentowego oparty na terminalu, opracowany przez Anthropic. Czyta bazę kodu, wykonuje polecenia, modyfikuje pliki i łączy się z zewnętrznymi narzędziami za pośrednictwem MCP.
Integracja MCP: Pełna obsługa zarówno XcodeBuildMCP, jak i Apple Xcode MCP. Agent wykrywa narzędzia za pomocą protokołu MCP i wywołuje je z parametrami strukturalnymi. 59 + 20 narzędzi w obu serwerach.
Konfiguracja:
# Install Claude Code (if not already installed)
claude --version # verify installation
# Add XcodeBuildMCP (59 tools — builds, tests, simulators, debugging)
claude mcp add XcodeBuildMCP \
-s user \
-e XCODEBUILDMCP_SENTRY_DISABLED=true \
-- npx -y xcodebuildmcp@latest mcp
# Add Apple Xcode MCP (20 tools — file ops, diagnostics, Swift REPL, previews)
claude mcp add --transport stdio xcode \
-s user -- xcrun mcpbridge
Alternatywa — automatyczny instalator xcodebuildmcp init (v2.1.0+, 2026-02-23):
Jeśli wolałby Pan/Pani pominąć ręczne konfigurowanie MCP, XcodeBuildMCP w wersji 2.1.0+ udostępnia podpolecenie init, które automatycznie wykrywa Claude Code, Cursor lub Codex i instaluje umiejętności agenta wraz z konfiguracją MCP w jednym kroku:
xcodebuildmcp init
# Or without a global install:
npx -y xcodebuildmcp@latest init
Flagi: --print (zapisuje konfigurację na stdout dla nieobsługiwanych klientów), --uninstall (usuwa). Warto pominąć tę opcję, jeśli zależy nam na jawnej kontroli nad tym, które serwery MCP są podłączone i w jakim zakresie; ręczne wywołania claude mcp add przedstawione powyżej dają taką kontrolę.15
Najlepiej sprawdza się przy: głębokich sesjach implementacyjnych — budowaniu nowych funkcji, refaktoryzacji obejmującej wiele plików, debugowaniu złożonych problemów oraz autonomicznym uruchamianiu pętli build-test-fix. Okno kontekstowe Claude Code o pojemności 1 mln tokenów (z Opus 4.6) sprawia, że agent może utrzymywać większość małych i średnich projektów iOS w pamięci roboczej — z mojego doświadczenia, do mniej więcej 50 plików w zależności od ich rozmiaru.
Typowa sesja:
You: Add a new SettingsView with toggles for notifications and haptic feedback.
Use the existing Settings.swift pattern from TimerManager.
Build for simulator after implementation and fix any errors.
Claude: [reads Settings.swift, TimerManager.swift, existing views]
[creates SettingsView.swift]
[calls build_sim via MCP]
[reads structured error: missing import HealthKit]
[fixes import]
[calls build_sim again — success, 0 errors, 1 warning]
[calls test_sim — all tests pass]
Kluczowa różnica w stosunku do procesu sprzed MCP: agent nigdy nie prosi o ręczne zbudowanie projektu ani o wklejenie wyniku błędu. Pętla build-error-fix jest autonomiczna.
2. Codex CLI
Czym jest: Agent kodowania OpenAI oparty na terminalu. Koncepcyjnie podobny do Claude Code, ale wykorzystuje modele OpenAI (GPT-4o, o3) i ma inny model uprawnień.
Integracja MCP: Codex obsługuje MCP za pomocą polecenia codex mcp add. Apple Xcode MCP działa bezpośrednio:
# Add Apple Xcode MCP to Codex
codex mcp add xcode -- xcrun mcpbridge
XcodeBuildMCP również współpracuje z Codex za pośrednictwem tego samego polecenia npx:
# Add XcodeBuildMCP to Codex
codex mcp add XcodeBuildMCP -- npx -y xcodebuildmcp@latest mcp
Najlepiej sprawdza się przy: bezgłowych operacjach wsadowych, integracji z CI/CD oraz zadaniach, w których przydatna jest druga opinia od innej rodziny modeli. Tryb sandbox w Codex uruchamia kod w izolowanych środowiskach, co jest użyteczne przy operacjach destrukcyjnych, takich jak uruchamianie zestawów testów modyfikujących stan.
Kluczowe różnice w porównaniu z Claude Code:
- Wykorzystuje modele OpenAI zamiast modeli Claude
- Inne rozmiary okien kontekstowych i ekonomia tokenów
- Model uprawnień oparty na sandboksie (domyślnie bardziej restrykcyjny)
- Mniejszy ekosystem MCP (mniej przetestowanych serwerów społecznościowych)
- Dostępny system hooków (v0.119.0+), ale mniej dojrzały niż w Claude Code — mniej typów zdarzeń i brak warunkowego pola if
Kiedy wybrać Codex zamiast Claude Code w iOS:
Z Codex warto skorzystać wtedy, gdy zależy nam na różnorodności modeli — drugi agent recenzujący kod napisany przez pierwszego wychwytuje inne klasy błędów. Przepływ pracy collab (Claude buduje, Codex recenzuje) sprawdza się w iOS, ponieważ wzorce SwiftUI, które jednej rodzinie modeli wydają się poprawne, mogą zawierać subtelne problemy wychwytywane przez inną. Szczególnie shadery Metal i wzorce współbieżności zyskują na podwójnej recenzji modelowej.
3. Natywni agenci Xcode 26.3
Czym jest: Apple zintegrowało agentów kodowania AI bezpośrednio z panelem Intelligence w Xcode. Począwszy od Xcode 26.3, można skonfigurować Claude Agent oraz Codex jako dostawców inteligencji w Xcode Settings > Intelligence.
Konfiguracja:
- Proszę otworzyć Xcode 26.3+
- Przejść do Settings > Intelligence
- Dodać nowego dostawcę:
- Dla Claude: wybrać „Claude Agent”, wprowadzić swój klucz API od Anthropic
- Dla Codex: wybrać „Codex”, wprowadzić swój klucz API OpenAI
- Agent pojawi się na pasku bocznym Intelligence i można go wywoływać w trybie inline
Najlepiej sprawdza się przy: szybkich edycjach inline, uzupełnianiu kodu z rozumowaniem na poziomie agenta oraz dla deweloperów, którzy wolą nie opuszczać Xcode. Natywna integracja oznacza, że agent ma bezpośredni dostęp do kontekstu projektu Xcode — otwartych plików, celów kompilacji, konfiguracji schematu — bez konieczności pomostu MCP.
Ograniczenia w porównaniu z agentami CLI: - Brak systemu hooków — nie można wymusić formatowania przy zapisie ani blokować zapisów do .pbxproj - Brak ładowania CLAUDE.md — agent nie czyta plików konfiguracyjnych na poziomie projektu - Ograniczona autonomia — agent operuje na bieżącym pliku lub zaznaczeniu, nie w obrębie całego projektu - Brak delegacji do podagentów — złożonych zadań wieloetapowych nie da się zrównoleglać - Brak konfiguracji serwerów MCP — agent korzysta wyłącznie z wbudowanych narzędzi Xcode
Kiedy używać natywnych agentów Xcode:
Do szybkich, ograniczonych zakresowo edycji, w których przełączanie się do terminala stanowi nadmierny narzut. „Dodaj wyliczaną właściwość do tego modelu.” „Napisz test jednostkowy dla tej funkcji.” „Zrefaktoryzuj ten widok, by używał @Observable.” Zadania dotykające jednego lub dwóch plików i niewymagające cyklu build-test.
We wszystkim, co wymaga budowania, testowania, refaktoryzacji wieloplikowej lub autonomicznej korekty błędów, należy korzystać z agenta CLI z MCP.
Macierz porównawcza środowisk uruchomieniowych
| Możliwość | Claude Code CLI | Codex CLI | Xcode 26.3 natywny |
|---|---|---|---|
| Wsparcie MCP | Pełne (79 narzędzi) | Pełne (79 narzędzi) | Tylko wbudowane narzędzia Xcode |
| System hooków | Tak (dojrzały) | Tak (podstawowy, v0.119.0+) | Nie |
| CLAUDE.md / konfiguracja projektu | Tak | Odpowiednik codex.md | Nie |
| Autonomiczne build-test-fix | Tak (przez MCP) | Tak (przez MCP) | Częściowe (tylko inline) |
| Delegacja do podagentów | Tak (do 10 równolegle) | Nie | Nie |
| Okno kontekstowe | 1 mln tokenów (Opus 4.6) | Zależy od modelu | Zależy od dostawcy |
| Operacje wieloplikowe | Pełen dostęp do bazy kodu | Pełen dostęp do bazy kodu | Bieżący plik / zaznaczenie |
| Ochrona .pbxproj | Przez hooki | Ręczna | N/D (używa natywnie Xcode) |
| Formatowanie przy zapisie | Przez hooki PostToolUse | Zewnętrzne narzędzia | Ustawienia Xcode |
| Praca offline | Nie | Nie | Nie |
| Model kosztowy | Zużycie API Anthropic | Zużycie API OpenAI | Zużycie API dostawcy |
Rekomendacja: Jako głównego środowiska uruchomieniowego warto używać Claude Code CLI. Natywni agenci Xcode 26.3 sprawdzą się przy szybkich edycjach inline. Codex CLI przyda się do przebiegów recenzyjnych i operacji wsadowych. Te trzy rozwiązania wzajemnie się uzupełniają, a nie konkurują ze sobą.
Konfiguracja MCP: pełna konfiguracja
MCP (Model Context Protocol) zmienia agenta z narzędzia, które „pisze Swift i ma nadzieję, że Pan/Pani je zbuduje”, w narzędzie, które „pisze Swift, buduje projekt, odczytuje ustrukturyzowane błędy i je naprawia”. Ta sekcja sięga głębiej niż wpis na blogu — obejmuje oba serwery, wszystkie metody instalacji, weryfikację oraz konfigurację agenta, która zapewnia, że narzędzia są faktycznie używane.
XcodeBuildMCP: 59 narzędzi do bezgłowego tworzenia aplikacji iOS
XcodeBuildMCP opakowuje xcodebuild, xcrun simctl i LLDB w 59 ustrukturyzowanych narzędzi MCP. Działa bez uruchomionego Xcode — cały cykl budowania, testowania i debugowania odbywa się bez interfejsu graficznego, przez narzędzia wiersza poleceń Apple.
Opcje instalacji:
# Option 1: Via npx (recommended — always uses latest version)
claude mcp add XcodeBuildMCP \
-s user \
-e XCODEBUILDMCP_SENTRY_DISABLED=true \
-- npx -y xcodebuildmcp@latest mcp
# Option 2: Via Homebrew (pinned version, manual updates)
brew install xcodebuildmcp
claude mcp add XcodeBuildMCP \
-s user \
-e XCODEBUILDMCP_SENTRY_DISABLED=true \
-- xcodebuildmcp mcp
# Option 3: Project-scoped (omit -s user)
claude mcp add XcodeBuildMCP \
-e XCODEBUILDMCP_SENTRY_DISABLED=true \
-- npx -y xcodebuildmcp@latest mcp
Flaga -s user udostępnia serwer globalnie we wszystkich projektach. Proszę ją pominąć przy instalacji ograniczonej do projektu (przydatne, jeśli MCP ma być używany tylko w projektach iOS, a nie w projektach webowych).
Zmienna środowiskowa -e XCODEBUILDMCP_SENTRY_DISABLED=true wyłącza telemetrię raportów awarii. XcodeBuildMCP domyślnie zawiera Sentry, które wysyła dane błędów, w tym ścieżki plików. Warto zrezygnować z tej opcji, chyba że chce Pan/Pani przekazywać diagnostykę do projektu.1
Pełny wykaz narzędzi (59 narzędzi w 8 kategoriach):
| Kategoria | Narzędzia | Co robią |
|---|---|---|
| Wykrywanie projektu | discover_projs, list_schemes, list_targets |
Znajdują pliki .xcodeproj/.xcworkspace oraz wyświetlają dostępne schematy i targety |
| Budowanie | build_sim, build_device, build_mac |
Budują z ustrukturyzowanym wyjściem błędów/ostrzeżeń JSON według pliku i wiersza |
| Testowanie | test_sim, test_device |
Uruchamiają testy z wynikami zaliczenia/niezaliczenia dla każdej metody |
| Cykl życia symulatora | list_sims, boot_sim, shutdown_sim, open_sim, session_set_defaults |
Tworzą, uruchamiają, zarządzają i konfigurują symulatory |
| Zarządzanie urządzeniami | list_devices, install_device, launch_device |
Obsługują wdrażanie i zarządzanie na rzeczywistych urządzeniach |
| Debugowanie | debug_attach_sim, debug_attach_device, debug_breakpoint, debug_stack, debug_variables, debug_eval, debug_continue, debug_step, debug_detach |
Zapewniają pełną integrację z LLDB, w tym breakpointy i inspekcję zmiennych |
| Automatyzacja UI | snapshot_ui, screenshot, tap, swipe, type_text |
Automatyzują interakcję i przechwytywanie obrazu |
| Tworzenie szkieletu projektu | create_project, add_file, add_package |
Tworzą projekty i dodają zależności |
Narzędzia najważniejsze w codziennej pracy:
-
build_sim— będzie wywoływane setki razy. Zwraca JSON z błędami skategoryzowanymi według pliku, wiersza i poziomu ważności. Agent odczytuje błąd, przechodzi do pliku i naprawia go bez żadnej interwencji. -
test_sim— zwraca wyniki dla każdej metody testowej. Agent wie dokładnie, który test zakończył się niepowodzeniem i dlaczego, a nie tylko, że „testy się nie powiodły”. -
list_sims+boot_sim— zarządzanie symulatorem bez zapamiętywania flagxcrun simctl. Agent wykrywa dostępne środowiska uruchomieniowe i wybiera odpowiednie urządzenie. -
discover_projs+list_schemes— introspekcja projektu. Agent nie musi zgadywać nazwy schematu ani struktury workspace. -
debug_attach_sim+debug_stack+debug_variables— zdalne debugowanie LLDB. Agent może ustawiać breakpointy, sprawdzać zmienne i wykonywać kod krok po kroku bez otwierania debuggera.
Apple Xcode MCP: 20 narzędzi pomostowych do Xcode
Serwer MCP od Apple jest dostarczany z Xcode 26.3 przez xcrun mcpbridge. Komunikuje się z uruchomionym procesem Xcode przez XPC (framework Apple do komunikacji międzyprocesowej), udostępniając stan wewnętrzny, do którego żadne narzędzie CLI nie ma dostępu.
Instalacja:
# Standard installation (global)
claude mcp add --transport stdio xcode \
-s user -- xcrun mcpbridge
# For Codex CLI
codex mcp add xcode -- xcrun mcpbridge
Wymaga Xcode 26.3+ oraz uruchomionego procesu Xcode. Jeśli Xcode nie jest otwarty, każde wywołanie MCP przez ten serwer zakończy się błędem albo zawiesi. XcodeBuildMCP nie ma tego ograniczenia.
Wykaz narzędzi (20 narzędzi w 5 kategoriach):
| Kategoria | Narzędzia | Co robią |
|---|---|---|
| Operacje na plikach | XcodeRead, XcodeWrite, XcodeUpdate, XcodeGlob, XcodeGrep |
Odczytują/zapisują pliki w kontekście projektu Xcode |
| Budowanie i testowanie | BuildProject, GetBuildLog, RunAllTests, RunSomeTests |
Budują i testują za pomocą wewnętrznego systemu budowania Xcode |
| Diagnostyka | XcodeListNavigatorIssues, XcodeRefreshCodeIssuesInFile |
Zapewniają diagnostykę kodu w czasie rzeczywistym (nie tylko błędy budowania) |
| Kod i dokumentacja | ExecuteSnippet, DocumentationSearch |
Wykonują kod w Swift REPL i przeszukują dokumentację Apple |
| Previews | RenderPreview |
Renderują SwiftUI preview bez interfejsu graficznego |
Narzędzia unikalne dla Apple MCP (niedostępne w XcodeBuildMCP):
-
DocumentationSearch— przeszukuje dokumentację developerską Apple, w tym sesje WWDC. W przypadku pytań o API od Apple jest szybsze i bardziej niezawodne niż wyszukiwanie w sieci. Można zapytać „czy HKQuantityType(.dietaryWater) jest poprawne?” i uzyskać jednoznaczną odpowiedź ze źródła. -
ExecuteSnippet— wykonywanie Swift REPL w kontekście projektu. Agent może zweryfikować zachowanie API, przetestować konwersje typów i sprawdzić poprawność wyrażeń bez budowania całej aplikacji. -
RenderPreview— renderuje SwiftUI previews bez interfejsu graficznego. Agent może sprawdzić, czy widok renderuje się bez błędów, choć nie może ocenić poprawności wizualnej (render jest zwracany jako dane, a nie wizualnie sprawdzany). -
XcodeListNavigatorIssues— zwraca diagnostykę w czasie rzeczywistym z analizatora Xcode, a nie tylko błędy budowania. Wykrywa problemy takie jak nieużywane zmienne, potencjalne cykle silnych referencji i ostrzeżenia o wycofaniu funkcji, których system budowania nie pokazuje.
Dlaczego oba serwery
Nakładają się w obszarze budowania i testów, ale zasadniczo się różnią:
┌─────────────────────────────────────────────────────────────────┐
│ MCP TOOL COVERAGE │
├─────────────────────────────────────────────────────────────────┤
│ │
│ XcodeBuildMCP (59 tools) Apple Xcode MCP (20 tools) │
│ ┌─────────────────────┐ ┌─────────────────────┐ │
│ │ Standalone │ │ Requires Xcode │ │
│ │ (no Xcode process) │ │ (XPC bridge) │ │
│ │ │ │ │ │
│ │ ✓ Simulators │ BOTH │ ✓ Documentation │ │
│ │ ✓ Real devices │ ┌─────┐ │ ✓ Swift REPL │ │
│ │ ✓ LLDB debugging │ │Build│ │ ✓ SwiftUI previews │ │
│ │ ✓ UI automation │ │Test │ │ ✓ Live diagnostics │ │
│ │ ✓ Project scaffold │ └─────┘ │ ✓ Analyzer issues │ │
│ │ ✓ Screenshot │ │ │ │
│ └─────────────────────┘ └─────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘
XcodeBuildMCP należy używać do: cyklu budowania, testowania i debugowania. Działa bez otwartego Xcode, zużywa mniej pamięci systemowej i zapewnia bogatsze zarządzanie symulatorami oraz urządzeniami. To podstawowe narzędzie do budowania.
Apple Xcode MCP należy używać do: wyszukiwania w dokumentacji, weryfikacji w Swift REPL, renderowania SwiftUI preview i diagnostyki w czasie rzeczywistym. Podczas sesji wymagających tych możliwości Xcode powinien pozostać otwarty.
W praktyce: używam XcodeBuildMCP do około 90% wywołań MCP, a Apple Xcode MCP do dokumentacji i weryfikacji w REPL. Agent domyślnie wybiera XcodeBuildMCP do budowania i testowania, ponieważ jest szybszy (brak narzutu procesu Xcode) i bardziej niezawodny (brak zależności od XPC).
Weryfikacja
Po zainstalowaniu obu serwerów proszę sprawdzić, czy są połączone:
# List all configured MCP servers
claude mcp list
# Expected output includes:
# XcodeBuildMCP: npx -y xcodebuildmcp@latest mcp - Connected
# xcode: xcrun mcpbridge - Connected
Jeśli serwer pokazuje „Disconnected” albo się nie pojawia:
- XcodeBuildMCP się nie łączy: proszę upewnić się, że zainstalowano Node.js (
node --version). Polecenienpxwymaga Node.js 18+. - Apple Xcode MCP się nie łączy: proszę upewnić się, że zainstalowano Xcode 26.3+ i że polecenie
xcrun mcpbridgedziała w terminalu. Należy otworzyć Xcode co najmniej raz, aby zaakceptować umowę licencyjną. - Nie pojawia się żaden z nich: proszę ponownie uruchomić Claude Code (
claudew nowym terminalu). Serwery MCP zarejestrowane w trakcie sesji mogą nie pojawić się do czasu restartu.
Nauczenie agenta używania MCP
Instalacja serwerów MCP jest konieczna, ale niewystarczająca. Bez wyraźnych wskazówek agent może wrócić do uruchamiania xcodebuild przez Bash (nieustrukturyzowane wyjście, zmarnowane tokeny kontekstu) albo używać wyszukiwania w sieci dla dokumentacji Apple (wolniejsze, mniej niezawodne).
Proszę dodać to do CLAUDE.md albo definicji agenta:
## Build & Test — Always Use MCP
Prefer MCP tools over raw shell commands for ALL build operations:
- **Build**: `build_sim` / `build_device` (NOT `xcodebuild` via Bash)
- **Test**: `test_sim` / `test_device` (NOT `xcodebuild test` via Bash)
- **Simulators**: `list_sims`, `boot_sim`, `open_sim` (NOT `xcrun simctl` via Bash)
- **Debug**: `debug_attach_sim`, `debug_stack`, `debug_variables`
- **Apple docs**: `DocumentationSearch` (NOT WebSearch for Apple APIs)
- **Swift verification**: `ExecuteSnippet` (NOT `swift` via Bash)
- **Previews**: `RenderPreview` for headless SwiftUI verification
MCP returns structured JSON. Bash returns unstructured text.
Structured data means fewer tokens consumed and better error diagnosis.
Ta wskazówka sprawia, że agent w pierwszej kolejności sięga po narzędzia MCP. Bez niej można zaobserwować, jak agent konstruuje długie polecenia xcodebuild przez Bash, zużywa tysiące tokenów kontekstu na parsowanie wyjścia, a czasem błędnie identyfikuje właściwy błąd.
Wzorce CLAUDE.md dla projektów iOS
CLAUDE.md to najważniejszy plik w projekcie przy tworzeniu oprogramowania z pomocą agentów. To dokument onboardingowy agenta — różnica między nową osobą w zespole, która przeczytała dokumentację architektury, a taką, która zgaduje.
Każdy projekt iOS, który utrzymuję, ma CLAUDE.md. Oto wzorce, które działają, wyprowadzone ze wszystkich 8 aplikacji.
Niezbędne sekcje
Każdy iOS CLAUDE.md potrzebuje tych 6 sekcji. Wszystko inne jest opcjonalne.
1. Tożsamość projektu
# Return - Zen Focus Timer
**Bundle ID:** `com.941apps.Return`
**Target:** iOS 26+ / macOS Tahoe / watchOS 26+ / tvOS 26+
**Architecture:** SwiftUI with @Observable pattern, companion Watch and TV apps
**Swift version:** 6.2
**Minimum deployment:** iOS 26.0
Dlaczego to ma znaczenie: agent musi znać docelową wersję wdrożenia, zanim napisze jakikolwiek kod. Agent celujący w iOS 17 użyje NavigationView i @ObservedObject. Agent celujący w iOS 26 użyje NavigationStack i @Observable. Bundle ID ma znaczenie dla uprawnień i konfiguracji HealthKit. Wersja Swift określa model współbieżności (async/await zamiast callbacków completion handler, ścisła współbieżność zamiast łagodnej).
2. Struktura plików z adnotacjami celu
## File Structure
```
Return/
├── ReturnApp.swift # App entry, dark mode enforcement
├── ContentView.swift # Main timer view with theme backgrounds
├── TimerManager.swift # Timer state, logic, and repeat handling
├── AudioManager.swift # Sound playback with AVAudioPlayer
├── Settings.swift # Centralized settings with validation
├── SettingsSheet.swift # Settings UI
├── HealthKitManager.swift # Mindful session logging + cross-device sync
├── LiveActivityManager.swift # Lock Screen/Dynamic Island
├── Theme.swift # Theme definitions
├── ThemeManager.swift # Theme state management
├── VideoBackgroundView.swift # AVPlayer video backgrounds
├── GlassTextShape.swift # Core Text glyph paths for glass effect
├── GlassTimerText.swift # Timer text with glass material
└── Constants.swift # App constants
```
Komentarze inline po każdej nazwie pliku nie są ozdobą. To dokumentacja o największym przełożeniu, jaką można napisać. Gdy agent decyduje, gdzie dodać nową funkcję, te adnotacje prowadzą go do właściwego pliku przy pierwszej próbie, zamiast zmuszać do czytania każdego pliku, by zrozumieć układ projektu.
Antywzorzec: lista plików bez adnotacji. TimerManager.swift nie mówi agentowi nic o tym, czy obsługuje stan, UI, czy jedno i drugie. TimerManager.swift # Timer state, logic, and repeat handling mówi dokładnie, co tam należy, a co nie.
3. Polecenia budowania i testowania
## Build & Test
Build for iOS simulator:
```bash
xcodebuild -scheme Return -destination 'platform=iOS Simulator,name=iPhone 16 Pro' build
```
Run tests:
```bash
xcodebuild -scheme Return -destination 'platform=iOS Simulator,name=iPhone 16 Pro' test
```
Run tvOS tests:
```bash
xcodebuild -scheme ReturnTV -destination 'platform=tvOS Simulator,name=Apple TV' test
```
**Prefer MCP tools** (`build_sim`, `test_sim`) over these raw commands.
MCP returns structured JSON with categorized errors.
Należy uwzględnić surowe polecenia, mimo że agent powinien preferować MCP. Surowe polecenia służą jako dokumentacja awaryjna oraz jasno wskazują nazwy scheme i destination.
4. Kluczowe wzorce i zasady
## Key Patterns
### Observable Architecture
- ALL view models use `@Observable` (NEVER `ObservableObject`)
- ALL navigation uses `NavigationStack` (NEVER `NavigationView`)
- State management via `@Observable` classes with `@MainActor` isolation
### Settings Pattern
- Centralized `Settings.shared` singleton
- All settings bounded to valid ranges with validation
- Sound names validated against whitelist
- Thread-safe access via @MainActor
### Audio System
- `AVAudioPlayer` with `.playback` category (plays in silent mode)
- Silent audio loop for background execution
- Bell playback with completion callbacks and token-based staleness
Te wzorce zapobiegają wprowadzaniu przez agenta niespójności. Bez jawnej dokumentacji wzorców agent czasem użyje ObservableObject w jednym pliku i @Observable w innym albo utworzy nowy mechanizm ustawień zamiast użyć istniejącego singletona Settings.shared.
5. Rzeczy, których agent nigdy nie może robić
## Rules
- **NEVER modify .pbxproj files** — create Swift files, then I will add them to Xcode manually
- **NEVER modify .xcodeproj/ contents directly**
- **NEVER add new package dependencies** without asking first
- **NEVER change the deployment target**
- **NEVER modify entitlements files** unless explicitly asked
- **NEVER use NavigationView** — always NavigationStack
- **NEVER use ObservableObject** — always @Observable
- **NEVER use @StateObject** — always @State with @Observable
Jawne zakazy są skuteczniejsze niż domyślne oczekiwania. Agent pewniej przestrzega ograniczeń negatywnych niż pozytywnych sugestii, ponieważ są binarne (zrób / nie rób), a nie heurystyczne (preferuj to / czasem użyj tamtego).
6. Kontekst specyficzny dla frameworka
Ta sekcja różni się w zależności od aplikacji. Warto ją uwzględnić dla każdego frameworka, który ma nieoczywistą konfigurację:
Dla aplikacji HealthKit:
## HealthKit Configuration
- Entitlement: `com.apple.developer.healthkit`
- Info.plist keys:
- `NSHealthShareUsageDescription`: "Return reads your mindful minutes..."
- `NSHealthUpdateUsageDescription`: "Return logs meditation sessions..."
- Category types: `HKCategoryType(.mindfulSession)`
- Authorization checked on every write (user can revoke at any time)
- HealthKit is unavailable on tvOS — guard with `#if canImport(HealthKit)`
Dla aplikacji SwiftData:
## SwiftData Models
### Model Relationships
- `GroceryList` has many `GroceryItem` (cascade delete)
- `GroceryItem` belongs to one `GroceryList`
- `GroceryItem` has optional `Category`
### Model Container Setup
- Configured in App struct with `modelContainer(for:)`
- Schema versioning: currently V2
- Migration plan: `GroceryMigrationPlan` handles V1 → V2
### Queries
- `@Query(sort: \GroceryItem.name)` for sorted fetches
- `@Query(filter: #Predicate { !$0.isCompleted })` for active items
- Always use `@Query` in views, `modelContext.fetch()` in managers
Dla aplikacji SpriteKit:
## SpriteKit Scene Hierarchy
```
GameScene (SKScene)
├── backgroundLayer (SKNode, zPosition: -100)
│ └── StarfieldNode (custom, parallax scrolling)
├── gameLayer (SKNode, zPosition: 0)
│ ├── playerShip (PlayerNode, zPosition: 10)
│ ├── enemyContainer (SKNode, zPosition: 5)
│ └── bulletPool (SKNode, zPosition: 8)
├── effectsLayer (SKNode, zPosition: 50)
│ └── ParticleManager (manages explosion/trail emitters)
└── hudLayer (SKNode, zPosition: 100)
├── scoreLabel (SKLabelNode)
└── healthBar (HealthBarNode)
```
- Physics categories defined in `PhysicsCategory.swift` as bitmasks
- Contact detection via `didBegin(_ contact:)` on GameScene
- Bullet pooling: pre-allocate 50, recycle via `removeFromParent()` + re-add
Dla aplikacji Metal:
## Metal Pipeline
- Render pipeline: `MetalView` → `Renderer` → `ShaderLibrary`
- Compute pipeline: `AudioAnalyzer` → compute shader → texture output
- Shared uniforms struct: `Uniforms` in `ShaderTypes.h` (bridged to Swift)
- Frame timing: `CADisplayLink` drives render loop
- Buffer triple-buffering: 3 in-flight frames with semaphore
### Shader Files
- `Shaders.metal` — Main render shaders (vertex + fragment)
- `Compute.metal` — Audio analysis compute kernel
- `PostProcess.metal` — Bloom and color grading
### DO NOT modify Metal shaders without testing on device.
Simulator Metal is not representative of device GPU behavior.
Rzeczywisty CLAUDE.md: Banana List (SwiftUI + SwiftData + iCloud + serwer MCP)
Oto przykład z adnotacjami pokazujący, jak wszystkie 6 sekcji współdziała w umiarkowanie złożonej aplikacji. To wzorzec CLAUDE.md, którego używam dla Banana List, 53-plikowej aplikacji listy zakupów z synchronizacją iCloud oraz niestandardowym serwerem MCP, który udostępnia dane aplikacji dla Claude Desktop:
# Banana List - Grocery List App
**Bundle ID:** `com.941apps.BananaList`
**Target:** iOS 26+
**Architecture:** SwiftUI + SwiftData + iCloud Drive sync
**Swift version:** 6.2
**Minimum deployment:** iOS 26.0
## Core Features
- Grocery lists with items, categories, and quantities
- iCloud Drive sync via SwiftData CloudKit integration
- Custom MCP server exposing list data to Claude Desktop
- Liquid Glass design system
- Haptic feedback on interactions
- Share sheets for list sharing
## File Structure
```
BananaList/
├── BananaListApp.swift # App entry, model container setup
├── Models/
│ ├── GroceryList.swift # @Model: list with name, items, color
│ ├── GroceryItem.swift # @Model: item with name, quantity, category, isCompleted
│ ├── Category.swift # @Model: user-defined categories
│ └── SampleData.swift # Preview and test data
├── Views/
│ ├── ListsView.swift # Main list of grocery lists
│ ├── ListDetailView.swift # Items within a list
│ ├── ItemRow.swift # Single item row with swipe actions
│ ├── AddItemSheet.swift # New item form
│ ├── CategoryPicker.swift # Category selection with create-new
│ └── SettingsView.swift # App settings
├── Managers/
│ ├── CloudSyncManager.swift # iCloud Drive sync status and conflict resolution
│ └── HapticManager.swift # UIImpactFeedbackGenerator wrapper
├── MCP/
│ ├── MCPServer.swift # MCP server for Claude Desktop integration
│ ├── ListTools.swift # MCP tools: list CRUD operations
│ └── ItemTools.swift # MCP tools: item CRUD operations
└── Extensions/
├── Color+Extensions.swift # Custom color definitions
└── View+Extensions.swift # Reusable view modifiers
```
## SwiftData Models
### Relationships
- `GroceryList` has many `GroceryItem` (cascade delete)
- `GroceryItem` belongs to one `GroceryList` (required)
- `GroceryItem` has optional `Category`
- `Category` has many `GroceryItem` (nullify on delete)
### Container Setup
```swift
@main
struct BananaListApp: App {
var body: some Scene {
WindowGroup {
ListsView()
}
.modelContainer(for: [GroceryList.self, GroceryItem.self, Category.self])
}
}
```
### Query Patterns
- Lists: `@Query(sort: \GroceryList.name) var lists: [GroceryList]`
- Active items: `@Query(filter: #Predicate { !$0.isCompleted })`
- By category: filter in-memory after fetch (SwiftData predicate limitations)
## Build & Test
```bash
xcodebuild -scheme BananaList -destination 'platform=iOS Simulator,name=iPhone 16 Pro' build
xcodebuild -scheme BananaList -destination 'platform=iOS Simulator,name=iPhone 16 Pro' test
```
Prefer MCP tools (`build_sim`, `test_sim`) over raw commands.
## Key Patterns
### Observable + SwiftData
- SwiftData `@Model` classes are automatically Observable
- DO NOT add `@Observable` to `@Model` classes (redundant, causes warnings)
- Use `@Bindable` for two-way bindings to model properties in forms
- Use `@Query` in views, `modelContext.fetch()` in non-view code
### iCloud Sync
- Automatic via SwiftData CloudKit integration
- Conflict resolution: last-write-wins (CloudKit default)
- Sync status exposed via `CloudSyncManager.shared.syncState`
- Test sync by running on two simulators with same iCloud account
### MCP Server Architecture
- Runs as a local WebSocket server on port 8765
- Exposes 6 tools: listAll, getList, createList, addItem, completeItem, deleteItem
- Claude Desktop connects via MCP config in `~/.config/claude-desktop/config.json`
## Rules
- NEVER modify .pbxproj or .xcodeproj contents
- NEVER change the model schema without updating SampleData.swift
- NEVER use `ObservableObject` — SwiftData models are already Observable
- NEVER use `@StateObject` — use `@State` with `@Observable` classes
- NEVER use `NavigationView` — always `NavigationStack`
- NEVER add `@Observable` macro to `@Model` classes
- ALWAYS use `@Bindable` for form bindings to model properties
- ALWAYS test iCloud sync changes on two simulator instances
Rzeczywisty CLAUDE.md: Reps (minimalna aplikacja SwiftData — 14 plików)
W małych projektach CLAUDE.md może być zwięzły. Oto wzorzec dla Reps, 14-plikowego trackera treningów. Warto zauważyć, że nawet krótki CLAUDE.md obejmuje wszystkie 6 niezbędnych sekcji:
# Reps - Workout Tracking
**Bundle ID:** `com.941apps.Reps`
**Target:** iOS 26+
**Architecture:** SwiftUI + SwiftData
**Swift version:** 6.2
## File Structure
```
Reps/
├── RepsApp.swift # App entry, model container
├── Models/
│ ├── Workout.swift # @Model: workout with exercises, date, duration
│ ├── Exercise.swift # @Model: exercise with sets, reps, weight
│ └── ExerciseTemplate.swift # @Model: saved exercise definitions
├── Views/
│ ├── WorkoutListView.swift # Main list of workouts
│ ├── WorkoutDetailView.swift # Exercises within a workout
│ ├── ExerciseRow.swift # Single exercise with inline editing
│ ├── AddExerciseSheet.swift # Exercise selection from templates
│ ├── NewWorkoutView.swift # Start new workout flow
│ └── StatsView.swift # Progress charts and summaries
├── Managers/
│ └── WorkoutTimer.swift # Active workout timer
└── Extensions/
└── Date+Extensions.swift # Formatting helpers
```
## Build & Test
```bash
xcodebuild -scheme Reps -destination 'platform=iOS Simulator,name=iPhone 16 Pro' build
xcodebuild -scheme Reps -destination 'platform=iOS Simulator,name=iPhone 16 Pro' test
```
## SwiftData Relationships
- `Workout` has many `Exercise` (cascade delete)
- `Exercise` has optional `ExerciseTemplate`
- `ExerciseTemplate` standalone (nullify on exercise delete)
## Rules
- NEVER modify .pbxproj
- NEVER use ObservableObject — use @Observable
- NEVER use NavigationView — use NavigationStack
- @Model classes are already Observable — do not add @Observable macro
- Use @Bindable for form bindings to model properties
To 40 linii CLAUDE.md dla 14-plikowego projektu. Ich napisanie zajmuje 10 minut i oszczędza godziny dezorientacji agenta.
Rzeczywisty CLAUDE.md: Starfield Destroyer (SpriteKit + Metal — 32 pliki)
Projekty gier wymagają szerszego kontekstu specyficznego dla frameworków. Agent musi rozumieć graf sceny, kategorie fizyki i maszynę stanów gry:
# Starfield Destroyer - Space Shooter
**Bundle ID:** `com.941apps.StarfieldDestroyer`
**Target:** iOS 26+
**Architecture:** SpriteKit + Metal post-processing + Game Center
**Swift version:** 6.2
## Game Overview
99 levels across 3 galaxies. 8 unlockable ships with different stats.
Game Center leaderboards and achievements. Metal shader post-processing
for bloom and screen effects.
## File Structure
```
StarfieldDestroyer/
├── StarfieldDestroyerApp.swift # App entry, Game Center auth
├── GameScene.swift # Main game scene, update loop
├── MenuScene.swift # Title screen, ship selection
├── Entities/
│ ├── PlayerShip.swift # Player node with physics, weapons, shields
│ ├── EnemyShip.swift # Enemy base class with AI behaviors
│ ├── Bullet.swift # Bullet pool node
│ ├── PowerUp.swift # Collectible power-ups
│ └── Boss.swift # Boss enemies (levels 33, 66, 99)
├── Systems/
│ ├── LevelManager.swift # Level progression, wave spawning
│ ├── PhysicsCategory.swift # UInt32 bitmask categories
│ ├── CollisionHandler.swift # Contact delegate methods
│ ├── ScoreManager.swift # Score tracking, multipliers
│ ├── ParticleManager.swift # Explosion, trail, shield emitters
│ └── AudioManager.swift # Sound effects, background music
├── UI/
│ ├── HUDNode.swift # Score, health, level display
│ ├── ShipSelectView.swift # SwiftUI ship selection (UIHostingController)
│ ├── GameOverView.swift # Game over screen with score submission
│ └── PauseMenu.swift # Pause overlay
├── Metal/
│ ├── MetalRenderer.swift # Post-processing render pipeline
│ ├── BloomShader.metal # Bloom post-process effect
│ └── ShaderTypes.h # Shared uniforms (bridging header)
├── Data/
│ ├── ShipData.swift # 8 ship definitions (speed, damage, shields)
│ ├── LevelData.swift # 99 level configurations
│ └── AchievementData.swift # Game Center achievement definitions
└── GameCenterManager.swift # Leaderboard/achievement submission
```
## SpriteKit Scene Hierarchy
```
GameScene (SKScene)
├── backgroundLayer (zPosition: -100)
│ └── StarfieldNode (parallax scrolling, 3 layers)
├── gameLayer (zPosition: 0)
│ ├── playerShip (zPosition: 10)
│ ├── enemyContainer (zPosition: 5)
│ ├── bulletPool (zPosition: 8) — pre-allocated 50 bullets
│ └── powerUpContainer (zPosition: 3)
├── effectsLayer (zPosition: 50)
│ └── ParticleManager (explosion + trail emitters)
└── hudLayer (zPosition: 100)
├── scoreLabel (SKLabelNode)
├── healthBar (custom SKShapeNode)
└── levelLabel (SKLabelNode)
```
## Physics Categories
```swift
struct PhysicsCategory {
static let none: UInt32 = 0
static let player: UInt32 = 0b1 // 1
static let enemy: UInt32 = 0b10 // 2
static let bullet: UInt32 = 0b100 // 4
static let powerUp: UInt32 = 0b1000 // 8
static let shield: UInt32 = 0b10000 // 16
static let bossBullet:UInt32 = 0b100000 // 32
}
// Contact pairs:
// player + enemy → damage
// player + powerUp → collect
// bullet + enemy → destroy
// player + bossBullet → damage
```
## Game State Machine
```
.menu → .playing → .paused → .playing
→ .gameOver → .menu
→ .bossIntro → .playing
→ .levelComplete → .playing (next level)
```
## Metal Post-Processing
- Bloom shader: `BloomShader.metal` — multi-pass Gaussian blur + additive blend
- Uniforms: `PostProcessUniforms { float intensity; float threshold; float2 resolution; }`
- Applied after SpriteKit renders each frame via `SKView.presentScene(:transition:)`
- DO NOT modify Metal shaders without testing on device
## Build & Test
```bash
xcodebuild -scheme StarfieldDestroyer -destination 'platform=iOS Simulator,name=iPhone 16 Pro' build
xcodebuild -scheme StarfieldDestroyer -destination 'platform=iOS Simulator,name=iPhone 16 Pro' test
```
## Rules
- NEVER modify .pbxproj
- NEVER modify PhysicsCategory bitmasks (breaks all collision detection)
- NEVER change the scene hierarchy z-ordering without understanding render order
- NEVER modify ShaderTypes.h without updating both Swift and Metal references
- Add new enemies by subclassing EnemyShip, not by modifying it
- Bullet pooling: recycle via removeFromParent() + re-add, never allocate new
- Game Center: always check isAuthenticated before submitting scores
Rzeczywisty CLAUDE.md: amp97 (Metal + wizualizacja audio — 41 plików)
Projekty Metal potrzebują najwięcej kontekstu specyficznego dla frameworka, ponieważ agenci nie mogą zweryfikować wyniku wizualnego:
# amp97 - Audio Visualizer
**Bundle ID:** `com.941apps.amp97`
**Target:** iOS 26+
**Architecture:** Metal render pipeline + AVAudioEngine analysis
**Swift version:** 6.2
## Architecture
```
Audio Input (microphone/file)
→ AVAudioEngine tap
→ FFT (vDSP)
→ Frequency/amplitude buffers
→ Metal compute shader (analysis)
→ Metal render pipeline (visualization)
→ CADisplayLink (60fps)
→ MTKView
```
## File Structure
```
amp97/
├── amp97App.swift # App entry
├── Audio/
│ ├── AudioEngine.swift # AVAudioEngine setup, tap installation
│ ├── FFTProcessor.swift # vDSP FFT, frequency bin extraction
│ ├── AudioBuffer.swift # Ring buffer for audio data
│ └── MicrophoneManager.swift # Microphone permission, session config
├── Rendering/
│ ├── MetalView.swift # MTKView wrapper for SwiftUI
│ ├── Renderer.swift # Main render loop, pipeline state
│ ├── ShaderLibrary.swift # Compiled shader management
│ ├── BufferManager.swift # Triple-buffered uniform updates
│ └── TextureManager.swift # Offscreen render targets
├── Shaders/
│ ├── Shaders.metal # Vertex + fragment shaders
│ ├── AudioCompute.metal # Audio analysis compute kernel
│ ├── PostProcess.metal # Bloom, color grading
│ └── ShaderTypes.h # Shared uniforms (bridging header)
├── Visualizations/
│ ├── WaveformViz.swift # Oscilloscope-style waveform
│ ├── SpectrumViz.swift # Frequency spectrum bars
│ ├── CircularViz.swift # Radial visualization
│ └── VizSelector.swift # Visualization switching
├── Views/
│ ├── MainView.swift # Full-screen viz with overlays
│ ├── ControlsOverlay.swift # Play/pause, viz selection, gain
│ └── SettingsView.swift # Audio source, sensitivity
└── Extensions/
├── SIMD+Extensions.swift # Vector math helpers
└── Color+Metal.swift # UIColor → float4 conversion
```
## Metal Pipeline
### Uniforms (ShaderTypes.h)
```c
typedef struct {
float time;
float2 resolution;
float audioLevel; // 0.0-1.0 RMS amplitude
float frequencyBins[64]; // FFT output, normalized
float4x4 transform;
} Uniforms;
```
### Render Pipeline
1. Compute pass: AudioCompute.metal processes FFT data → texture
2. Render pass: Shaders.metal reads texture + uniforms → visualization
3. Post-process pass: PostProcess.metal applies bloom → final output
### Buffer Management
- Triple buffering with DispatchSemaphore(value: 3)
- Uniforms updated per-frame on CPU, consumed by GPU 1-2 frames later
- Audio data ring buffer: 4096 samples, lock-free single producer/consumer
## Rules
- NEVER modify ShaderTypes.h without updating BOTH Swift and Metal sides
- NEVER exceed 64 frequency bins (fixed buffer size in shader)
- NEVER test Metal visual output in simulator — device only
- NEVER modify the audio engine tap format (48kHz, mono, float32)
- Triple buffer discipline: always signal semaphore in completion handler
- Audio session: .playAndRecord category with .defaultToSpeaker option
Skalowanie CLAUDE.md wraz z rozmiarem projektu
Właściwy poziom szczegółowości zależy od liczby plików i złożoności frameworków:
| Rozmiar projektu | Głębokość CLAUDE.md | Przykład |
|---|---|---|
| Mały (< 20 plików) | Tożsamość + lista plików + zasady | Reps (14 plików): podstawowe wzorce SwiftData, polecenia budowania, zakazy |
| Średni (20-40 plików) | + kontekst frameworka + kluczowe wzorce | TappyColor (30 plików): hierarchia scen SpriteKit, kategorie fizyki, pętla gry |
| Duży (40+ plików) | + diagramy architektury + mapy relacji + informacje o wielu targetach | Return (63 pliki): architektura wieloplatformowa, diagram synchronizacji sesji, różnice per platforma |
| Wyspecjalizowany (Metal/GPU) | + diagramy pipeline + definicje typów współdzielonych + układy buforów | amp97 (41 plików): etapy render pipeline, struktura uniform, zarządzanie buforami |
Koszt nadmiernej dokumentacji jest bliski zeru (agent pomija to, czego nie potrzebuje). Koszt niedostatecznej dokumentacji jest wysoki (agent wymyśla wzorce sprzeczne z Państwa codebase).
Lista kontrolna CLAUDE.md
Warto używać tej listy kontrolnej podczas tworzenia lub audytu CLAUDE.md dla projektu iOS:
- [ ] Określono Bundle ID i deployment target
- [ ] Podano wersję Swift i nazwę wzorca architektury
- [ ] Struktura plików zawiera adnotacje celu inline
- [ ] Polecenie budowania ma poprawny scheme i destination
- [ ] Polecenie testowania ma poprawny scheme i destination
- [ ] Odnotowano preferencję MCP („prefer build_sim over xcodebuild”)
- [ ] Reguła @Observable (nigdy ObservableObject)
- [ ] Reguła NavigationStack (nigdy NavigationView)
- [ ] Zakaz .pbxproj
- [ ] Kontekst specyficzny dla frameworka (uprawnienia HealthKit, relacje SwiftData, hierarchia SpriteKit, pipeline Metal)
- [ ] Udokumentowano ograniczenia dostępności platform (#if canImport, #if os)
- [ ] Udokumentowano kluczowe singletony i współdzielone wzorce
- [ ] Odnotowano znane ograniczenia lub pułapki
Pierwsza sesja z agentem
Po skonfigurowaniu MCP i dodaniu CLAUDE.md w projekcie poniżej znajduje się przebieg skutecznej pierwszej sesji. W przykładzie użyto Claude Code CLI, ale ten workflow sprawdza się w dowolnym środowisku uruchomieniowym.
Krok 1: sprawdzenie, czy agent widzi projekt
You: Summarize this project. What scheme should I build with?
Claude: [reads CLAUDE.md]
[calls discover_projs via MCP]
[calls list_schemes via MCP]
This is Return, a zen meditation timer for iOS 26+, watchOS, and tvOS.
Available schemes: Return, ReturnWatch, ReturnTV, ReturnTests.
Primary scheme for iOS: Return.
Jeśli agent nie odwołuje się do treści CLAUDE.md, należy sprawdzić, czy plik znajduje się w katalogu głównym projektu (tym samym folderze co .xcodeproj lub Package.swift).
Krok 2: uruchomienie kontrolnego builda
You: Build the Return scheme for iOS simulator and report results.
Claude: [calls list_sims — finds iPhone 16 Pro on iOS 26.2]
[calls boot_sim — boots the simulator]
[calls build_sim — builds the project]
Build succeeded. 63 source files compiled.
2 warnings:
- HomeView.swift:132 — UIScreen.main deprecated in iOS 26.0
- LogWaterIntent.swift:61 — Result of try? is unused
0 errors.
Krok 3: uruchomienie testów
You: Run all tests and report pass/fail.
Claude: [calls test_sim]
12 tests executed:
✓ TimerManagerTests (5/5 passed)
✓ SettingsTests (4/4 passed)
✓ ConstantsTests (3/3 passed)
All tests passed.
Krok 4: zaimplementowanie funkcji
You: Add a new "Rain" theme to the theme system. Follow the existing
pattern in Theme.swift and ThemeManager.swift. Include a rain
ambient sound. Build and test after implementation.
Claude: [reads Theme.swift — understands Theme struct pattern]
[reads ThemeManager.swift — understands theme registration]
[reads existing theme definitions]
[adds Rain theme to Theme.swift following existing pattern]
[registers Rain theme in ThemeManager.swift]
[calls build_sim — build succeeds]
[calls test_sim — all tests pass]
Added Rain theme:
- Theme.swift: new `static let rain` with video, cover, ambient
- ThemeManager.swift: added to `allThemes` array
- Build: success (0 errors, 2 existing warnings)
- Tests: 12/12 passed
Note: You'll need to add rain_ambient.wav to the project
and add the new Theme.swift changes to the Xcode target manually
(I did not modify .pbxproj).
Uwaga agenta o niemodyfikowaniu .pbxproj wynika z reguł w CLAUDE.md. Bez tej reguły agent próbowałby zmodyfikować plik projektu i prawdopodobnie go uszkodził.
W czym agenci dobrze sprawdzają się w iOS
To zadania, w których agenci konsekwentnie dostarczają poprawne, produkcyjnej jakości rezultaty przy minimalnej weryfikacji przez człowieka.
Widoki i modyfikatory SwiftUI
Agenci bardzo dobrze rozpoznają wzorce deklaratywnej składni SwiftUI. Kompozycja widoków, łańcuchy modyfikatorów, wiązania stanu i layout — te elementy dobrze pasują do danych treningowych agenta, ponieważ zakres API w SwiftUI jest dobrze udokumentowany, a wzorce są bardzo spójne.
W czym agenci są szczególnie skuteczni:
- Tworzenie nowych widoków na podstawie opisu („utwórz arkusz ustawień z przełącznikami dla X, Y, Z”)
- Stosowanie łańcuchów modyfikatorów (.glassEffect(), .sensoryFeedback(), .navigationTitle())
- Konwertowanie między wzorcami layoutu (VStack na LazyVGrid, List na ScrollView)
- Implementowanie wiązań formularzy @Bindable z modelami SwiftData
- Tworzenie preview providers z przykładowymi danymi
Przykładowy prompt, który daje bardzo dobre wyniki:
Create a SettingsView that matches the existing pattern in SettingsSheet.swift.
Include toggles for:
- Enable haptic feedback (Settings.shared.hapticsEnabled)
- Enable HealthKit logging (Settings.shared.healthKitEnabled)
- Show session history (navigation link to SessionHistoryView)
Use Liquid Glass styling with .glassEffect() on section backgrounds.
Follow the @Observable pattern, not ObservableObject.
Konkretność ma znaczenie. „Utwórz widok ustawień” daje generyczny rezultat. „Utwórz SettingsView zgodny z istniejącym wzorcem w SettingsSheet.swift” daje wynik spójny z bazą kodu projektu.
Modele i zapytania SwiftData
Agenci niezawodnie obsługują makro @Model w SwiftData, relacje oraz wzorce @Query. Deklaratywny charakter frameworka (podobny do Django ORM lub SQLAlchemy) dobrze odpowiada wzorcom, które agent widział w wielu bazach kodu.
W czym agenci są szczególnie skuteczni:
- Definiowanie klas @Model z relacjami
- Pisanie @Query z deskryptorami sortowania i predykatami
- Implementowanie operacji CRUD przez modelContext
- Plany migracji między wersjami schematu
- Dane do preview i fixtures testowe
Gdzie agenci potrzebują wskazówek:
- Złożone wyrażenia #Predicate (DSL predykatów SwiftData ma ograniczenia, których agent nie zawsze jest świadomy — znane ograniczenia warto udokumentować w CLAUDE.md)
- Konfiguracja synchronizacji CloudKit (automatyczna przez SwiftData, ale agent może próbować implementować synchronizację ręcznie)
Testy jednostkowe
Testy jednostkowe pisane przez agentów są konsekwentnie wysokiej jakości w projektach iOS. Agent rozumie wzorce XCTest, asynchroniczne metody testowe oraz cykl życia setup/teardown.
Write unit tests for TimerManager covering:
1. Initial state is .stopped
2. start() transitions to .running
3. pause() transitions to .paused
4. reset() returns to .stopped with original duration
5. Timer counts down correctly (test with 3-second duration)
Agent tworzy dobrze ustrukturyzowane przypadki testowe XCTest z setUp() i tearDown(), odpowiednimi asercjami oraz obsługą async dla testów opartych na timerach.
Refaktoryzacja i stosowanie wzorców
Agenci świetnie radzą sobie z mechaniczną refaktoryzacją: wydzielaniem widoków do komponentów, konwersją ObservableObject na @Observable, migracją z NavigationView do NavigationStack oraz spójnym stosowaniem wzorców w wielu plikach.
Refactor all views in the Views/ directory to use @Observable instead of
ObservableObject. Update @StateObject to @State, @ObservedObject to direct
property access, and @Published to plain properties.
Agent metodycznie przechodzi przez każdy plik, poprawnie stosuje transformację i zachowuje istniejącą funkcjonalność. To praca o wysokiej dźwigni — refaktoryzacja, która ręcznie zajęłaby godzinę, z agentem kończy się w kilka minut z niemal idealną dokładnością.
Diagnozowanie błędów builda przez MCP
Dzięki ustrukturyzowanemu wyjściu MCP agenci diagnozują błędy builda szybciej niż większość programistów. Agent odczytuje JSON błędu, identyfikuje dokładny plik i wiersz, rozumie komunikat błędu i stosuje poprawkę — często w jednej turze.
Błędy, które agenci naprawiają autonomicznie: - Brakujące importy - Niezgodności typów - Braki w zgodności z protokołami - Użycie przestarzałego API (z zamiennikiem) - Brakujące wymagane parametry inicjalizatora - Naruszenia kontroli dostępu
Błędy, przy których agenci potrzebują pomocy: - Niejednoznaczne rozwiązywanie typów (wiele modułów definiuje ten sam typ) - Złożone błędy ograniczeń generycznych - Błędy rozwijania makr (agent nie widzi rozwiniętego wyjścia makra)
Zarządzanie symulatorem
Agenci dobrze obsługują cykl życia symulatora przez MCP:
Boot an iPhone 16 Pro simulator on iOS 26, install the app, and take a screenshot.
Agent wywołuje list_sims, aby znaleźć dostępne środowiska wykonawcze, boot_sim, aby uruchomić symulator, build_sim, aby zbudować i zainstalować aplikację, oraz screenshot, aby wykonać zrzut ekranu — wszystko przez ustrukturyzowane wywołania MCP.
Z czym agenci radzą sobie słabo w iOS
Uczciwe podsumowanie miejsc, w których agenci zawodzą. Znajomość tych granic zapobiega frustracji i marnowaniu tokenów.
Modyfikacje pliku .pbxproj — NIGDY
To najważniejsza zasada w tworzeniu iOS z użyciem agentów. Plik .pbxproj to konfiguracja projektu Xcode — ustrukturyzowany plik tekstowy z odwołaniami UUID, listami faz budowania i przynależnością do targetów. Formalnie jest czytelny dla człowieka, ale w praktyce agenci AI nie są w stanie go niezawodnie parsować.
Dlaczego agenci zawodzą przy .pbxproj: - Plik używa niestandardowego formatu (nie JSON, nie YAML, nie XML) o znaczeniu zależnym od położenia - Każdy wpis jest powiązany przez UUID — dodanie pliku wymaga spójnej aktualizacji 3–5 różnych sekcji - Jeden źle umieszczony znak uszkadza cały plik projektu - Rozwiązywanie konfliktów scalania w .pbxproj przez Xcode i tak jest kruche — edycje agenta tylko to pogarszają
Co się dzieje, gdy agent edytuje .pbxproj: 1. Edycja wygląda na udaną (agent zgłasza „file updated”) 2. Xcode odmawia otwarcia projektu („The project file is corrupted”) 3. Trzeba poświęcić 15–60 minut na odzyskiwanie z historii git 4. Wtedy staje się jasne, że warto dodać hook PreToolUse (zob. Hooki)
Workflow: Agent tworzy pliki Swift. Następnie należy dodać je ręcznie do projektu Xcode (przeciągnąć do Xcode albo użyć File > Add Files). Zajmuje to 5 sekund na plik i zapobiega godzinom odzyskiwania projektu.
W przypadku projektów Swift Package Manager: To ograniczenie jest mniej dotkliwe. Package.swift to standardowy plik Swift, który agenci mogą edytować niezawodnie. Jeśli projekt korzysta wyłącznie z SPM (bez .xcodeproj), agent może zarządzać pełną strukturą projektu.
Złożone edycje Interface Builder / Storyboard
Jeśli projekt używa Interface Builder (pliki .xib) albo Storyboardów (pliki .storyboard), agenci nie potrafią edytować ich w sensowny sposób. Są to pliki XML z automatycznie generowanymi UUID, odwołaniami do constraints i połączeniami outlets, zaprojektowane do edycji wizualnej, a nie tekstowej.
Ograniczenie ryzyka: Do nowych widoków należy używać wyłącznie SwiftUI. Jeśli projekt ma starsze pliki Interface Builder, najlepiej zostawić je bez zmian i budować nowy UI w SwiftUI.
Optymalizacja wydajności
Agenci piszą poprawny kod, ale niekoniecznie kod wydajny. Nie potrafią profilować aplikacji, identyfikować wąskich gardeł ani mierzyć liczby klatek na sekundę. Optymalizacja wydajności wymaga:
- Profilowania w Instruments (narzędzie wizualne, niedostępne dla agenta)
- Zrozumienia charakterystyki GPU/CPU konkretnego urządzenia
- Iteracyjnych zmian opartych na pomiarach
Gdzie to widać:
- Optymalizacja shaderów Metal (agent pisze poprawny Metal, ale nie może zmierzyć czasu klatki GPU)
- Złożoność body widoku SwiftUI (agent tworzy głęboko zagnieżdżone widoki, które powodują narzut przy ponownym rysowaniu)
- Optymalizacja zapytań Core Data / SwiftData (agent pisze poprawne zapytania, które mogą być wolne na dużych zbiorach danych)
Ograniczenie ryzyka: Agenci sprawdzają się przy implementacji, ale profilowanie należy wykonać ręcznie w Instruments, a następnie poprosić agenta o zastosowanie konkretnych, zidentyfikowanych optymalizacji.
Code signing i provisioning
Agenci nie potrafią debugować problemów z code signing poza odczytaniem komunikatu błędu. Zarządzanie provisioning profile, tworzenie certyfikatów, konfiguracja entitlements i wysyłanie do App Store to zasadniczo workflow wykonywane przez człowieka, obejmujące portal Apple Developer, Keychain Access oraz UI podpisywania w Xcode.
Co widzi agent: „Signing for ‘Return’ requires a development team.”
Czego agent nie widzi: Czy certyfikat wygasł, czy provisioning profile obejmuje urządzenie, czy bundle ID pasuje do App ID albo czy plik entitlements jest poprawny.
Ograniczenie ryzyka: Całe podpisywanie należy obsługiwać w karcie Signing & Capabilities w Xcode. Nie należy prosić agentów o debugowanie błędów podpisywania.
Złożone debugowanie shaderów Metal
Agenci piszą składniowo poprawny Metal Shading Language (MSL), ale nie potrafią zweryfikować wyniku wizualnego ani debugować problemów po stronie GPU. Shadery Metal wykonują się na GPU — agent nie ma mechanizmu informacji zwrotnej, który pozwalałby stwierdzić, czy shader daje poprawny wynik wizualny.
Co agenci mogą zrobić z Metal:
- Napisać shadery vertex i fragment na podstawie opisów
- Skonfigurować pipeline renderowania Metal w Swift
- Tworzyć compute shaders do operacji równoległych na danych
- Naprawiać błędy kompilacji w plikach .metal
Czego agenci nie mogą zrobić z Metal: - Zweryfikować poprawności wizualnej wyniku shadera - Debugować wydajności GPU (czas klatki, occupancy, przepustowość pamięci) - Diagnozować artefaktów wizualnych (banding, problemy z precyzją, nieprawidłowa przestrzeń kolorów) - Testować na różnych architekturach GPU (różnice zachowania między A-series a M-series)
Ograniczenie ryzyka: Shadery Metal należy testować na fizycznych urządzeniach. Implementacja Metal w Simulatorze nie odzwierciedla zachowania GPU na urządzeniu. Do debugowania wizualnego warto używać GPU Frame Capture w Xcode.
Weryfikacja układu wizualnego
Agenci nie widzą UI aplikacji. Piszą kod układu SwiftUI i mogą sprawdzić, czy się kompiluje, ale nie potrafią ocenić, czy wynikowy ekran wygląda poprawnie. Widok przesunięty o 10 pikseli od środka, używający niewłaściwej grubości fontu albo mający nakładające się elementy nie generuje błędu budowania i przechodzi wszystkie testy logiki.
Ograniczenie ryzyka: Zmiany UI należy sprawdzać wizualnie. Do weryfikacji układu warto używać SwiftUI Previews w Xcode (albo RenderPreview przez Apple MCP do renderowania headless). W przypadku automatycznego wykrywania regresji wizualnych warto rozważyć snapshot testing z bibliotekami takimi jak swift-snapshot-testing.
Hooki w tworzeniu aplikacji iOS
Hooki to polecenia powłoki, które wykonują się deterministycznie w określonych punktach przepływu pracy agenta. Są mechanizmem egzekwowania zasad — różnicą między „proszę nie edytować .pbxproj” (sugestią, którą agent może zignorować) a „nie można edytować .pbxproj” (twardą blokadą).
Kontekst dotyczący systemu hooków znajduje się w przewodniku po hookach Claude Code. Ta sekcja omawia wzorce hooków specyficzne dla iOS.
PreToolUse: blokowanie zapisu do .pbxproj
Najważniejszy hook w każdym projekcie iOS. Blokuje agentowi możliwość zapisu do plików .pbxproj, katalogów .xcodeproj/ oraz innych plików zarządzanych przez Xcode:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Edit|Write",
"command": "bash -c 'INPUT=$(cat); FP=$(echo \"$INPUT\" | jq -r \".tool_input.file_path // empty\"); if echo \"$FP\" | grep -qE \"\\.(pbxproj|xcworkspace|xib|storyboard)$|xcodeproj/|xcworkspace/\"; then echo \"BLOCKED: Do not modify Xcode project files. Create Swift files and add to Xcode manually.\" >&2; exit 2; fi'"
}
]
}
}
Należy umieścić to w .claude/settings.json w katalogu głównym projektu albo w ~/.claude/settings.json, aby uzyskać ochronę globalną.
Jak to działa: Gdy agent próbuje użyć narzędzia Edit lub Write na dowolnym pliku pasującym do wzorca, hook się uruchamia, wykrywa ścieżkę pliku, wypisuje ostrzeżenie do stderr i kończy działanie z kodem 2 (co blokuje użycie narzędzia). Agent otrzymuje komunikat o błędzie i dostosowuje swoje podejście.
Co wykrywa:
- Bezpośrednie edycje .pbxproj
- Dowolny plik w katalogach .xcodeproj/ lub .xcworkspace/
- Pliki Interface Builder (.xib, .storyboard)
PostToolUse: formatowanie przy zapisie za pomocą SwiftFormat
Automatyczne formatowanie plików Swift za każdym razem, gdy agent je zapisuje lub edytuje:
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"command": "bash -c 'INPUT=$(cat); FP=$(echo \"$INPUT\" | jq -r \".tool_input.file_path // empty\"); if echo \"$FP\" | grep -qE \"\\.swift$\"; then swiftformat \"$FP\" --quiet 2>/dev/null; fi'"
}
]
}
}
Wymagania: SwiftFormat musi być zainstalowany (brew install swiftformat).
Dlaczego to ważne: Agenci generują składniowo poprawny Swift, ale nie zawsze konsekwentnie przestrzegają konwencji formatowania. SwiftFormat normalizuje wcięcia, położenie nawiasów klamrowych oraz kolejność importów. Hook formatowania przy zapisie oznacza, że każdy plik Swift dotknięty przez agenta zostaje automatycznie sformatowany, zanim Pan/Pani go zobaczy.
Opcjonalnie: należy dodać plik konfiguracyjny .swiftformat w katalogu głównym projektu, aby dostosować reguły formatowania:
# .swiftformat
--indent 4
--allman false
--stripunusedargs closure-only
--importgrouping testable-bottom
--header strip
PostToolUse: automatyczne uruchamianie SwiftLint
Jeśli używany jest SwiftLint, należy uruchamiać go po każdej edycji pliku Swift:
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"command": "bash -c 'INPUT=$(cat); FP=$(echo \"$INPUT\" | jq -r \".tool_input.file_path // empty\"); if echo \"$FP\" | grep -qE \"\\.swift$\"; then swiftlint lint --path \"$FP\" --quiet 2>/dev/null || true; fi'"
}
]
}
}
|| true zapobiega blokowaniu agenta przez ostrzeżenia lintowania. Jeśli naruszenia reguł lintowania mają blokować działanie, należy to usunąć.
PostToolUse: automatyczne budowanie po zmianach
Aby uzyskać agresywną pętlę informacji zwrotnej, można wyzwalać build po każdej zmianie pliku Swift:
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"command": "bash -c 'INPUT=$(cat); FP=$(echo \"$INPUT\" | jq -r \".tool_input.file_path // empty\"); if echo \"$FP\" | grep -qE \"\\.swift$\"; then xcodebuild -scheme Return -destination \"platform=iOS Simulator,name=iPhone 16 Pro\" build 2>&1 | tail -5; fi'"
}
]
}
}
Ostrzeżenie: To kosztowne. Każda edycja pliku uruchamia build. Należy używać oszczędnie — jest to najbardziej przydatne podczas sesji debugowania, gdy potrzebna jest natychmiastowa informacja zwrotna z budowania. Przy normalnym developmentcie lepiej pozwolić agentowi ręcznie uruchamiać buildy przez MCP, gdy będzie gotowy.
PreToolUse: blokowanie modyfikacji entitlements
Ochrona pliku entitlements przed przypadkowymi modyfikacjami ze strony agenta:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Edit|Write",
"command": "bash -c 'INPUT=$(cat); FP=$(echo \"$INPUT\" | jq -r \".tool_input.file_path // empty\"); if echo \"$FP\" | grep -qE \"\\.entitlements$\"; then echo \"BLOCKED: Do not modify entitlements files without explicit permission.\" >&2; exit 2; fi'"
}
]
}
}
Łączna konfiguracja hooków iOS
Oto pełny .claude/settings.json, którego używam we wszystkich projektach iOS:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Edit|Write",
"command": "bash -c 'INPUT=$(cat); FP=$(echo \"$INPUT\" | jq -r \".tool_input.file_path // empty\"); if echo \"$FP\" | grep -qE \"\\.(pbxproj|xcworkspace|xib|storyboard|entitlements)$|xcodeproj/|xcworkspace/\"; then echo \"BLOCKED: Do not modify Xcode-managed files. Create Swift files and add manually.\" >&2; exit 2; fi'"
}
],
"PostToolUse": [
{
"matcher": "Edit|Write",
"command": "bash -c 'INPUT=$(cat); FP=$(echo \"$INPUT\" | jq -r \".tool_input.file_path // empty\"); if echo \"$FP\" | grep -qE \"\\.swift$\"; then swiftformat \"$FP\" --quiet 2>/dev/null; fi'"
}
]
}
}
Daje to 2 gwarancje: 1. Agent nie może uszkodzić plików projektu Xcode (blokada PreToolUse) 2. Każdy plik Swift dotknięty przez agenta jest automatycznie formatowany (formatowanie PostToolUse)
Wzorce architektury, które dobrze współpracują z agentami
Nie wszystkie architektury Swift są równie przyjazne dla agentów. Poniższe wzorce dają najlepsze wyniki, ponieważ są jawne, spójne i dobrze reprezentowane w danych treningowych.
@Observable (nigdy ObservableObject)
W targetach iOS 26+ należy używać wyłącznie @Observable. Jest to zarówno nowoczesny wzorzec, jak i wzorzec przyjazny dla agentów:
// CORRECT — @Observable
@Observable
@MainActor
final class TimerManager {
var timeRemaining: TimeInterval = 0
var state: TimerState = .stopped
func start() {
state = .running
// ...
}
}
// In a view:
struct TimerView: View {
@State private var timer = TimerManager()
var body: some View {
Text(timer.timeRemaining, format: .number)
}
}
// WRONG — ObservableObject (deprecated pattern)
class TimerManager: ObservableObject {
@Published var timeRemaining: TimeInterval = 0
@Published var state: TimerState = .stopped
}
// WRONG — @StateObject (deprecated pattern)
struct TimerView: View {
@StateObject private var timer = TimerManager()
}
Dlaczego @Observable jest przyjazne dla agentów: Ten wzorzec jest prostszy (nie wymaga adnotacji @Published), model własności jest czytelniejszy (@State zamiast rozróżnienia @StateObject i @ObservedObject), a agenci popełniają z nim mniej błędów, ponieważ zawiera mniej ruchomych części.
Należy udokumentować to w CLAUDE.md: Nawet przy targetowaniu iOS 26 agenci czasem wracają do wzorców ObservableObject ze swoich danych treningowych. Wyraźny zakaz temu zapobiega.
NavigationStack (nigdy NavigationView)
// CORRECT
NavigationStack {
List(items) { item in
NavigationLink(value: item) {
ItemRow(item: item)
}
}
.navigationDestination(for: Item.self) { item in
ItemDetailView(item: item)
}
}
// WRONG
NavigationView {
List(items) { item in
NavigationLink(destination: ItemDetailView(item: item)) {
ItemRow(item: item)
}
}
}
NavigationStack jest dostępny od iOS 16+ i stanowi jedyny wzorzec nawigacji, którego należy używać w nowym kodzie. Typowany wzorzec navigationDestination(for:) zapobiega tworzeniu przez agenta niepoprawnych linków nawigacyjnych.
SwiftData do utrwalania danych
Modele SwiftData są najczystszym wzorcem utrwalania danych w developmentcie wspieranym przez agentów:
@Model
final class GroceryItem {
var name: String
var quantity: Int
var isCompleted: Bool
var category: Category?
var list: GroceryList?
init(name: String, quantity: Int = 1) {
self.name = name
self.quantity = quantity
self.isCompleted = false
}
}
Kluczowe zasady dla agentów pracujących ze SwiftData:
1. Klasy @Model są automatycznie Observable — nie należy dodawać @Observable
2. Do powiązań formularzy należy używać @Bindable: @Bindable var item: GroceryItem
3. W widokach należy używać @Query dla danych reaktywnych: @Query var items: [GroceryItem]
4. W kodzie poza widokami należy używać modelContext.fetch()
5. Usuwanie relacji wymaga jawnych reguł: .cascade, .nullify, .deny
Współbieżność Swift 6.2
W nowych projektach należy celować w ścisłą współbieżność Swift 6.2:
// Actor isolation for shared mutable state
@MainActor
@Observable
final class DataManager {
var items: [Item] = []
func loadItems() async throws {
let fetched = try await api.fetchItems()
items = fetched // Safe: @MainActor isolated
}
}
// Sendable conformance for cross-actor transfers
struct Item: Sendable, Identifiable {
let id: UUID
let name: String
let createdAt: Date
}
Wskazówki dla agentów dotyczące współbieżności:
- Wszystkie modele widoków należy oznaczać @MainActor (zapobiega to ostrzeżeniom o wyścigach danych)
- Do wszystkich operacji asynchronicznych należy używać async/await (bez completion handlers)
- Typy wartości należy oznaczać jako Sendable na potrzeby transferów między aktorami
- W widokach do asynchronicznej inicjalizacji należy używać Task { }
- nonisolated należy stosować tylko wtedy, gdy zmierzono realną potrzebę wydajnościową
System projektowy Liquid Glass (iOS 26+)
iOS 26 wprowadził system projektowy Liquid Glass. Agenci dobrze sobie z nim radzą, gdy otrzymają wyraźne wskazówki:
// Glass effect on containers
VStack {
// content
}
.glassEffect()
// Glass effect with tint
Button("Action") { }
.glassEffect(.regular.tint(.blue))
// Glass effect on navigation bars (automatic in iOS 26)
NavigationStack {
// content
}
// Navigation bar automatically uses glass material
// Custom glass shapes
RoundedRectangle(cornerRadius: 16)
.fill(.ultraThinMaterial)
.glassEffect()
Należy uwzględnić w CLAUDE.md: „Use .glassEffect() on section backgrounds and card containers. Navigation bars automatically adopt glass material in iOS 26. Do not manually recreate glass effects with custom materials — use the system modifier.”
Kontekst specyficzny dla frameworków
Każdy framework Apple ma kwestie specyficzne dla agentów. Ta sekcja omawia frameworki używane w 8 aplikacjach.
HealthKit
Aplikacje, które go używają: Return, Water
HealthKit wymaga ostrożnej obsługi uprawnień i zabezpieczeń platformowych:
// Always check availability and authorization
import HealthKit
@MainActor
@Observable
final class HealthKitManager {
private let store = HKHealthStore()
var isAuthorized = false
func requestAuthorization() async {
guard HKHealthStore.isHealthDataAvailable() else { return }
let types: Set<HKSampleType> = [
HKQuantityType(.dietaryWater),
HKCategoryType(.mindfulSession)
]
do {
try await store.requestAuthorization(toShare: types, read: types)
isAuthorized = true
} catch {
// User denied — do not retry automatically
}
}
}
Zasady dla agentów dotyczące HealthKit:
- Zawsze należy zabezpieczać kod przez HKHealthStore.isHealthDataAvailable()
- Nigdy nie należy zakładać autoryzacji — trzeba sprawdzać ją przy każdym zapisie
- W kodzie wieloplatformowym należy używać #if canImport(HealthKit) (HealthKit jest niedostępny na tvOS)
- Nigdy nie należy przechowywać danych zdrowotnych lokalnie poza tym, co zapewnia HealthKit
- W Info.plist należy uwzględnić zarówno NSHealthShareUsageDescription, jak i NSHealthUpdateUsageDescription
SpriteKit
Aplikacje, które go używają: TappyColor, Starfield Destroyer
Model grafu sceny w SpriteKit wymaga wyraźnych wskazówek dla agenta:
## SpriteKit Rules
- Scene hierarchy is a tree of SKNodes with zPosition ordering
- Physics bodies use category bitmasks (UInt32) for collision detection
- Node pooling: pre-allocate reusable nodes (bullets, particles)
- Never add nodes directly to the scene — use layer nodes for organization
- Update loop: `update(_ currentTime:)` runs every frame — keep it fast
- Actions: use SKAction sequences for animations, not manual property updates
- Textures: use texture atlases for performance (.atlas directories)
Mocne strony agentów w pracy ze SpriteKit: - Tworzenie sekwencji i grup SKAction - Konfigurowanie ciał fizycznych i wykrywania kontaktów - Implementowanie maszyn stanów gry - Budowanie nakładek HUD
Słabe strony agentów w pracy ze SpriteKit: - Pętle gry wrażliwe na wydajność (agent dodaje niepotrzebną pracę w każdej klatce) - Złożone symulacje fizyki (niestandardowa fizyka daje większą precyzję niż SKPhysicsBody) - Dostrajanie efektów cząsteczkowych (jest wizualne i wymaga iteracji)
Metal
Aplikacje, które go używają: amp97, Water, Starfield Destroyer
Metal to framework, z którym agenci radzą sobie najgorzej. Model programowania GPU zasadniczo różni się od Swift po stronie CPU, a agenci nie mogą zweryfikować wyniku wizualnego.
## Metal Rules
- Shared types between Swift and Metal go in a bridging header (ShaderTypes.h)
- Triple buffer in-flight frames (semaphore with value 3)
- Test shaders on DEVICE, not simulator (Metal behavior differs)
- Compute shaders: threadgroup size must divide evenly into grid size
- Fragment shaders: output color must be in correct color space (sRGB or linear)
- DO NOT optimize shaders without Instruments GPU profiling data
Co należy uwzględnić w CLAUDE.md dla projektów Metal: - Definicję struktury Uniforms (współdzieloną między Swift i MSL) - Wzorzec konfiguracji stanu potoku renderowania - Indeksy buforów i ich przeznaczenie - Listę istniejących shaderów oraz opis działania każdego z nich - Znane problemy z precyzją (half vs. float)
Live Activities
Aplikacje, które go używają: Return
Live Activities wymagają konkretnej konfiguracji, z którą agenci dobrze sobie radzą po jej udokumentowaniu:
## Live Activities
- ActivityAttributes defined in `TimerActivityAttributes.swift`
- ActivityKit framework: `import ActivityKit`
- Widget extension: `ReturnWidgets/ReturnLiveActivity.swift`
- Start: `Activity<TimerActivityAttributes>.request(attributes:content:)`
- Update: `activity.update(ActivityContent(state:staleDate:))`
- End: `activity.end(ActivityContent(state:staleDate:), dismissalPolicy:)`
- Push token: register for updates via `activity.pushTokenUpdates`
Game Center
Aplikacje, które go używają: Starfield Destroyer
## Game Center
- Authentication: `GKLocalPlayer.local.authenticateHandler`
- Leaderboards: `GKLeaderboard.submitScore(_:context:player:leaderboardIDs:completionHandler:)`
- Achievements: `GKAchievement.report(_:withCompletionHandler:)` (takes `[GKAchievement]` array)
- Always check `GKLocalPlayer.local.isAuthenticated` before submitting
- Handle authentication failure gracefully (offline play must work)
Wzorce wieloplatformowe
Return obejmuje iOS, watchOS i tvOS. Rozwój wieloplatformowy z agentami wymaga jawnej dokumentacji granic między platformami.
Organizacja współdzielonego kodu
Shared/
├── MeditationSession.swift # Data model (all platforms)
├── SessionStore.swift # iCloud sync (all platforms)
└── SessionHistoryView.swift # UI (adapts per platform)
Return/ # iOS-specific
ReturnWatch Watch App/ # watchOS-specific
ReturnTV/ # tvOS-specific
Reguła dla agentów: „Jeśli plik znajduje się w Shared/, zmiany wpływają na wszystkie platformy. Jeśli plik znajduje się w katalogu platformy, zmiany są odizolowane. Przed modyfikacją pliku zawsze należy sprawdzić, w którym katalogu się znajduje”.
Warunki dostępności platform
// HealthKit: available on iOS and watchOS, not tvOS
#if canImport(HealthKit)
import HealthKit
// HealthKit code here
#endif
// ActivityKit: available on iOS only
#if canImport(ActivityKit)
import ActivityKit
// Live Activity code here
#endif
// WatchKit: available on watchOS only
#if os(watchOS)
import WatchKit
// Watch-specific code here
#endif
Wskazówki dla agenta: „Podczas używania frameworków specyficznych dla platformy zawsze należy stosować warunki #if canImport() lub #if os(). Nie należy zakładać, że dany framework jest dostępny we wszystkich targetach”.
Adaptacja UI dla poszczególnych platform
struct SessionHistoryView: View {
@Query var sessions: [MeditationSession]
var body: some View {
List(sessions) { session in
SessionRow(session: session)
}
#if os(tvOS)
.focusable()
#endif
#if os(iOS)
.swipeActions {
Button("Delete", role: .destructive) {
// delete
}
}
#endif
}
}
Zaawansowane przepływy pracy
Autonomiczne pętle build-test-fix
Najbardziej efektywny wzorzec: przekazać agentowi specyfikację funkcji i pozwolić mu samodzielnie iterować przez cykle build-test-fix.
Implement a countdown timer that:
1. Starts from a user-selected duration (10, 20, or 30 minutes)
2. Shows remaining time with a circular progress indicator
3. Plays a bell sound on completion
4. Logs the session to HealthKit as mindful minutes
Build after each change. Fix all errors. Run tests when the build succeeds.
Continue until all tests pass and the build is clean.
Agent pisze kod, buduje przez MCP, odczytuje ustrukturyzowane błędy, poprawia je i powtarza proces. Funkcja, która wymagałaby 5-10 ludzkich cykli build-error-fix, zostaje ukończona w jednej autonomicznej pętli.
Kiedy to działa: Dobrze zdefiniowane funkcje z jasnymi kryteriami akceptacji.
Kiedy to się psuje: Funkcje otwarte („spraw, żeby wyglądało ładnie”), kod wrażliwy na wydajność albo wszystko, co wymaga weryfikacji wizualnej.
Delegowanie do subagentów dla iOS
System subagentów w Claude Code działa w projektach iOS:
Use a subagent to research the best approach for implementing
iCloud key-value store sync for meditation sessions across iOS,
watchOS, and tvOS. Report back with the recommended pattern.
Subagent eksploruje dokumentację i wzorce kodu w osobnym oknie kontekstu, zwraca podsumowanie, a główna sesja wdraża rekomendację. Dzięki temu research nie zużywa podstawowego kontekstu.
Stosowanie wzorców między aplikacjami
Gdy utrzymuje się wiele aplikacji iOS ze spójnymi wzorcami, agenci mogą przenosić wzorce z jednej aplikacji do drugiej:
Look at how Settings.swift works in the Return project
(centralized singleton with validation). Apply the same pattern
to create a Settings.swift for the Water project.
Agent odczytuje wzorzec źródłowy, rozumie strukturę i tworzy spójną implementację w projekcie docelowym.
Podwójny przegląd agentów (Claude + Codex)
Przy krytycznych zmianach warto użyć dwóch agentów z różnych rodzin modeli:
- Claude Code pisze implementację
- Codex CLI sprawdza ją w osobnym przebiegu
# After Claude implements the feature:
codex "Review the changes in the last commit. Focus on Swift 6.2
concurrency correctness, SwiftData relationship integrity,
and potential retain cycles. Report issues only — no praise."
Różne rodziny modeli wychwytują różne klasy błędów. Ma to szczególną wartość przy shaderach Metal i wzorcach współbieżności, gdzie łatwo wprowadzić subtelne błędy.
Co podwójny przegląd wychwytuje, a czego nie wyłapuje pojedynczy przegląd:
| Typ problemu | Mocna strona Claude | Mocna strona Codex |
|---|---|---|
| Cykle relacji SwiftData | Umiarkowana | Silna (GPT-4o) |
| Luki w izolacji @MainActor | Silna | Umiarkowana |
| Wyrównanie bufora Metal | Umiarkowana | Umiarkowana |
| Wykrywanie cykli retain | Silna (Opus) | Silna (o3) |
| Świadomość wycofania API | Silna (nowsze dane treningowe) | Umiarkowana |
| Race conditions we współbieżności | Silna | Silna (wychwytywane są inne wzorce) |
Podwójny przegląd nie polega na znajdowaniu większej liczby błędów — chodzi o znajdowanie innych błędów. Każda rodzina modeli ma inne tryby awarii w rozpoznawaniu wzorców.
Operacje wsadowe w wielu aplikacjach
Gdy zmiana frameworka lub wzorca wpływa na wiele aplikacji:
# Update @Observable pattern across all projects
for project in BananaList Return Water Reps; do
cd ~/Projects/$project
claude -p "Audit all files for any remaining ObservableObject usage.
Convert to @Observable following the pattern in CLAUDE.md.
Build and test after changes." --dangerously-skip-permissions
done
Używać ostrożnie. Flaga --dangerously-skip-permissions jest wymagana w trybie nieinteraktywnym, ale omija wszystkie kontrole bezpieczeństwa. Należy upewnić się, że hooki PreToolUse są skonfigurowane, aby chronić pliki .pbxproj.
Aplikacje korzystające z lokalnego LLM Apple
Jeśli aplikacja wywołuje framework Foundation Models Apple (np. do podsumowań offline, klasyfikacji albo generowania ustrukturyzowanych wyników), agenci muszą znać budżet promptu. iOS 26.4 dodał dwa APIs do SystemLanguageModel, które zastąpiły wcześniejsze założenie 4096 tokenów: contextSize (maksymalna liczba tokenów, jaką model akceptuje w jednej konwersacji) oraz tokenCount(for:) (async throws, zwraca, ile tokenów faktycznie kosztuje dany prompt).16 Oba są @backDeployed(before: iOS 26.4), więc są dostępne we wszystkich wersjach OS obsługujących FM bez drabinki #available.
Wzorzec, którego agent powinien przestrzegać podczas generowania kodu konstrukcji promptów:
import FoundationModels
func budgetFor(prompt: String, reservedReply: Int = 256) async throws -> Int {
let model = SystemLanguageModel.default
let promptCost = try await model.tokenCount(for: prompt)
let budget = model.contextSize - promptCost - reservedReply
guard budget > 0 else { throw ContextError.promptTooLong }
return budget
}
Warto dodać ten wzorzec do CLAUDE.md, jeśli aplikacja dotyka SystemLanguageModel. Bez niego agenci wracają do starego hardcode’u 4096 i po cichu ucinają prompty na urządzeniach dostarczanych z większymi oknami kontekstu. Sygnatura async throws w tokenCount(for:) ma kluczowe znaczenie — agenci, którzy wkleją wersję synchroniczną, nie skompilują kodu.
Studia przypadków z praktyki
Łatwo dawać ogólne rady. Poniżej znajdują się konkretne scenariusze z 8 aplikacji, które pokazują, jak w praktyce działa tworzenie aplikacji iOS z pomocą agentów — także wtedy, gdy coś się nie udaje.
Studium przypadku 1: Dodanie aplikacji TV do Return (sukces)
Zadanie: Dodać target tvOS do Return, czyli timera medytacyjnego, który miał już wersje na iOS i watchOS. Aplikacja TV wymagała nawigacji za pomocą Siri Remote, interfejsu dla dużego ekranu oraz synchronizacji ustawień z aplikacją iOS.
Co agent zrobił dobrze:
- Odczytał istniejący iOS TimerManager i utworzył TVTimerManager, który pomijał Live Activities oraz HealthKit (niedostępne na tvOS)
- Utworzył niestandardowe style przycisków dla nawigacji fokusem Siri Remote (TVCapsuleButtonStyle, TVCircleButtonStyle)
- Zbudował komponent TVStepper, który zastępuje selektory kołowe (nieużywalne z Siri Remote) przyciskami +/-
- Zaimplementował synchronizację ustawień przez App Groups (group.com.941apps.Return)
- Dodał zabezpieczenia #if os(tvOS) w całym współdzielonym kodzie
- Zbudował i przetestował przez MCP z platform=tvOS Simulator,name=Apple TV
Co trzeba było zrobić ręcznie: - Utworzyć target tvOS w Xcode (File > New > Target > tvOS App) - Dodać nowy target do projektu Xcode (zmiany w .pbxproj) - Skonfigurować uprawnienie App Groups dla targetu TV - Dodać target TV do istniejącego schematu albo utworzyć nowy - Ręcznie dodać wszystkie pliki Swift utworzone przez agenta do targetu TV - Ręcznie przetestować nawigację Siri Remote (agent nie potrafi ocenić zachowania fokusu)
Rezultat: 15 nowych plików Swift, w pełni działająca aplikacja TV, po około 3 godzinach pracy z pomocą agenta. Według moich szacunków agent wykonał mniej więcej 80% prac implementacyjnych; po mojej stronie były elementy wymagające interakcji z UI Xcode (uprawnienia, konfiguracja targetu, flagi funkcji) oraz ręczne testowanie fokusu na prawdziwym Apple TV. Równoważna samodzielna praca w tej bazie kodu — na podstawie podobnych funkcji, które wdrażałem bez agentów — zajęłaby kilka dni.
Studium przypadku 2: Debugowanie shadera Metal w amp97 (częściowe niepowodzenie)
Zadanie: Dodać system intensywności oparty na energii do shadera oscyloskopu. Wizualizacja miała pulsować zgodnie z energią dźwięku.
Co się wydarzyło:
1. Agent napisał poprawną modyfikację shadera Metal, dodając uniform uEnergy i tonemapping HDR
2. Kod skompilował się bez błędów
3. Na urządzeniu wizualizacja była całkowicie biała — współczynnik intensywności był 10 razy za wysoki (3,5 zamiast 0,30)
4. Agent nie mógł zobaczyć białego ekranu, więc nie miał sygnału zwrotnego
5. Zidentyfikowałem problem wizualnie i poprosiłem agenta o obniżenie współczynnika
6. Agent go obniżył, ale cały automat stanów energii był zbyt złożony i psuł wizualizator na inne sposoby
7. Całość wycofano — dwa commity (67959ed i cda4830) zostały wycofane w 869d914
Lekcja: Shadery Metal to najtrudniejsza domena dla developmentu wspieranego przez agentów, ponieważ pętla informacji zwrotnej jest przerwana. Agent może zweryfikować składnię (kompiluje się) i semantykę (typy są poprawne), ale nie może zweryfikować wyniku (czy wygląda dobrze). Każda modyfikacja shadera, która zmienia zachowanie wizualne, wymaga ludzkiej weryfikacji na urządzeniu.
Co zostało potem dodane do CLAUDE.md: „NIE podejmować prób modyfikacji stanu energii w shaderze oscyloskopu bez wyjątkowo ostrożnego testowania współczynników. Poprzednia próba zepsuła wizualizator przez współczynniki 10 razy za wysokie.”
Studium przypadku 3: Migracja SwiftData w Banana List (sukces)
Zadanie: Zmigrować model danych z V1 do V2, dodając pole quantity do GroceryItem oraz nowy model Category z relacjami.
Co zrobił agent:
1. Odczytał istniejące definicje modelu V1
2. Utworzył definicje modelu V2 z nowymi polami i relacjami
3. Napisał GroceryMigrationPlan zgodny z protokołem SchemaMigrationPlan
4. Zaimplementował etap migracji V1toV2: dodał domyślne quantity: 1 oraz category: nil
5. Zaktualizował wszystkie widoki tak, aby obsługiwały nowe pola
6. Zaktualizował SampleData.swift dla podglądów
7. Zbudował projekt i uruchomił testy przez MCP — wszystkie przeszły
8. Utworzył testy jednostkowe specyficzne dla migracji
Klucz: Agent odniósł sukces, ponieważ migracje SwiftData podążają za dobrze zdefiniowanym wzorcem protokołu, szeroko opisanym w dokumentacji Apple i danych treningowych. CLAUDE.md jawnie dokumentował model V1, więc agent rozumiał, z czego wykonuje migrację.
Studium przypadku 4: Synchronizacja sesji iCloud w Return (sukces ze złożonością)
Zadanie: Zaimplementować rejestrowanie sesji medytacyjnych między urządzeniami. Sesje ukończone na Apple TV lub Mac powinny synchronizować się z iPhone w celu zapisu w HealthKit.
Co wygenerował agent:
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ tvOS │ │ Mac │ │ Watch │
│ TVTimerMgr │ │ TimerMgr │ │ WatchTimer │
└──────┬──────┘ └──────┬──────┘ └──────┬──────┘
│ │ │
└───────────────────┼───────────────────┘
│
▼
┌────────────────────────┐
│ SessionStore │
│ (iCloud Key-Value) │
└───────────┬────────────┘
│
▼
┌────────────────────────┐
│ iPhone (on foreground)│
│ → Write to HealthKit │
└────────────────────────┘
Agent:
1. Utworzył model danych MeditationSession z UUID, datami, czasem trwania, urządzeniem źródłowym i statusem synchronizacji HealthKit
2. Zbudował singleton SessionStore, który zarządza NSUbiquitousKeyValueStore na potrzeby synchronizacji iCloud
3. Zaimplementował rozwiązywanie konfliktów scalania (deduplikacja oparta na UUID)
4. Dodał SessionHistoryView z adaptacjami specyficznymi dla platformy (przeciągnięcie, aby usunąć na iOS, obsługa fokusu na tvOS)
5. Połączył synchronizację HealthKit po stronie iPhone dla sesji z innych urządzeń
Co wymagało iteracji: Początkowa implementacja nie obsługiwała przypadku, w którym aplikacja iPhone uruchamia się w tle (brak powiadomienia pierwszoplanowego dla synchronizacji). Agent potrzebował konkretnej wskazówki: „Użyj NSUbiquitousKeyValueStore.didChangeExternallyNotification, aby wyzwolić synchronizację przy zmianach KV w tle.” Po tej podpowiedzi implementacja była poprawna.
Lekcja: Agenci dobrze radzą sobie z wieloplatformowymi wzorcami architektonicznymi, gdy architektura jest jasno opisana. Wzorzec synchronizacji iCloud nie jest trywialny, ale podąża za udokumentowanym wzorcem Apple, który agent rozumiał. Przypadek brzegowy (synchronizacja w tle) wymagał ludzkiej wiedzy domenowej, ponieważ nie jest dobrze udokumentowany.
Studium przypadku 5: Integracja Game Center w Starfield Destroyer (sukces)
Zadanie: Dodać rankingi i osiągnięcia Game Center do strzelanki kosmicznej.
Co agent zrobił dobrze:
- Zaimplementował GKLocalPlayer.local.authenticateHandler w punkcie wejścia aplikacji
- Utworzył GameCenterManager z metodami do przesyłania wyników i raportowania osiągnięć
- Dodał sprawdzanie stanu uwierzytelnienia przed wszystkimi operacjami Game Center
- Elegancko obsłużył tryb offline (gra działa bez Game Center, a wyniki są przesyłane po ponownym połączeniu)
- Utworzył definicje osiągnięć odpowiadające systemowi progresji 8 statków
Co wymagało ręcznej pracy: - Utworzenie rankingów i osiągnięć w App Store Connect (portal webowy, niedostępny dla agenta) - Skonfigurowanie uprawnienia Game Center w Xcode - Testowanie z kontem sandbox Game Center (wymaga ręcznego zalogowania na urządzeniu)
Cykl życia projektu z agentami
Rozpoczynanie nowego projektu iOS
Optymalny przepływ pracy przy rozpoczynaniu nowego projektu ze wsparciem agenta:
Faza 1: konfiguracja wykonywana przez człowieka (15-30 minut) 1. Utworzenie projektu Xcode (File > New > Project) 2. Skonfigurowanie podpisywania i uprawnień 3. Ustawienie celu wdrożenia i obsługiwanych miejsc docelowych 4. Dodanie wymaganych entitlements (HealthKit, Game Center itp.) 5. Utworzenie początkowego CLAUDE.md z tożsamością projektu i regułami
Faza 2: implementacja przez agenta (od kilku godzin do kilku dni) 1. Agent tworzy model danych (SwiftData, Core Data lub zwykłe struktury) 2. Agent buduje widoki zgodnie z udokumentowanymi wzorcami 3. Agent implementuje logikę biznesową w klasach manager/service 4. Agent pisze testy jednostkowe 5. Pętla build-test-fix przez MCP (autonomicznie)
Faza 3: integracja wykonywana przez człowieka (30-60 minut) 1. Dodanie plików utworzonych przez agenta do targetów Xcode 2. Zweryfikowanie podpisywania i entitlements 3. Przetestowanie na fizycznym urządzeniu 4. Przegląd układu wizualnego i UX 5. Przesłanie do App Store Connect
Utrzymywanie istniejącego projektu
W przypadku bieżącego rozwoju ustabilizowanych aplikacji:
You: Here's the next feature for Return: add a "Focus Score" that
calculates from session duration and consistency. Show it on
the main timer view. Build and test.
Claude: [reads CLAUDE.md, understands patterns]
[reads TimerManager.swift, Settings.swift]
[creates FocusScore.swift — model with calculation logic]
[creates FocusScoreView.swift — display component]
[integrates into ContentView.swift]
[calls build_sim — 1 error: missing import]
[fixes import]
[calls build_sim — success]
[writes FocusScoreTests.swift]
[calls test_sim — all pass]
Skuteczność agenta rośnie wraz z tym, jak dobrze CLAUDE.md odzwierciedla aktualny stan projektu. CLAUDE.md należy aktualizować po dodaniu istotnych nowych funkcji, zmianie wzorców architektonicznych lub wprowadzeniu nowych frameworków.
Kiedy angażować agenta, a kiedy nie
| Zadanie | Agent? | Dlaczego |
|---|---|---|
| Nowy widok SwiftUI | Tak | Agenci świetnie radzą sobie z deklaratywnym UI |
| Zmiany w modelu SwiftData | Tak | Dobrze zdefiniowane, testowalne |
| Testy jednostkowe | Tak | Mechaniczne, oparte na wzorcach |
| Refaktoryzacja | Tak | Systematyczna, obejmująca wiele plików |
| Diagnozowanie błędów kompilacji | Tak (przez MCP) | Uporządkowana pętla informacji zwrotnej |
| Nowy target Xcode | Nie | Wymaga UI Xcode i zmian w .pbxproj |
| Podpisywanie i provisioning | Nie | Oparte na portalu, niedostępne dla agenta |
| Dopracowanie wizualne | Nie | Wymaga ludzkiej oceny estetycznej |
| Dostrajanie shaderów Metal | Nie | Wymaga testowania GPU na urządzeniu |
| Przesłanie do App Store | Nie | Portal i Xcode Organizer |
| Profilowanie wydajności | Nie | Wymaga Instruments |
| Audyt dostępności | Częściowo | Agent może dodać etykiety, człowiek weryfikuje VoiceOver |
Konfigurowanie definicji agentów
Jeśli używany jest system definicji agentów Claude Code (.claude/agents/), należy utworzyć agenta specyficznego dla iOS:
---
name: ios-developer
description: iOS development agent with MCP build tools and SwiftUI expertise
tools:
- XcodeBuildMCP
- xcode
---
# iOS Developer Agent
You are an iOS development agent for apps targeting iOS 26+ with SwiftUI.
## Architecture Rules
- @Observable for all view models (NEVER ObservableObject)
- NavigationStack for all navigation (NEVER NavigationView)
- SwiftData for persistence
- Swift 6.2 strict concurrency
- @MainActor on all Observable classes
## Build & Test — Always Use MCP
Prefer MCP tools over raw shell commands for ALL build operations:
- **Build**: `build_sim` / `build_device` (NOT `xcodebuild` via Bash)
- **Test**: `test_sim` / `test_device` (NOT `xcodebuild test` via Bash)
- **Simulators**: `list_sims`, `boot_sim`, `open_sim`
- **Debug**: `debug_attach_sim`, `debug_stack`, `debug_variables`
- **Apple docs**: `DocumentationSearch` (NOT WebSearch for Apple APIs)
- **Swift verification**: `ExecuteSnippet` (NOT `swift` via Bash)
MCP returns structured JSON. Bash returns unstructured text.
## File Management Rules
- NEVER modify .pbxproj, .xcodeproj/, .xcworkspace/, .xib, .storyboard
- Create Swift files in the correct directory
- Report files that need manual addition to Xcode targets
## SwiftData Rules
- @Model classes are automatically Observable — do not add @Observable
- Use @Bindable for form bindings to model properties
- Use @Query in views, modelContext.fetch() elsewhere
- Document relationship delete rules
## When You Get Stuck
- Build errors: use `build_sim` via MCP for structured output
- API questions: use `DocumentationSearch` via Apple MCP
- Swift verification: use `ExecuteSnippet` via Apple MCP
- Never guess — verify with tools
Do tego agenta można odwoływać się za pomocą @ios-developer w sesjach Claude Code.
Wzorce testowania dla iOS wspomaganego przez agentów
Agenci piszą znakomite testy jednostkowe, gdy otrzymają jasne wytyczne. Poniżej znajdują się wzorce, które dają najlepsze wyniki.
Organizacja plików testowych
# In CLAUDE.md:
## Test Structure
Tests mirror source structure:
- `ReturnTests/TimerManagerTests.swift` tests `TimerManager.swift`
- `ReturnTests/SettingsTests.swift` tests `Settings.swift`
- `ReturnTests/ConstantsTests.swift` tests `Constants.swift`
Test naming: `test_<what>_<condition>_<expected>`
Example: `test_start_whenStopped_transitionsToRunning`
Promptowanie testów
Skuteczny prompt testowy:
Write unit tests for TimerManager covering:
1. Initial state is .stopped with timeRemaining == selectedDuration
2. start() transitions state to .running
3. pause() from .running transitions to .paused
4. reset() from any state returns to .stopped with original duration
5. start() from .paused resumes (state becomes .running)
6. Edge case: reset() when already stopped is a no-op
7. Edge case: pause() when already paused is a no-op
Follow the existing test pattern in SettingsTests.swift.
Use setUp() to create a fresh TimerManager for each test.
Dlaczego to działa: Numerowane kryteria akceptacji dają agentowi checklistę. Odwołanie do istniejącego pliku testowego ustanawia wzorzec. Określenie użycia setUp() zapobiega tworzeniu przez agenta splątanego stanu testowego.
Nieskuteczny prompt testowy:
Write tests for TimerManager.
To prowadzi do ogólnych, płytkich testów, które pomijają przypadki brzegowe i mogą nie podążać za wzorcami projektu.
Wzorce testów async
Do testowania kodu opartego na timerach i async:
// Agent produces this pattern when guided correctly:
final class TimerManagerTests: XCTestCase {
var sut: TimerManager!
@MainActor
override func setUp() {
super.setUp()
sut = TimerManager()
}
@MainActor
func test_start_whenStopped_transitionsToRunning() {
// Given
XCTAssertEqual(sut.state, .stopped)
// When
sut.start()
// Then
XCTAssertEqual(sut.state, .running)
}
@MainActor
func test_timerCountsDown_afterOneSecond() async throws {
// Given
sut.selectedDuration = 10
sut.reset()
sut.start()
// When
try await Task.sleep(for: .seconds(1.1))
// Then
XCTAssertLessThanOrEqual(sut.timeRemaining, 9.0)
}
}
Kluczowe wzorce, o których agentom trzeba przypominać:
- @MainActor przy metodach testowych, które testują klasy @MainActor
- async throws dla testów używających Task.sleep lub operacji async
- Tolerancja w asercjach opartych na czasie (1,1 sekundy, nie dokładnie 1,0)
- Czyste setUp() / tearDown() dla izolacji testów
Snapshot testing
Do wykrywania regresji wizualnych warto rozważyć dodanie swift-snapshot-testing:
Add snapshot tests for the main timer view in three states:
1. Stopped (showing full duration)
2. Running (showing countdown)
3. Completed (showing 00:00 with completion state)
Use SnapshotTesting library. Create reference images on first run.
Agenci poprawnie konfigurują snapshot tests, ale nie mogą oceniać obrazów referencyjnych. Człowiek sprawdza początkowe snapshoty, a następnie testy agenta wychwytują regresje wizualne w przyszłych zmianach.
Zarządzanie oknem kontekstu w projektach iOS
Okno kontekstu 1M (Opus 4.6) jest duże, ale nie nieskończone. Projekty iOS mają własne wymagania związane z zarządzaniem kontekstem.
Koszt tokenów plików iOS
| Typ pliku | Typowy rozmiar | Przybliżona liczba tokenów |
|---|---|---|
| Widok SwiftUI (prosty) | 50-100 wierszy | 500-1,000 |
| Widok SwiftUI (złożony) | 200-400 wierszy | 2,000-4,000 |
| Model SwiftData | 30-80 wierszy | 300-800 |
| Klasa managera/usługi | 100-300 wierszy | 1,000-3,000 |
| Shader Metal (.metal) | 50-200 wierszy | 500-2,000 |
| Plik testów jednostkowych | 50-200 wierszy | 500-2,000 |
| CLAUDE.md | 100-300 wierszy | 1,000-3,000 |
| Odpowiedź MCP (build) | różnie | 200-2,000 |
| Odpowiedź MCP (test) | różnie | 500-5,000 |
Dla projektu z 50 plikami: Odczytanie wszystkich plików zużywa około 50,000-100,000 tokenów — spokojnie mieści się w oknie 1M. Agent może utrzymać cały projekt w kontekście.
Dla projektu z ponad 100 plikami: Konieczny staje się selektywny odczyt. Agent najpierw czyta CLAUDE.md (ze względu na adnotacje struktury plików), a następnie w razie potrzeby czyta konkretne pliki. Dlatego adnotacje plików w CLAUDE.md są kluczowe — prowadzą agenta do właściwych plików bez czytania wszystkiego.
Strategie dla dużych projektów
- Szczegółowe adnotacje plików w CLAUDE.md — Agent czyta mapę plików i przechodzi bezpośrednio do odpowiednich plików
- Delegowanie do subagentów — Eksplorację i research warto kierować do subagentów (czysty kontekst, zwracane podsumowania)
- Precyzyjne prompty — „Modify SettingsView.swift to add a new toggle” jest lepsze niż „update the settings”
- Granice sesji — Dla niepowiązanych funkcji warto rozpoczynać nowe sesje zamiast przedłużać długą sesję
- Użycie
/compact— Polecenie kompaktowania Claude Code podsumowuje rozmowę i zwalnia kontekst
Efektywność tokenów MCP
Jeden z najmocniejszych argumentów za MCP: ustrukturyzowane odpowiedzi JSON zużywają znacznie mniej tokenów niż surowy output xcodebuild.
| Scenariusz | Tokeny w surowym Bash | Tokeny MCP | Oszczędność |
|---|---|---|---|
| Udany build | 3,000-10,000 | 200-500 | 85-95% |
| Nieudany build (1 błąd) | 3,000-10,000 | 300-800 | 90-92% |
| Wyniki testów (20 testów) | 2,000-5,000 | 500-1,000 | 75-80% |
| Lista symulatorów | 500-2,000 | 200-400 | 60-80% |
Podczas typowej sesji programistycznej z 10-20 cyklami buildów MCP oszczędza 30,000-150,000 tokenów w porównaniu z surowym xcodebuild — tokenów, które pozostają dostępne na właściwe rozumowanie o kodzie.
Rozwiązywanie problemów
„build_sim failed — scheme not found”
Agent zgaduje nazwę schematu. Rozwiązanie:
Use discover_projs and list_schemes to find the correct scheme name
for this project before building.
Albo proszę dodać nazwę schematu bezpośrednio do CLAUDE.md:
## Build
Primary scheme: `Return` (iOS)
Watch scheme: `ReturnWatch` (watchOS)
TV scheme: `ReturnTV` (tvOS)
„xcrun mcpbridge — command not found”
Potrzebny jest Xcode 26.3 lub nowszy. Można to sprawdzić poleceniem xcodebuild -version. Jeśli Xcode 26.3+ jest zainstalowany, ale polecenie nadal kończy się niepowodzeniem:
# Ensure Xcode command line tools are selected
sudo xcode-select -s /Applications/Xcode.app/Contents/Developer
# Verify
xcrun mcpbridge --help
„Narzędzia MCP nie pojawiają się w Claude Code”
Narzędzia MCP zarejestrowane w trakcie sesji mogą nie pojawić się do momentu ponownego uruchomienia. Należy zamknąć Claude Code i rozpocząć nową sesję:
# Exit current session (Ctrl+C or /exit)
# Start fresh
claude
Następnie zweryfikować:
You: List all available MCP tools from XcodeBuildMCP.
„Agent nadal używa xcodebuild przez Bash zamiast MCP”
Agent nie odkrywa narzędzi MCP przez Tool Search. Dwa rozwiązania:
- Dodać bezpośrednią wskazówkę do CLAUDE.md (zob. Jak nauczyć agenta korzystania z MCP)
- Poprosić bezpośrednio: „Use the build_sim MCP tool, not xcodebuild via Bash”
„Build kończy się powodzeniem, ale agent zgłasza błąd”
XcodeBuildMCP parsuje output xcodebuild. Jeśli build generuje ostrzeżenia wyglądające jak błędy (częste przy ostrzeżeniach o deprecjacji), agent może błędnie zinterpretować wynik. Należy sprawdzić rzeczywiste pole statusu w odpowiedzi MCP.
„Simulator zawiesza się podczas uruchamiania”
Należy zamknąć wszystkie symulatory i uruchomić ponownie:
xcrun simctl shutdown all
xcrun simctl boot "iPhone 16 Pro"
Albo poprosić agenta:
Shut down all simulators, then boot a fresh iPhone 16 Pro.
„Agent próbował zmodyfikować .pbxproj mimo reguł w CLAUDE.md”
Reguły CLAUDE.md są sugestiami. Hooks wymuszają zachowanie. Jeśli nie ma hooka PreToolUse blokującego zapisy do .pbxproj, agent w końcu spróbuje to zrobić. Proszę zainstalować hook:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Edit|Write",
"command": "bash -c 'INPUT=$(cat); FP=$(echo \"$INPUT\" | jq -r \".tool_input.file_path // empty\"); if echo \"$FP\" | grep -qE \"\\.(pbxproj|xcworkspace|xib|storyboard)$|xcodeproj/|xcworkspace/\"; then echo \"BLOCKED: Do not modify Xcode project files.\" >&2; exit 2; fi'"
}
]
}
}
Reguły mówią „proszę tego nie robić”. Hooks mówią „nie można tego zrobić”.
FAQ
Od którego środowiska uruchomieniowego agenta warto zacząć?
Claude Code CLI z XcodeBuildMCP. Ma najgłębszą integrację z MCP, najbardziej dojrzały system hooków oraz okno kontekstu 1M (Opus 4.6), które potrafi utrzymać całe projekty iOS w pamięci roboczej. Warto zacząć od tego, a następnie dodać Codex do przeglądu kodu oraz natywne agenty Xcode do szybkich edycji inline, gdy workflow stanie się bardziej dojrzały.
Czy potrzebne są oba serwery MCP?
Dla większości deweloperów sam XcodeBuildMCP pokrywa 90% potrzeb (buildy, testy, symulatory, debugowanie). Warto dodać Xcode MCP od Apple, jeśli potrzebne jest wyszukiwanie dokumentacji, weryfikacja w Swift REPL albo renderowanie podglądów SwiftUI. Zawsze można dodać go później — oba serwery są niezależne.
Czy agenty mogą utworzyć nowy projekt Xcode od zera?
XcodeBuildMCP zawiera narzędzie create_project, które tworzy szkielety nowych projektów Xcode. Jednak w przypadku aplikacji produkcyjnych zalecam utworzenie projektu w Xcode (aby poprawnie skonfigurować podpisywanie, capabilities i targety), a następnie używanie agentów do całej implementacji kodu. 5 minut poświęcone w kreatorze nowego projektu Xcode oszczędza godziny problemów z konfiguracją projektu wygenerowaną przez agenta.
Jak agenty obsługują zależności Swift Package Manager?
Dobrze. Package.swift to standardowy plik Swift, który agenty potrafią niezawodnie czytać i edytować. Dodawanie zależności, aktualizowanie zakresów wersji i konfigurowanie targetów działa poprawnie. Ograniczeniem jest zarządzanie zależnościami oparte na .xcodeproj (interfejs rozwiązywania pakietów w Xcode) — tym zarządza Xcode i nie należy edytować tego za pomocą agentów.
Czy agenty mogą przesłać aplikację do App Store?
Nie. Przesyłanie do App Store obejmuje Organizer w Xcode, profile provisioning, zrzuty ekranu, metadane oraz portal App Store Connect. Żaden z tych elementów nie jest dostępny przez MCP ani narzędzia wiersza poleceń w sposób, który agenty mogłyby sensownie obsłużyć. Agenty zajmują się wszystkim aż do archiwum — implementacją, testowaniem, naprawą błędów i dokumentacją. Ostatni etap przesyłania pozostaje wykonywany przez człowieka.
Agenty mogą jednak pomóc z metadanymi App Store. Proszę poprosić agenta o napisanie opisu aplikacji, słów kluczowych i tekstu „co nowego” na podstawie najnowszych zmian. To praca nad generowaniem tekstu, w której agenty są bardzo skuteczne.
Jak obsługiwać sekrety i klucze API w rozwoju iOS wspomaganym przez agentów?
Nigdy nie należy commitować sekretów. W przypadku aplikacji iOS łączących się z backendowymi API:
- Używać plików
.xcconfigdo konfiguracji specyficznej dla środowiska - Dodać pliki
.xcconfigdo.gitignore - Odwoływać się do wartości konfiguracyjnych przez ustawienia builda
Info.plist - Udokumentować wymagane sekrety w CLAUDE.md bez podawania rzeczywistych wartości
## Configuration
API base URL and keys are in `Config.xcconfig` (not committed).
Required keys:
- `API_BASE_URL` — Backend server URL
- `API_KEY` — Authentication token
Create `Config.xcconfig` from `Config.xcconfig.template`.
Agent wie, że klucze istnieją i gdzie są używane, ale nigdy nie widzi rzeczywistych wartości.
A co z animacjami SwiftUI — czy agenty potrafią je pisać?
Agenty dobrze piszą kod animacji pod względem składniowym, ale nie potrafią wizualnie zweryfikować rezultatu. Proste animacje (.animation(.spring()), .transition(.slide), withAnimation { }) dają poprawne wyniki. Złożone, wieloetapowe animacje z precyzyjnym timingiem wymagają iteracji wizualnej, której agenty nie mogą wykonać.
Skuteczne: „Dodać animację sprężynową, gdy timer przechodzi między stanami.”
Nieskuteczne: „Sprawić, żeby animacja timera była satysfakcjonująca.” (Subiektywne, wymaga strojenia wizualnego.)
Jak agenty radzą sobie ze wzorcami obsługi błędów?
Bardzo dobrze. Agenty rozumieją wzorce Swift: do/catch, Result i async throws:
Implement error handling for the HealthKit authorization flow:
1. Check HKHealthStore.isHealthDataAvailable() — show alert if not
2. Request authorization — handle denial gracefully
3. On write failure — retry once, then show error
4. All errors should be user-facing with localized descriptions
Agenty tworzą uporządkowaną obsługę błędów z właściwymi komunikatami skierowanymi do użytkownika. Czasami obsługują błędy zbyt szeroko (łapią wyjątki, które powinny zostać przekazane dalej), dlatego warto przejrzeć bloki catch.
Czy można używać agentów do implementacji dostępności?
Częściowo. Agenty poprawnie dodają etykiety, podpowiedzi i cechy dostępności:
Add accessibility labels to all interactive elements in TimerView:
- Timer display: current time remaining
- Start/Pause button: current state and action
- Reset button: "Reset timer"
- Duration picker: selected duration
Czego agenty nie potrafią zrobić: zweryfikować poprawnej kolejności nawigacji VoiceOver, przetestować skalowania Dynamic Type ani ocenić współczynników kontrastu kolorów. Do weryfikacji należy użyć Accessibility Inspector w Xcode.
Jak agenty obsługują migrację Core Data (jeśli nie używa się SwiftData)?
Agenty piszą mapowania migracji Core Data i wersje modeli, ale ręcznych kroków w Xcode (tworzenia nowych wersji modelu, wybierania bieżącej wersji) nie da się zautomatyzować. Jeśli projekt nadal używa Core Data zamiast SwiftData, warto udokumentować historię wersji modelu w CLAUDE.md:
## Core Data Model Versions
- V1: Initial (GroceryList, GroceryItem)
- V2: Added Category model (current)
- Migration: Lightweight automatic for V1→V2
Jak agenty obsługują podglądy SwiftUI?
Na dwa sposoby:
1. Narzędzie RenderPreview w Apple Xcode MCP renderuje podglądy headless i zwraca wynik. Agent może zweryfikować, że podgląd się kompiluje i renderuje bez błędów, ale nie potrafi ocenić poprawności wizualnej.
2. Weryfikacja oparta na buildzie przez build_sim potwierdza, że providery podglądów się kompilują. Jeśli podgląd zawiesza się w runtime, build nadal kończy się powodzeniem — awaria ujawnia się dopiero wtedy, gdy Xcode próbuje wyrenderować podgląd.
Do wizualnej weryfikacji podglądów nadal trzeba mieć otwarte Xcode.
A co z visionOS i Apple Vision Pro?
Obowiązują te same wzorce. XcodeBuildMCP obsługuje symulatory visionOS, a wzorce architektoniczne (@Observable, NavigationStack, SwiftData) są identyczne. Kod specyficzny dla RealityKit (treści 3D, przestrzenie immersyjne, śledzenie dłoni) ma te same ograniczenia co Metal — agenty mogą pisać poprawny kod, ale nie mogą zweryfikować wyniku przestrzennego.
Jak duży może być projekt, zanim agenty zaczną mieć trudności?
Czynnikiem ograniczającym jest rozmiar okna kontekstu. Przy oknie 1M tokenów w Opus 4.6 Claude Code może jednocześnie utrzymać w aktywnej pamięci roboczej około 50-70 plików Swift. W większych projektach agent używa wyszukiwania plików i selektywnego czytania, aby pracować na podzbiorach codebase’u. Projekty mające ponad 100 plików działają dobrze — agent po prostu czyta pliki na żądanie, zamiast trzymać wszystko w kontekście.
Praktycznym limitem nie jest liczba plików, lecz spójność codebase’u. Dobrze udokumentowany projekt z 200 plikami i szczegółowym CLAUDE.md daje lepsze wyniki niż nieudokumentowany projekt z 30 plikami.
Czy trzeba znać Swift, aby używać agentów do rozwoju iOS?
Trzeba umieć przeglądać wynik pracy agenta i podejmować decyzje architektoniczne. Nie trzeba pisać każdej linii samodzielnie, ale należy rozumieć Swift na tyle dobrze, by wychwycić niepoprawne wybory agenta — szczególnie w obszarach współbieżności, zarządzania pamięcią i wzorców specyficznych dla frameworków. Agent jest 10-krotnym wzmacniaczem istniejących umiejętności, a nie ich zamiennikiem.
Jak agenty obsługują konflikty merge w plikach Swift?
Agenty niezawodnie rozwiązują konflikty merge w plikach źródłowych Swift. Standardowe znaczniki konfliktów (<<<<<<<, =======, >>>>>>>) są dobrze rozumiane przez wszystkie środowiska agentów. Jednak konflikty merge w plikach .pbxproj nadal wymagają ręcznego rozwiązania — nie należy prosić agentów o rozwiązywanie konfliktów .pbxproj.
Jaki jest koszt używania agentów do rozwoju iOS?
W planie Max od Anthropic (Opus 4.6, kontekst 1M) typowa sesja rozwoju iOS trwa 30-120 minut i przetwarza 200K-800K tokenów. Wywołania narzędzi MCP dodają minimalny narzut (ustrukturyzowane odpowiedzi JSON są oszczędne pod względem tokenów w porównaniu z surowym outputem builda). Koszt jest porównywalny z używaniem Claude Code dla dowolnego innego codebase’u — rozwój iOS nie jest istotnie droższy ani tańszy niż rozwój webowy.
Czy można używać agentów z projektami UIKit?
Tak, ale agenty są skuteczniejsze ze SwiftUI. UIKit wymaga więcej boilerplate’u, ma mniej deklaratywną strukturę i często obejmuje pliki Interface Builder, których agenty nie mogą edytować. Jeśli projekt używa UIKit, warto rozważyć używanie agentów do warstwy modelu i logiki biznesowej, obsługując UI ręcznie, albo stopniowo migrować widoki do SwiftUI.
Jak agenty obsługują lokalizację?
Agenty skutecznie tworzą i edytują pliki .xcstrings (katalog stringów Xcode). Mogą dodawać nowe klucze lokalizacyjne, dostarczać tłumaczenia i utrzymywać spójność między językami. Ustrukturyzowany format JSON plików .xcstrings jest przyjazny dla agentów. W przypadku plików .strings (starszy format) agenty również radzą sobie dobrze — format klucz-wartość jest prosty.
Typowe błędy agentów w iOS (i jak im zapobiegać)
Oto powtarzające się błędy, które zaobserwowałem w tysiącach interakcji z agentami w 8 projektach iOS. Każdy z nich ma strategię zapobiegania.
Błąd 1: Mieszanie wzorców Observable
Co się dzieje: Agent używa @Observable w jednym pliku, a ObservableObject w innym, albo dodaje @Observable do klasy @Model (która już jest Observable).
Zapobieganie: Jawne reguły w CLAUDE.md:
- NEVER use ObservableObject — use @Observable
- NEVER add @Observable to @Model classes (already Observable)
- NEVER use @StateObject — use @State with @Observable
- NEVER use @ObservedObject — access @Observable properties directly
Błąd 2: Tworzenie cykli silnych referencji w domknięciach
Co się dzieje: Agent tworzy domknięcia, które silnie przechwytują self, zwłaszcza w Timer.publish, NotificationCenter i handlerach zakończenia.
Zapobieganie: Uwzględnić wzorzec domknięcia w CLAUDE.md:
## Closure Pattern
- Timer callbacks: use `[weak self]` and guard
- NotificationCenter observers: store in `Set<AnyCancellable>` and use `[weak self]`
- Completion handlers: use `[weak self]` for any closure stored beyond the call site
Błąd 3: Ignorowanie wymagań @MainActor
Co się dzieje: Agent tworzy klasy @Observable bez izolacji @MainActor, co powoduje ostrzeżenia współbieżności Swift 6.2 albo awarie w czasie działania, gdy aktualizacje UI odbywają się poza głównym wątkiem.
Zapobieganie:
## Concurrency Rule
ALL @Observable classes MUST be @MainActor:
```swift
@Observable
@MainActor
final class SomeManager { }
```
Błąd 4: Używanie NavigationLink z domknięciem destination
Co się dzieje: Agent używa przestarzałego NavigationLink(destination:label:) zamiast bezpiecznego typowo wzorca NavigationLink(value:) + .navigationDestination(for:).
Zapobieganie:
## Navigation Pattern
ALWAYS use value-based navigation:
```swift
NavigationLink(value: item) { ItemRow(item: item) }
.navigationDestination(for: Item.self) { ItemDetailView(item: $0) }
```
NEVER use: `NavigationLink(destination: ItemDetailView(item: item)) { }`
Błąd 5: Twarde kodowanie nazw symulatorów
Co się dzieje: Agent zapisuje polecenia budowania z konkretnymi nazwami symulatorów („iPhone 16 Pro”), które mogą nie istnieć w danym systemie.
Zapobieganie: MCP obsługuje to — list_sims wykrywa dostępne symulatory. W CLAUDE.md:
## Simulators
Do NOT hardcode simulator names. Use `list_sims` MCP tool to discover
available devices, then `boot_sim` with the discovered device ID.
Błąd 6: Tworzenie plików w niewłaściwych katalogach
Co się dzieje: Agent tworzy nowy plik widoku w katalogu głównym projektu zamiast w podfolderze Views/ albo umieszcza model w niewłaściwej grupie.
Zapobieganie: Adnotacje struktury plików w CLAUDE.md wskazują właściwe miejsce. Dodatkowo:
## File Placement Rules
- Views → `AppName/Views/`
- Models → `AppName/Models/`
- Managers → `AppName/Managers/`
- Extensions → `AppName/Extensions/`
- Tests → `AppNameTests/`
Błąd 7: Brak obsługi dostępności platform
Co się dzieje: Agent używa HealthKit we współdzielonym kodzie kompilowanym dla tvOS (gdzie HealthKit jest niedostępny) albo używa ActivityKit w kodzie watchOS.
Zapobieganie:
## Platform Guards
- HealthKit: `#if canImport(HealthKit)` (unavailable on tvOS)
- ActivityKit: `#if canImport(ActivityKit)` (iOS only)
- WatchKit: `#if os(watchOS)`
- UIKit haptics: `#if os(iOS)` (unavailable on tvOS, watchOS uses WKHaptic)
Błąd 8: Nadmierne komplikowanie prostych funkcji
Co się dzieje: Agent tworzy protokół, rozszerzenie protokołu, konkretną implementację, fabrykę i kontener dependency injection dla czegoś, co powinno być 20-wierszową funkcją narzędziową.
Zapobieganie: Uwzględnić zasadę prostoty:
## Architecture Principle
Prefer the simplest solution that handles the requirements.
- Direct implementation over protocol abstraction (unless you have 2+ conforming types)
- Concrete types over generics (unless reuse is proven)
- Extensions on existing types over new wrapper types
Uczciwa ocena
Po wydaniu 8 aplikacji iOS z użyciem agentów AI podsumowanie wygląda następująco:
Agenci zmienili: Szybkość implementacji. To, co zajmowało dni, zajmuje godziny. Widoki SwiftUI, modele SwiftData, testy jednostkowe, refaktoryzacja — dziś są one przede wszystkim tworzone przez agentów i sprawdzane przez człowieka.
Agenci nie zmienili: Decyzji architektonicznych, projektowania wizualnego, optymalizacji wydajności ani procesu zgłoszenia do App Store. Te obszary nadal pozostają po stronie człowieka.
Mnożnik jest realny, ale ograniczony. Moja subiektywna ocena na podstawie portfolio 8 aplikacji: 3-5x krótszy czas dostarczenia funkcji w dobrze udokumentowanych projektach z poprawną konfiguracją MCP i hooków. Nie jest to pomiar względem grupy kontrolnej; to porównanie czasu zegarowego między funkcjami tworzonymi z pomocą agenta a równoważną samodzielną pracą w tych samych codebase’ach. Projekty bez dokumentacji i hooków osiągają może 1,5-2x poprawy — agent traci zbyt dużo czasu na zgadywanie zamiast budowania.18
Inwestycja, która się zwraca: Czas poświęcony na CLAUDE.md, hooki i konfigurację MCP. Każda godzina konfiguracji oszczędza wiele godzin poprawiania błędów agenta. Konfiguracja jest produktem — agent jest silnikiem wykonawczym.
Co mnie zaskoczyło: Jak bardzo serwery MCP zmieniły dynamikę pracy. Przed MCP agenci byli zaawansowanymi edytorami tekstu, które przypadkiem rozumiały Swift. Po MCP są partnerami programistycznymi, którzy piszą, budują, testują, debugują i iterują. Strukturalna pętla informacji zwrotnej odróżnia agenta, który pisze kod, od agenta, który dostarcza kod.
Co powiedziałbym sobie z przeszłości: Zacząć od najmniejszej aplikacji (Reps, 14 plików), poprawnie skonfigurować MCP i hooki, napisać dokładny CLAUDE.md, a potem skalować wzorce na większe projekty. Nie zaczynać od 63-plikowej aplikacji wieloplatformowej. Inwestycja w infrastrukturę jest taka sama niezależnie od rozmiaru projektu — warto zrobić to raz w małym projekcie, a potem skopiować wszędzie indziej.
Przyszłość: Natywna integracja agentów w Xcode 26.3 to początek, nie koniec. Wsparcie MCP dostarczone przez Apple oznacza, że toolchain zmierza w stronę developmentu agent-first. Deweloperzy, którzy już teraz inwestują w struktury projektów zgodne z agentami — czyste pliki CLAUDE.md, testowalne architektury, zautomatyzowane hooki — będą kumulować korzyści z tej inwestycji wraz z rozwojem narzędzi.
Szybka karta referencyjna
Instalacja (jednorazowa konfiguracja)
# XcodeBuildMCP (59 tools)
claude mcp add XcodeBuildMCP -s user \
-e XCODEBUILDMCP_SENTRY_DISABLED=true \
-- npx -y xcodebuildmcp@latest mcp
# Apple Xcode MCP (20 tools)
claude mcp add --transport stdio xcode -s user -- xcrun mcpbridge
# Codex MCP setup
codex mcp add xcode -- xcrun mcpbridge
# Verify
claude mcp list
Kluczowe sekcje CLAUDE.md
1. Project identity (bundle ID, target OS, architecture)
2. File structure with annotations
3. Build and test commands
4. Key patterns and rules
5. Prohibitions (NEVER touch .pbxproj)
6. Framework-specific context
Kluczowe hooki
{
"PreToolUse": [{ "matcher": "Edit|Write", "command": "block .pbxproj" }],
"PostToolUse": [{ "matcher": "Edit|Write", "command": "swiftformat" }]
}
Reguły architektury
@Observable (not ObservableObject)
NavigationStack (not NavigationView)
@State (not @StateObject)
SwiftData @Model (not Core Data)
async/await (not completion handlers)
@MainActor (on all Observable classes)
.glassEffect() (Liquid Glass, iOS 26+)
Priorytety narzędzi MCP
Build: build_sim (not xcodebuild via Bash)
Test: test_sim (not xcodebuild test via Bash)
Sim: list_sims/boot_sim (not xcrun simctl via Bash)
Docs: DocumentationSearch (not WebSearch)
REPL: ExecuteSnippet (not swift via Bash)
Dziennik zmian
| Data | Zmiany |
|---|---|
| 2026-04-28 | Podniesiono rekomendowaną wersję Xcode do 26.4+ dla workflow agentów (26.4.1, 2026-04-16, build 17E202 to najnowsza stabilna wersja, wyłącznie z poprawkami błędów). Przywołano funkcje Xcode 26.4 (2026-03-24, build 17E192) przydatne dla testów i lokalizacji pisanych przez agentów: załączniki obrazów w Swift Testing, severity w Issue.record, ostrzeżenia o awariach testów UI z dołączonymi crashlogami (konkretnie dla aplikacji XCUIApplication(bundleIdentifier:) / XCUIApplication(url:)), ulepszenia edytora String Catalog. Dodano autoinstalator xcodebuildmcp init (v2.1.0+, 2026-02-23) jako alternatywę dla ręcznej konfiguracji MCP. |
| 2026-04-27 | App Store Connect: zgłoszenia z Xcode 26+ obowiązkowe od 2026-04-28. Foundation Models otrzymało APIs SystemLanguageModel.contextSize i tokenCount(for:) (back-deployed do iOS 26.4) — dodano wzorzec dla generowanego przez agenta kodu budżetu promptów FM. iOS 26.4.2 (22 kwi) i iOS 26.5 beta 3 (20 kwi) zostały wydane bez zmian wpływających na toolchain agentów. |
| 2026-04-13 | Pierwsza publikacja. 8 aplikacji, 3 runtime’y, konfiguracja MCP, wzorce CLAUDE.md, hooki, case studies. |
Bibliografia
-
XcodeBuildMCP domyślnie obejmuje telemetrię Sentry. Dokumentacja prywatności projektu szczegółowo opisuje, co jest wysyłane: komunikaty o błędach, ślady stosu, a w niektórych przypadkach ścieżki plików. Zmienna środowiskowa
XCODEBUILDMCP_SENTRY_DISABLED=truecałkowicie wyłącza tę funkcję. ↩ -
Anthropic, „Model Context Protocol Specification”, modelcontextprotocol.io/specification. Specyfikacja MCP definiuje transport JSON-RPC, wykrywanie narzędzi oraz protokół zasobów, które implementują zarówno XcodeBuildMCP, jak i Apple Xcode MCP. ↩
-
XcodeBuildMCP, github.com/getsentry/XcodeBuildMCP. Projekt open source utrzymywany przez Sentry. 59 narzędzi obejmujących przepływy pracy z symulatorem, urządzeniami, debugowaniem i automatyzacją UI. Wersjonowanie semantyczne z changelogami. ↩
-
Apple wprowadziło serwer Xcode MCP jako część inicjatywy inteligentnych narzędzi deweloperskich Xcode 26.3, pozycjonując MCP jako warstwę interfejsu między asystentami kodowania AI a łańcuchem narzędzi Xcode. Oficjalna dokumentacja znajduje się w Xcode Release Notes. ↩
-
Rudrank Riyam, „Exploring Xcode Using MCP Tools”, rudrank.com/exploring-xcode-using-mcp-tools-cursor-external-clients, 2026. Niezależne potwierdzenie liczby narzędzi Apple MCP, zależności od XPC oraz możliwości wyszukiwania w dokumentacji. ↩
-
Jimenez, C.E., Yang, J., Wettig, A. i in., „SWE-bench: Can Language Models Resolve Real-World GitHub Issues?” ICLR 2024. arxiv.org/abs/2310.06770. Agenci ze strukturalnym dostępem do narzędzi osiągali znacznie lepsze wyniki niż agenci ograniczeni do nieustrukturyzowanych poleceń powłoki. To ustalenie potwierdza skuteczność strukturalnych interfejsów MCP dla agentów. ↩
-
Dokumentacja Claude Code CLI, code.claude.com. System hooków, konfiguracja MCP, delegowanie do subagentów oraz definicje agentów. ↩
-
SwiftFormat, github.com/nicklockwood/SwiftFormat. Narzędzie do formatowania Swift używane w hookach PostToolUse w celu zachowania spójnego stylu kodu. ↩
-
Oficjalna strona XcodeBuildMCP, xcodebuildmcp.com. Potwierdza 59 narzędzi MCP na przykładzie danych wyjściowych CLI. Kategorie narzędzi: symulator, urządzenie, debugowanie i automatyzacja UI. Instalacja przez Homebrew lub npx. ↩
-
Swiftjective-C, „Agentic Coding in Xcode 26.3 with Claude Code and Codex”, swiftjectivec.com, luty 2026. Potwierdza, że Xcode 26.3 jest dostarczany z natywnym wsparciem dla Claude Agent i środowiska uruchomieniowego Codex przez Settings > Intelligence. 20 narzędzi MCP udostępnionych przez
xcrun mcpbridge. ↩ -
Blake Crosley, „Two MCP Servers Made Claude Code an iOS Build System”, blakecrosley.com/blog/xcode-mcp-claude-code, luty 2026. Omówienie konfiguracji oraz rzeczywiste wyniki z workflow programowania iOS tego samego autora. ↩
-
Apple Developer News, „Upcoming Requirements”. Wpis z 28 kwietnia 2026 r.: „Aplikacje przesyłane do App Store Connect muszą być budowane za pomocą Xcode 26 lub nowszego z użyciem SDK dla iOS 26, iPadOS 26, tvOS 26, visionOS 26 lub watchOS 26”. macOS nie znajduje się na liście platform objętych tym wymaganiem. ↩
-
Apple, „Xcode 26.4 Release Notes”. Xcode 26.4 (24 marca 2026 r., build 17E192). Funkcje przytoczone z informacji o wydaniu: Swift Testing obsługuje teraz załączniki obrazów przez
CGImage,NSImage,UIImageiCIImage;Issue.recordakceptuje poziomy istotności; niektóre awarie aplikacji w testach UI — konkretnie aplikacji obsługiwanych przezXCUIApplication(bundleIdentifier:)lubXCUIApplication(url:)— są raportowane jako ostrzeżenia z dołączonymi crashlogami, zamiast powodować niepowodzenie testu; edytor String Catalog dodaje wycinanie/kopiowanie/wklejanie wpisów, usuwanie języków i wstępne uzupełnianie tłumaczeń z istniejącego języka, a także ustawienieBUILD_ONLY_KNOWN_LOCALIZATIONS. ↩ -
Apple Developer News, „Xcode 26.4.1 (Build 17E202) Now Available”, 16 kwietnia 2026 r. Wydanie punktowe obejmujące wyłącznie poprawki błędów — naprawia awarię MetricKit wynikającą z brakujących symboli w wersjach iOS / macOS / visionOS sprzed 26.4 oraz błąd alokacji stosu Swift async („freed pointer was not the last allocation” w
swift_asyncLet_finish). ↩ -
getsentry/XcodeBuildMCP wydanie v2.1.0, 23 lutego 2026 r. Dodano polecenie CLI
xcodebuildmcp init, które instaluje umiejętności agenta i konfigurację MCP w jednym kroku, zastępując samodzielny skryptinstall-skill.sh. Automatycznie wykrywa Claude Code, Cursor i Codex; obsługuje--print(zapis konfiguracji do stdout dla nieobsługiwanych klientów) oraz--uninstall(usunięcie). ↩ -
InfoQ, „Apple Adds Context Window Management to Foundation Models”, marzec 2026. Dokumentuje nowe APIs
SystemLanguageModel.contextSizeitokenCount(for:)oraz potwierdza adnotacje@backDeployed(before: iOS 26.4). Zastępuje wcześniejsze przypuszczenie społeczności o twardo zakodowanym limicie 4096 tokenów. ↩ -
Liczby plików pochodzą z polecenia
find . -name '*.swift' -not -path '*/Tests/*' | wc -luruchomionego dla każdego z 8 prywatnych repozytoriów aplikacji 27 kwietnia 2026 r. Pliki testowe zostały wykluczone. Suma jest wewnętrznie spójna z tabelą rozbicia według aplikacji w sekcji §The Portfolio. ↩ -
Subiektywne oszacowanie czasu rzeczywistego, a nie pomiar względem grupy kontrolnej. Wartość 3-5x odzwierciedla pamięć autora dotyczącą porównań czasu realizacji funkcji wspomaganych przez agentów w 2026 r. z równoważnymi funkcjami wdrożonymi samodzielnie w tych samych bazach kodu przed wdrożeniem workflow agentowego. Należy traktować ją jako heurystykę tego, czego można oczekiwać po konfiguracji MCP i hooków, a nie jako benchmark. ↩