Add workflows network layer for multipage paywalls#6557
Add workflows network layer for multipage paywalls#6557
Conversation
- Add `getWorkflows` and `getWorkflow` endpoint paths - Add `WorkflowsListResponse` and `PublishedWorkflow` response models - Add `WorkflowDetailProcessor` to handle `inline`/`use_cdn` response actions - Add `WorkflowCdnFetcher` protocol and `DirectWorkflowCdnFetcher` implementation - Add `GetWorkflowsOperation` and `GetWorkflowOperation` cacheable network operations - Add `WorkflowsAPI` facade and wire into `Backend` - Add unit tests for all new components iOS equivalent of RevenueCat/purchases-android#3300 Made-with: Cursor
4 builds increased size
RevenueCat 1.0 (1)
|
| Item | Install Size Change |
|---|---|
| DYLD.String Table | ⬆️ 121.2 kB |
| DYLD.Exports | ⬆️ 9.5 kB |
| Code Signature | ⬆️ 9.4 kB |
| 📝 RevenueCat.WorkflowsAPI.WorkflowsAPI | ⬆️ 4.6 kB |
| RevenueCat.WebBillingAPI.WebBillingAPI | ⬇️ -1.4 kB |
BinarySizeTest 1.0 (1)
com.revenuecat.binary-size-test.local-source
⚖️ Compare build
📦 Install build
⏱️ Analyze build performance
Total install size change: ⬆️ 93.1 kB (0.8%)
Total download size change: ⬆️ 29.6 kB (0.76%)
Largest size changes
| Item | Install Size Change |
|---|---|
| 📝 RevenueCat.WorkflowScreen.value witness | ⬆️ 10.1 kB |
| DYLD.String Table | ⬆️ 10.0 kB |
| 📝 RevenueCat.PublishedWorkflow.__derived_struct_equals | ⬆️ 7.7 kB |
| RevenueCat.UIConfig.Equatable | ⬇️ -4.9 kB |
| 📝 RevenueCat.WorkflowScreen.__derived_struct_equals | ⬆️ 4.6 kB |
BinarySizeTest 1.0 (1)
com.revenuecat.binary-size-test.cocoapods
⚖️ Compare build
📦 Install build
⏱️ Analyze build performance
Total install size change: ⬆️ 205.3 kB (0.79%)
Total download size change: ⬆️ 44.2 kB (0.75%)
Largest size changes
| Item | Install Size Change |
|---|---|
| DYLD.String Table | ⬆️ 78.0 kB |
| 📝 RevenueCat.WorkflowScreen.value witness | ⬆️ 10.1 kB |
| 📝 RevenueCat.PublishedWorkflow.__derived_struct_equals | ⬆️ 7.5 kB |
| RevenueCat.UIConfig.Equatable | ⬇️ -4.8 kB |
| Code Signature | ⬆️ 4.8 kB |
BinarySizeTest 1.0 (1)
com.revenuecat.binary-size-test.spm
⚖️ Compare build
📦 Install build
⏱️ Analyze build performance
Total install size change: ⬆️ 84.5 kB (0.83%)
Total download size change: ⬆️ 30.7 kB (0.77%)
Largest size changes
| Item | Install Size Change |
|---|---|
| 📝 RevenueCat.WorkflowScreen.value witness | ⬆️ 10.1 kB |
| 📝 RevenueCat.PublishedWorkflow.__derived_struct_equals | ⬆️ 7.7 kB |
| RevenueCat.UIConfig.Equatable | ⬇️ -4.9 kB |
| 📝 RevenueCat.WorkflowScreen.__derived_struct_equals | ⬆️ 4.6 kB |
| RevenueCat.PaywallComponent.StackComponent.StackComponent | ⬇️ -4.0 kB |
🛸 Powered by Emerge Tools
Comment trigger: Size diff threshold of 100.00kB exceeded
- Add WorkflowTrigger struct (name, type, action_id, component_id) - Add triggers, outputs, and metadata fields to WorkflowStep - Add metadata field to PublishedWorkflow - Remove value field from WorkflowTriggerAction (backend uses step_id only) Made-with: Cursor
- Replace value/resolvedTargetStepId assertions with stepId - Remove testDecodeWorkflowTriggerActionValueTakesPrecedence (value field removed) - Add testDecodeWorkflowTrigger for new WorkflowTrigger struct - Add testDecodePublishedWorkflowWithMetadata - Update testDecodeWorkflowStepDefaults to cover triggers, outputs, metadata - Add testDecodeWorkflowStepMatchingActualBackendResponse with real backend payload Made-with: Cursor
Made-with: Cursor
…o callbacks CDN fetch and JSON decoding were running once per deduplicated callback. Compute the Result<WorkflowFetchResult, BackendError> once outside the performOnAllItemsAndRemoveFromCache loop, matching the pattern used by GetOfferingsOperation and other operations in the codebase. Made-with: Cursor
…purchases-ios into feat/workflows-network-layer
…y errors correctly - Replace Data(contentsOf:) with URLSession.shared.dataTask + DispatchSemaphore in DirectWorkflowCdnFetcher; gets URLSession timeout, HTTP status validation, and proper network stack semantics - Add WorkflowDetailProcessingError.cdnFetchFailed typed error so CDN I/O failures are distinguishable from envelope parsing failures - Catch cdnFetchFailed in GetWorkflowOperation and map to NetworkError.networkError instead of NetworkError.decoding, fixing misleading error classification - Update WorkflowDetailProcessorTests to assert the typed error is thrown Made-with: Cursor
…gContinuation
- Make WorkflowCdnFetcher.fetchCompiledWorkflowData async throws; use
withCheckedThrowingContinuation to bridge URLSession.dataTask into async,
avoiding any thread-blocking
- Make WorkflowDetailProcessor.process async throws to propagate async
- Bridge into async in GetWorkflowOperation via Task {}; completion() is
called inside the Task after CDN fetch and decoding complete
- Update WorkflowDetailProcessorTests to async throws with await
Made-with: Cursor
Avoids Task{} in GetWorkflowOperation and keeps all operations calling
completion() synchronously from within the HTTP callback, matching every
other operation in the codebase.
- WorkflowCdnFetcher.fetchCompiledWorkflowData now takes a completion handler;
DirectWorkflowCdnFetcher uses URLSession.dataTask (non-blocking, no semaphore)
- WorkflowDetailProcessor.process now takes a completion handler; inline action
completes synchronously, use_cdn fans out to the fetcher callback
- GetWorkflowOperation splits into getWorkflow/handleResponse/backendResult/
distribute helpers to stay within line-length limits
- WorkflowDetailProcessorTests updated to use waitUntilValue pattern
Made-with: Cursor
Space-separated appUserID+workflowId could collide (e.g. user 'a b' + workflow 'c' == user 'a' + workflow 'b c'). Use newline as delimiter, matching the precedent set by GetWebBillingProductsOperation. Made-with: Cursor
ajpallares
left a comment
There was a problem hiding this comment.
Don't have all the context yet, but I have some early comments
| .postOfferForSigning, | ||
| .postRedeemWebPurchase, | ||
| .getCustomerCenterConfig, | ||
| .getWorkflow, |
There was a problem hiding this comment.
Is it deliberate to have getWorkflows supportsSignatureVerification --> true while getWorkflow is false?
There was a problem hiding this comment.
yes, the backend only supports signature verification for the endpoint that lists workflows
There was a problem hiding this comment.
I am going to bring it up because it looks like an oversight to me
Generated by 🚫 Danger |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 30001f0. Configure here.





Summary
iOS equivalent of RevenueCat/purchases-android#3300.
Adds the networking layer needed to fetch multipage paywall workflows from the RevenueCat backend.
getWorkflows(appUserID:)andgetWorkflow(appUserID:workflowId:)inHTTPRequestPathWorkflowsListResponse,WorkflowSummary,PublishedWorkflow,WorkflowStep,WorkflowScreen,WorkflowTriggerAction,WorkflowFetchResultWorkflowDetailProcessornormalises the two response shapes —inline(data embedded in response) anduse_cdn(fetch JSON from CDN URL).GetWorkflowsOperationandGetWorkflowOperationasCacheableNetworkOperationsubclasses with callback deduplicationNote
Medium Risk
Adds new backend endpoints and response processing that can fetch workflow JSON from arbitrary CDN URLs, impacting networking behavior and error handling. Risk is moderated by heavy unit test and snapshot coverage plus request deduplication via callback caches.
Overview
Adds a new
WorkflowsAPIto fetch multipage paywall workflows from the backend via newGET /v1/subscribers/{appUserID}/workflowsandGET /v1/subscribers/{appUserID}/workflows/{workflowId}paths, wired intoBackend.Introduces workflow response models plus
GetWorkflowsOperation/GetWorkflowOperationwith callback-cache deduping and app-user ID validation. For workflow detail, addsWorkflowDetailProcessorto normalizeinlinevsuse_cdnenvelopes, including a newHTTPClient.fetchRawData(from:)helper to fetch workflow JSON from CDN URLs using the SDK’s configuredURLSession.Updates tests with new mocks, decoding/processor unit tests, and backend request snapshot coverage for the new endpoints.
Reviewed by Cursor Bugbot for commit e7b8a9f. Bugbot is set up for automated code reviews on this repo. Configure here.