Skip to content
Development
Command

/apollo-migrate

**Project context:** Values in angle brackets below (e.g. `<scheme>`, `<JIRA_KEY>`, `<flag-key-enum>`) are resolved at runtime — detect them from the project (`xcodebuild -list -json` for the scheme, `git`/`gh` for repo & owner, the branch name for the Jira key, a codebase

From plugin
ios-workflow-claude
722 skills3 agents22 commands
Install
$ npx -y skills add carloshpdoc/ios-workflow-claude --agent claude-code

How it fires

How this command gets triggered: by you, by Claude, or both.

  • Fires itselfClaude auto-loads it when your prompt matches the work.
  • You can call itInvoke it directly when you want it.
  • Slash command/apollo-migrate

Context preview

What this command does when you run it.

**Project context:** Values in angle brackets below (e.g. `<scheme>`, `<JIRA_KEY>`, `<flag-key-enum>`) are resolved at runtime — detect them from the project (`xcodebuild -list -json` for the scheme, `git`/`gh` for repo & owner, the branch name for the Jira key, a codebase

Command definition

apollo-migrate.md

Apollo Repository Migration

> **Project context:** Values in angle brackets below (e.g. `<scheme>`, `<JIRA_KEY>`, `<flag-key-enum>`) are resolved at runtime — detect them from the project (`xcodebuild -list -json` for the scheme, `git`/`gh` for repo & owner, the branch name for the Jira key, a codebase search for flag/font files), or ask if they cannot be inferred. This plugin ships no per-project config.

Migrate the Apollo repository **$ARGUMENTS** to the new `GraphQLClientProtocol` pattern.

Pre-Migration: Read the Investigation

**MANDATORY:** Before writing any code, read the investigation file:

docs/apollo-removal/issues/$ARGUMENTS.md

If the investigation file does NOT exist, tell the user to run `/apollo-check $ARGUMENTS` first and stop. Do not proceed without an investigation.

If the investigation file exists, read it completely. It contains:

  • The design decisions already made (pattern, fragment handling, PR splitting)
  • The exact files to create, modify, and delete
  • The consumers to update
  • The tests to write
  • Any risks or special considerations

**Follow the investigation.** The migration steps are always the same (see CLAUDE.md). What changes per repo is the target files and consumers identified in the investigation. If you need to deviate from it, note the deviation and the reason — you will need to explain this in the report.

Reference

Read `docs/apollo-migration-guide.md` for the full migration guide.

**Gold standard reference files (read before writing code):**

  • `<scheme>/Repositories/<ReferenceRepo>/Queries/<ReferenceRepo>Query.swift`
  • `<scheme>/Repositories/<ReferenceRepo>/<ReferenceRepo>GraphQLDataSource.swift`
  • `<scheme>/Repositories/<ReferenceRepo>/Models/<ReferenceRepo>GraphQLResponse.swift`
  • `<scheme>/Repositories/<ReferenceRepo>/<ReferenceRepo>ResponseMapper.swift`
  • `<scheme>/Repositories/<ReferenceRepo>/<ReferenceRepo>Repository.swift`
  • `<scheme>/Repositories/<ReferenceRepo>/<ReferenceRepo>RepositoryFactory.swift`

Migration Steps

The steps are always the same (defined in CLAUDE.md). Use the investigation file for repo-specific details:

Step 1: Gather Information

Read the source files listed in the investigation. Verify the investigation is still accurate (no files changed since it was written).

Step 2: Create Query File

Create `Queries/<Name>Query.swift` in the repository directory:

enum <Name>Query {
    static let query = """
        <paste the exact query from the .graphql file>
    """

    static let operationName = "<OperationName>"
}
  • Copy the query **exactly** from the `.graphql` file
  • The operation name is the name after `query` or `mutation` keyword

Step 3: Create GraphQL Response Models

Create `Models/<Name>GraphQLResponse.swift`:

  • Define `Codable` structs matching the GraphQL response JSON structure
  • Use `__typename` mapped via CodingKeys where needed
  • Match the field names from the `.graphql` query
  • Study the `.graphql.swift` generated types to understand the shape and nullability

Step 4: Create GraphQL DataSource

Create `<Name>GraphQLDataSource.swift`:

  • Define protocol `<Name>GraphQLDataSourceProtocol` with async throws methods
  • Implement using `GraphQLClientProtocol` from `import Services`
  • Use `InputEncodable` for query parameters
  • Use `withCheckedThrowingContinuation` to bridge the callback-based client to async/await
  • Include mock loading support (following <ReferenceRepo> pattern)

Step 5: Create Response Mapper

Create `<Name>ResponseMapper.swift`:

  • Define protocol `<Name>ResponseMapperProtocol`
  • Map from `*GraphQLResponse` types to domain models
  • Handle optional fields and type discriminators (`__typename`)
  • Reuse existing domain models from `SharedModels` when they exist

Step 6: Create/Update Repository

Create or update `<Name>Repository.swift`:

  • Keep the existing protocol if consumers already depend on it
  • If the protocol signature needs to change, update all consumers
  • Implementation delegates to DataSource + Mapper
  • Constructor takes `dataSource` and `mapper` parameters
  • **MANDATORY: All completion handlers MUST dispatch to `DispatchQueue.main.async`**
// ✅ CORRECT pattern for repository methods
func fetchData(completion: @escaping (Model?) -> Void) {
    Task {
        do {
            let response = try await dataSource.fetch()
            let model = mapper.map(response)
            DispatchQueue.main.async { completion(model) }
        } catch {
            Log.error(message: error.localizedDescription)
            DispatchQueue.main.async { completion(nil) }
        }
    }
}

Step 7: Create Factory

Create `<Name>RepositoryFactory.swift` following the standard pattern from `docs/apollo-migration-guide.md`.

Step 8: Update Consumers

For each consumer listed in the investigation:

1. Replace `import Apollo` with `import Services` (if needed) 2. Replace `Network<Name>Repository()` with `<Name>RepositoryFactory.makeRepository()` 3. Remove any direct Apollo type usage (`<Query>.Data`, fragments, etc.) 4. Update method calls if the protocol signature changed 5. Verify the consumer still compiles

Step 9: Delete Old Files

Remove the files listed in the investigation's "Files to Delete" section: 1. The `.graphql` file (unless it has shared fragments — check the plan) 2. The `.graphql.swift` file from `<scheme>/Services/Apollo/API/` 3. The old `Network*Repository.swift` (only if fully replaced) 4. Any Apollo-specific extensions or helpers only used by this repo

Step 10: Regenerate Project

**MANDATORY after adding or deleting files.** Run:

tuist generate --no-open

This regenerates `<scheme>.xcodeproj/project.pbxproj` and removes orphaned references to deleted files. Skipping this step causes build failures ("file not found" errors for deleted files that are still referenced in the project).

Step 11: Build and Verify

Build the project to verify compilation:

xcodebuild -works
Read more
Ships withios-workflow-claude

Reusable Claude Code slash-commands, skills, and workflows extracted from real iOS / backend projects. Packaged as three installable plugins - register the marketplace and /plugin install what you need.

Get the whole plugin, auto-invoked
Stats
7
Stars
0
Views
1
Forks
Maintained
Maintenance
Shell
Language
Apache-2.0
License
2mo ago
Last commit
2mo ago
Created

Repo: carloshpdoc/ios-workflow-claude