103 lines
14 KiB
Markdown
103 lines
14 KiB
Markdown
---
|
|
type: work-item
|
|
project: fidelity
|
|
status: done-pending-merge
|
|
ticket: PDIAP-15838
|
|
title: "Remove Apollo for iOS"
|
|
systems: [xflowsdk]
|
|
workstreams: [rest-migration]
|
|
people: [jeff-dewitte, bruce-meeks, adam-abdelhadi, tauf, jeffrey-oleary, aylwing-olivas]
|
|
related: [launchdarkly, github-copilot]
|
|
updated: 2026-05-13
|
|
tags:
|
|
- work-item
|
|
- fidelity
|
|
- rest
|
|
- graphql
|
|
---
|
|
# PDIAP-15838 - Remove Apollo for iOS
|
|
|
|
## Status
|
|
|
|
- Ticket moved to Done after external review feedback was addressed
|
|
- Draft PR remains unmerged and must be kept up to date with `main`
|
|
- PR merge should wait until REST backend is live in production and the previous REST-toggle implementation has been QA-tested and active in production with REST enabled for all consumers for at least 30 days without issues
|
|
- Sized at `8` points
|
|
|
|
---
|
|
|
|
## Context
|
|
|
|
- This ticket covers the REST migration cleanup on iOS.
|
|
- The approved title is `Remove Apollo for iOS`.
|
|
|
|
---
|
|
|
|
## Approved Scope
|
|
|
|
- Remove Apollo from iOS.
|
|
- Remove GraphQL-specific networking code.
|
|
- Remove related tests and mocks.
|
|
- Remove transport feature flags so REST remains.
|
|
|
|
---
|
|
|
|
## Current Guidance
|
|
|
|
- Do not frame this ticket as directly tied to the UIKit-removal spike.
|
|
- Do not imply it is dependent on or part of dismissal-sequencing work.
|
|
- Keep the migration framing explicit: REST remains behind a feature flag until otherwise confirmed, and GraphQL fallback context still matters when describing the overall migration.
|
|
- Keep the REST-activation investigation context as useful background, but focus current updates on Apollo-removal cleanup, validation, and merge sequencing.
|
|
- For standups and concise status updates, center the story on Apollo-removal progress and the `PicoSDK` transitive dependency path; omit extra exploratory asks unless they directly affect the story outcome or create a blocker.
|
|
- Jeff confirmed this investigation should stay ahead of Adam's separate service-side flow report for now and asked for faster progress.
|
|
- Current local evidence shows the LaunchDarkly boolean evaluating to `true`, with payload and context present from the iOS side; remaining uncertainty is around production-side context interpretation, timing/caching, or downstream transport gating.
|
|
- Use the current support path while direct Flagship LaunchDarkly access is missing: monitor the Tauf thread, follow the outreach path to Jeffrey O'Leary, package the scenario for GitHub Copilot with build settings and tool details, and ask Aylwing for a quick perspective if available.
|
|
- Adam later reported that the latest build is activating REST correctly, so the story context returned to the planned GraphQL-removal and related LaunchDarkly-toggle cleanup work.
|
|
- Keep the real-device-only scenario in mind as a useful fallback hypothesis if the issue returns: environment-specific differences such as LaunchDarkly context, timing, or cached toggle state may explain behavior that does not reproduce in the simulator.
|
|
- Adam was the reported source of the REST activation problem, and his side validates behavior on real devices.
|
|
- Current codebase analysis suggests the main remaining source-level blockers are no longer transport selection but residual Apollo model/runtime coupling: `XFlow.Slot` usage in the page interactor/worker path, `NetworkClient` references still touched by init/session lifecycle, and Apollo/AppSync config surface that may still behave like public API.
|
|
- Follow-up analysis suggested `XFlow.Slot` might be the only Apollo-generated production model still used outside the GraphQL-generated folder, but local trial changes surfaced additional Apollo-dependent models/build errors. Treat the `XFlow.Slot` simplification as a promising first step, not as a fully validated statement about the whole codebase.
|
|
- The suggested simplification is to remove the current round-trip `stagedValues() -> [String: String] -> XFlow.Slot -> [String: String] -> XFlowUpdateSlotsRequest.slots` and instead pass `[String: String]` straight through to `XFlowUpdateSlotsRequest.slots`, keeping `SlotVariable: Encodable` in the REST model layer for request serialization.
|
|
- The next AI follow-up should focus only on the first step and ask GitHub Copilot to corroborate residual Apollo-model dependencies by using `xcodebuild` failures, not just static reference search.
|
|
- Follow-up enum validation indicates at least some Apollo-generated enum types can likely be replaced with native Swift `enum Name: String` definitions without preserving Apollo `EnumType` behavior. For the currently checked production callers, Copilot reported no Apollo-specific enum API dependency for `XFlow.ContentType`, `XFlow.ScreenshotFormat`, and `XFlow.NextTransitionType`; current behavior relies on `rawValue`, equality/switch use, and `init?(rawValue:)`-style parsing.
|
|
- The currently observed fallback behavior is simple and code-local: unknown `ContentType` values are skipped by converter guards, unknown `ScreenshotFormat` values fall back to PDF in downstream callers, and unknown `NextTransitionType` values currently propagate as `nil` where the target property is optional.
|
|
- Design direction for the Phase 1 Apollo cleanup: prefer replacing `XFlow.Slot` with a native Swift `Slot` model instead of collapsing it to `[String: String]` through the full production path. Keep `[String: String]` only at the boundary where the REST request/DTO is built in the worker or transport layer.
|
|
- The current implementation state is cleaner on the model side: Apollo-generated production models have now been replaced with native Swift models/enums for the active path, so the next focus should move from model decoupling to remaining Apollo runtime/infrastructure dependencies.
|
|
- The `XFlowInitManager` runtime/init cleanup step has now been applied successfully: the three `NetworkClient.shared.updateAppSyncURL(...)` calls were removed from the start/session lifecycle paths, `getAppSyncEndPoint()` was removed after becoming unused, and the project still compiles with `getEndPoint()` left intact for current REST selection.
|
|
- `NetworkClient.swift` can likely stay temporarily in the tree as a disconnected compatibility shim until broader package/project cleanup, and `XFlowInitManagerConfig.swift` may need to keep AppSync getter/config surface temporarily to avoid an accidental public API break.
|
|
- Follow-up runtime scan now suggests `GraphQL/NetworkClient.swift` has no live production callers and only self-references remain inside the file. The proposed next removal order is to delete `GraphQL/NetworkClient.swift` first, build/reference-check, then delete `GraphQL/ApolloGeneratedCode`, while keeping the AppSync members in `XFlowInitManagerConfig.swift` temporarily as compatibility-only surface.
|
|
- Current local state after broader cleanup: runtime Apollo decoupling and most Apollo-specific test cleanup now appear complete, production code compiles cleanly aside from a pre-existing environment issue, and no live Apollo imports/references remain in production code. Remaining work is mainly package/build cleanup plus the deferred compatibility API surface in `XFlowInitManagerConfig.swift`.
|
|
- Current local state now also indicates the test target compiles cleanly after a minimal follow-up update to `XFlowTransportSelectionTests.swift`, preserving REST-relevant transport tests while removing obsolete GraphQL/Apollo assertions. The remaining Apollo-removal work appears concentrated in package/build cleanup plus the deferred compatibility API surface in `XFlowInitManagerConfig.swift`.
|
|
- Latest follow-up says the Apollo package/build cleanup has also now been applied: direct Apollo dependency references were removed from package/build ownership surfaces, leaving the main remaining follow-up as Fid4 validation plus any later decision on whether to deprecate/remove the temporary AppSync compatibility getters in `XFlowInitManagerConfig.swift`.
|
|
- Apollo source-level cleanup appears sequenced as: replace `XFlow.Slot` with a transport-agnostic model first, decouple `XFlowInitManager` from `NetworkClient` while preserving current REST endpoint behavior, then remove runtime GraphQL code, project wiring, Apollo-only tests/scripts/docs, and finally treat any transitive PicoSDK Apollo dependency as a separate dependency-exit task.
|
|
- Apollo may still remain in the pod graph transitively through PicoSDK even after source-level cleanup, so "Apollo removed" should be framed carefully unless the dependency graph is also cleared.
|
|
- Latest local follow-up suggests `SampleApp` depends on `PicoSDK`, and that transitive dependency may still be the practical reason Apollo remains in the pod graph. Newer `PicoSDK` versions no longer depend on Apollo, but the upgrade path does involve real breaking changes. The current investigation is to determine how `SampleApp` can absorb those changes by comparing against how `Fid4` currently uses `PicoSDK` for the two specific flows that still depend on it.
|
|
- Jeff later confirmed that this `PicoSDK` / `SampleApp` cleanup is in scope for `PDIAP-15838` because Apollo needs to be removed from the project, including the transitive sample-app path. Keep the nuance explicit that this update affects `SampleApp`, not the `XFlowSDK` production runtime directly.
|
|
- David updated `SampleApp` to use the newer `PicoSDK` path, removing Apollo from the transitive sample-app dependency path and re-enabling the FGO and FidFolios flows for testing in `SampleApp`.
|
|
- The `SampleApp` Pico changes now more closely mirror how Pico is already used in Fid4.
|
|
- A draft PR has been opened for `PDIAP-15838 - Remove Apollo for iOS`; after internal review, the link should be sent to Bruce.
|
|
- Internal review found and resolved `PicoSDK` integration concerns: `TransactionContextManager(resolver:)` handles Pico setup internally in `PicoSDK 4.3.18` through lazy resolver-based initialization, the resolver already exists on `XFlowSampleAppViewModel`, and `PicoInterface` was minimally patched so the async completion path avoids a strong `self` capture and returns through `MainActor.run` for UI-state safety.
|
|
- The REST kill-switch removal is intentional for permanent GraphQL deprecation, but merge timing is gated: the previous REST-toggle implementation should first be QA-tested and active in production with REST enabled for all consumers for 30 days without issues.
|
|
- Merge sequencing is now explicitly gated by backend production readiness: Bruce reinforced that the GraphQL/Apollo removal PR should not merge until the backend is in production because GraphQL fallback is still needed before then.
|
|
- Bruce clarified that the current SDK-side updates are not REST behavior changes; the functional REST/backend fix is on the Flagship/Fid4 side, while SDK updates are cleanup, more graceful error handling, logging, and replacing a deprecated logger interface.
|
|
- Bruce asked whether iOS Fid4 has a release-build optimization or code-minification concept comparable to Android; treat this as a validation/build-configuration question until clarified, not as evidence of a known iOS minification issue.
|
|
- Jeff clarified the validation ask: inspect whether Fid4 has simulator-versus-physical-device or generated-build differences in build settings/schemes/configurations, including any optimized-build-size or release-style settings that could explain behavior seen in generated builds but not when running locally.
|
|
- Current likely Fid4 build differences to report: Trunk/generated builds use the `Release` configuration while local runs are usually `Debug`; optimization settings such as `SWIFT_OPTIMIZATION_LEVEL` and `GCC_OPTIMIZATION_LEVEL` can differ; Jenkins uses a generated `build-overrides` xcconfig that local builds do not use and may affect values such as secrets; and CocoaPods dependency resolution can vary depending on the local specs repo state.
|
|
- External review reached Bruce and produced minor feedback. David addressed the feedback and pushed the suggested change.
|
|
- One accepted review change was to set `responseKey: String? = nil` as the default in `FlowRESTOperationContract`, allowing operations such as `updateSlots`, `storeString`, and `publishEvent` to omit `responseKey` when not needed.
|
|
- The native Swift domain enum file should remain as the canonical location for XFlow domain enums after removal of GraphQL-generated code.
|
|
- Jeff directed David to move the ticket to Done, while keeping the PR unmerged for at least 30 days.
|
|
- Branch maintenance is now part of the work: keep the GraphQL/Apollo-removal branch up to date with `main` until the REST backend/toggle validation window allows merge. If future `main` merges create conflicts that look non-trivial, raise it so a 1-2 point maintenance story can be created.
|
|
- May 11 preparation for another REST-layer validation meeting: Fid4 `4.32` was checked out in a separate folder, aligned to the published/internal build `Podfile.lock` from iOSInstaller, and built successfully. Current XQ1 behavior appears to have `iOS-XflowRestEnabled` already active, so Fid4 is loading REST; `Open an account` is the simplest non-authenticated XFlow entry point to use for a quick readiness test.
|
|
- Jeff confirmed May 11 that the REST back end has now been deployed, and a meeting is scheduled for May 12 with the team lead and Bruce to toggle the flag and test both REST and non-REST states.
|
|
- REST detection for the meeting: Charles Proxy to verify `/xflow/api` endpoints and inspect `mobile.launchdarkly.com` bulk payloads for the raw evaluated flag value.
|
|
- Production testing: Raj is trying to get approval to test in production. A production test account will be needed; currently only Bruce is known to have one. David found a way to force the production environment from the simulator if needed.
|
|
- May 12 REST validation nuance: pointing Fid4 at production through the plist by itself still showed GraphQL, but the fuller meeting result was successful iOS REST validation after Raj enabled the production LaunchDarkly toggle with specific targeting for the production test user's context, specifically the MID for the account tested with Bruce. Treat this as evidence that the production REST path can activate on iOS when the LD targeting context matches.
|
|
|
|
---
|
|
|
|
## Sequencing
|
|
|
|
- This story remains sequenced before `PDIAP-15836`.
|
|
- This branch should merge to `main` before the future `PDIAP-15836` / `PDIAP-12284` branch is updated and merged.
|