DOC
Créer une app iOS native depuis une API avec Happy et Steve
Orchestration d'une API complète (Happy) vers une app iOS/macOS/watchOS production-ready (Steve)
Créer une app iOS native depuis une API avec Happy et Steve
Contexte
Vous avez un produit web et vous voulez offrir une première-classe expérience native sur iOS, macOS, watchOS, tvOS et visionOS. Ce workflow orchestre deux agents : Happy conçoit l’API exhaustive complète (REST ou GraphQL) adaptée à tous les clients, puis Steve la consomme pour construire un starter kit SwiftUI compilable, des tests Swift, et accompagne jusqu’au déploiement App Store Connect.
Prérequis
Phase 1 (Happy — API Design)
- Projet web existant (Next.js, Rails, Django, etc.)
- Stack backend connu et documenté
- Modèles de données et endpoints existants (ou spécification préliminaire)
- Optionnel : OpenAPI 3.1 spec si API existe déjà
Phase 2 (Steve — iOS Implementation)
- Xcode 16+ avec Swift 6
- iOS deployment target: 16.0+
- macOS deployment target: 13.0+ (optionnel)
- watchOS deployment target: 10.0+ (optionnel)
- Developer certificate + App Store Connect access
Ecosystem Prerequisites
- Happy génère
docs/api/(source de vérité) - Steve lit
docs/api/pour construire natives - Fluke (Android) réutilisera la même
docs/api/sans redéfinir
Étapes
1. Phase 1 : Conception API avec Happy
Invoquer Happy pour auditer le projet et concevoir l’API :
/ulk:happy
# ou
happy
# ou
API design
# ou
concevoir API
2. Happy Phase 0-1 : Diagnostic et cadrage
Happy pose des questions :
🏗️ Happy — Architecte API
━━━━━━━━━━━━━━━━━━━━━━━━
Diagnostic du projet web:
Framework : Next.js 15
Backend : Node.js/Express (optionnel, détecté)
Base de données: PostgreSQL (Neon)
Auth : JWT + OAuth2
Clients prévus:
✅ Web (React)
✅ iOS (SwiftUI)
✅ Android (Flutter/Kotlin)
☐ CLI
☐ Partenaires tiers
Style API:
✅ REST (recommandé pour mobile)
☐ GraphQL (complexe pour mobile)
Cadrage:
1. Versioning? (URI: /v1/ vs Header: Accept)
2. Auth? (JWT Bearer, API Key, OAuth2)
3. Rate limiting? (Oui, recommandé)
4. Offline sync? (Oui, pour mobile)
5. Push notifications? (APNs + FCM)
3. Happy Phase 2-4 : Audit et conception API
Happy génère docs/api/ :
docs/api/
├── README.md # Overview + quick start
├── openapi.yaml # Spec complète (OpenAPI 3.1)
├── auth.md # Auth flows (JWT, OAuth2, etc.)
├── endpoints/
│ ├── users.md # GET /users, POST /users, etc.
│ ├── posts.md
│ ├── comments.md
│ └── ...
├── schemas/
│ ├── User.json
│ ├── Post.json
│ └── ...
├── push.md # APNs + FCM setup
├── sync.md # Offline sync strategy
└── errors.md # Error codes + handling
Exemple docs/api/endpoints/users.md :
## GET /users
Fetch paginated list of users.
### Query Parameters
- `page` (number, default: 1)
- `limit` (number, default: 20, max: 100)
- `search` (string, optional): Search by name/email
### Response
Status: 200 OK
\`\`\`json
{
"data": [
{
"id": "user-123",
"name": "John Doe",
"email": "john@example.com",
"avatar": "https://...",
"createdAt": "2026-04-14T10:30:00Z"
}
],
"pagination": {
"page": 1,
"limit": 20,
"total": 150
}
}
\`\`\`
### POST /users
Create a new user.
### Request Body
\`\`\`json
{
"name": "Jane Doe",
"email": "jane@example.com",
"password": "secure_password"
}
\`\`\`
### Response
Status: 201 Created
4. Phase 2 : Implémentation iOS avec Steve
Une fois docs/api/ généré par Happy, invoquer Steve :
/ulk:steve
# ou
steve
# ou
SwiftUI
# ou
iOS app
5. Steve Phase 0-1 : Diagnostic et setup
Steve lit docs/api/ et configure le projet :
🍎 Steve — Orchestrateur Apple
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Lisant docs/api/...
✅ OpenAPI 3.1 trouvé
✅ 12 endpoints détectés
✅ Auth: JWT Bearer
✅ Push: APNs + FCM supporté
Platforms cibles:
✅ iOS 16.0+
✅ macOS 13.0+
✅ watchOS 10.0+
☐ tvOS (optionnel)
☐ visionOS (optionnel)
Dépendances Swift:
✅ URLSession (built-in)
✅ SwiftData (built-in, iOS 17+)
✅ async/await (Swift 5.5+)
+ Packages: Alamofire, Apollo (GraphQL opt.), Combine
Configuration App Store Connect:
1. App ID created
2. Certificates configured
3. Provisioning profiles ready
6. Steve Phase 2-5 : Génération starter kit
Steve génère un projet Xcode compilable :
MyApp/
├── MyApp.swift # @main app entry
├── Models/
│ ├── User.swift # Decodable structures
│ ├── Post.swift
│ └── ...
├── Services/
│ ├── APIClient.swift # Gère requêtes API
│ ├── AuthService.swift # JWT + OAuth2
│ ├── PushNotificationService.swift
│ └── OfflineSyncService.swift
├── ViewModels/
│ ├── UserListViewModel.swift
│ ├── PostDetailViewModel.swift
│ └── ...
├── Views/
│ ├── ContentView.swift # Root navigation
│ ├── UserListView.swift
│ ├── PostDetailView.swift
│ ├── AuthView.swift
│ └── SettingsView.swift
├── Tests/
│ ├── APIClientTests.swift
│ ├── UserListViewModelTests.swift
│ └── ...
└── MyApp.xcodeproj # Xcode project (compilable)
Exemple de sortie
APIClient.swift (généré) :
import Foundation
class APIClient {
static let shared = APIClient()
private let baseURL = URL(string: "https://api.example.com")!
private var token: String?
func request<T: Decodable>(
_ endpoint: String,
method: String = "GET",
body: Encodable? = nil
) async throws -> T {
var request = URLRequest(url: baseURL.appendingPathComponent(endpoint))
request.httpMethod = method
if let token = token {
request.setValue("Bearer \(token)", forHTTPHeaderField: "Authorization")
}
if let body = body {
request.httpBody = try JSONEncoder().encode(body)
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
}
let (data, response) = try await URLSession.shared.data(for: request)
guard let httpResponse = response as? HTTPURLResponse,
(200...299).contains(httpResponse.statusCode) else {
throw APIError.requestFailed
}
return try JSONDecoder().decode(T.self, from: data)
}
func setAuthToken(_ token: String) {
self.token = token
}
}
enum APIError: Error {
case requestFailed
case decodingFailed
case unauthorized
}
Variantes
- Variante A : GraphQL au lieu de REST — Happy peut concevoir une API GraphQL, Steve l’implémente avec Apollo iOS
- Variante B : Offline-first sync — Happy conçoit sync strategy (optimistic updates, conflict resolution), Steve l’implémente avec SwiftData
- Variante C : Multiple platforms — Steve crée starter kits parallèles pour iOS + macOS + watchOS + tvOS depuis la même
docs/api/
Agents enchaînés
Flux orchestré (Happy → Steve) :
Happy (mobile/49) — Conception API
├─ Phase 0 : Diagnostic projet web (5 min)
├─ Phase 1 : Cadrage clients (5 min)
├─ Phase 2 : Audit endpoints existants (20 min)
├─ Phase 3 : Conception complète (20 min)
└─ Output : docs/api/ (OpenAPI 3.1)
↓
Steve (mobile/27) — Implémentation iOS
├─ Phase 0 : Lire docs/api/ (5 min)
├─ Phase 1 : Setup Xcode + App Store Connect (10 min)
├─ Phase 2 : Générer Models + Services (30 min)
├─ Phase 3 : Générer Views + ViewModels (30 min)
├─ Phase 4 : Générer Tests (20 min)
└─ Output : Xcode project compilable + deploy instructions
Après déploiement iOS, Fluke (48) réutilise la même docs/api/ pour Android.
Troubleshooting
| Symptôme | Cause probable | Résolution |
|---|---|---|
| ”Happy can’t detect endpoints” | Projet web trop complexe ou mal documenté | Fournir OpenAPI spec ou relancer avec --manual |
| ”Steve reports missing App Store Certificate” | Developer account non configuré | Lancer asc auth login et créer certificat via App Store Connect |
| ”Models decoding fails” | JSON schema doesn’t match API response | Vérifier endpoints réels et relancer Steve avec --skip-models pour édition manuelle |
| ”Push notifications not working” | APNs key not configured | Générer APNs key dans App Store Connect, configurer dans Steve via --apns-key |
Voir aussi
./12-web-to-flutter.md— Créer une app Android/Flutter (même API, autre platform)./02-blackemperor-pre-release.md— Pre-release orchestrator (inclut iOS deployment)agents/mobile/49-happy.md— Documentation Happy (API design)agents/mobile/27-steve.md— Documentation Steve (iOS implementation)agents/_shared/mobile-protocol.md— Protocole mobile complet- App Store Connect : https://appstoreconnect.apple.com — Developer dashboard