Skip to content

feat(remote-config): support RC Container format in network stack and use for remote-config request#7037

Merged
rickvdl merged 6 commits into
mainfrom
rickvdl/remote-config-request
Jun 19, 2026
Merged

feat(remote-config): support RC Container format in network stack and use for remote-config request#7037
rickvdl merged 6 commits into
mainfrom
rickvdl/remote-config-request

Conversation

@rickvdl

@rickvdl rickvdl commented Jun 18, 2026

Copy link
Copy Markdown
Member

Part of a stack of PRs, builds on #7030.

Implements support for the RCContainer format in the network stack, and implements it for the POST /v2/config endpoint. The network stack part of this PR matches that of RevenueCat/purchases-android#3607

  • Requests to this endpoint now add the Accept: application/x-rc-format
  • Automatic etag caching is disabled
  • The response is parsed into the RCContainer binary format

No data is extracted from the RCContainer response yet, this will be done in a follow up PR.


Note

Medium Risk
Touches shared HTTP decoding and caching behavior plus a new binary remote-config contract; signature verification is intentionally disabled for this endpoint until signing lands.

Overview
Remote config is wired through the shared HTTP stack as POST /v2/config, requesting Accept: application/x-rc-format and decoding successful bodies into RCContainer (callbacks now return RCContainer?). 204 No Content is treated as success with a nil container instead of attempting binary parse.

The client adds per-path headers, skips ETag caching for remote config (even if the server sends ETag headers), and leaves signature verification off for that path until binary responses are signed (TODOs in code). Decoding goes through HTTPResponseBody.create(with:httpStatusCode:), with Optional mapping noContent to nil and HTTPClient.responseBodyData normalizing 304 vs 204 body handling.

Tests cover POST path/body, Accept header, no ETag/signature headers, RC Container parse success, 204 nil, and decode failures for invalid/JSON/empty 200 responses.

Reviewed by Cursor Bugbot for commit 60efa0c. Bugbot is set up for automated code reviews on this repo. Configure here.

@rickvdl rickvdl changed the title feat(remote-config): request RC Container format feat(remote-config): implement RC Container format in network stack and enable for remote-config request Jun 18, 2026
@rickvdl rickvdl changed the title feat(remote-config): implement RC Container format in network stack and enable for remote-config request feat(remote-config): implement RC Container format in network stack and use for remote-config request Jun 18, 2026
@rickvdl rickvdl changed the title feat(remote-config): implement RC Container format in network stack and use for remote-config request feat(remote-config): support RC Container format in network stack and use for remote-config request Jun 18, 2026
@rickvdl rickvdl changed the title feat(remote-config): support RC Container format in network stack and use for remote-config request feat(remote-config): request RC Container format Jun 18, 2026
@rickvdl rickvdl changed the title feat(remote-config): request RC Container format feat(remote-config): support RC Container format in network stack and use for remote-config request Jun 18, 2026
@rickvdl rickvdl force-pushed the rickvdl/remote-config-request branch from 5e680dd to b985dc0 Compare June 18, 2026 13:14
@emerge-tools

emerge-tools Bot commented Jun 18, 2026

Copy link
Copy Markdown

4 builds increased size

Name Version Download Change Install Change Approval
RevenueCat
com.revenuecat.PaywallsTester
1.0 (1) 18.8 MB ⬆️ 7.4 kB (0.04%) 68.1 MB ⬆️ 30.3 kB (0.04%) N/A
BinarySizeTest
com.revenuecat.binary-size-test.local-source
1.0 (1) 4.3 MB ⬆️ 11.5 kB (0.27%) 13.0 MB ⬆️ 22.7 kB (0.18%) N/A
BinarySizeTest
com.revenuecat.binary-size-test.cocoapods
1.0 (1) 6.6 MB ⬆️ 12.4 kB (0.19%) 28.8 MB ⬆️ 43.6 kB (0.15%) ⏳ Needs approval
BinarySizeTest
com.revenuecat.binary-size-test.spm
1.0 (1) 4.5 MB ⬆️ 11.9 kB (0.27%) 11.4 MB ⬆️ 18.9 kB (0.17%) N/A

RevenueCat 1.0 (1)
com.revenuecat.PaywallsTester

⚖️ Compare build
⏱️ Analyze build performance

Total install size change: ⬆️ 30.3 kB (0.04%)
Total download size change: ⬆️ 7.4 kB (0.04%)

Largest size changes

Item Install Size Change
DYLD.String Table ⬆️ 12.8 kB
DYLD.Exports ⬆️ 888 B
Code Signature ⬆️ 624 B
RevenueCat.ETagManager.ETagManager ⬇️ -520 B
Other ⬆️ 16.5 kB
View Treemap

Image of diff

BinarySizeTest 1.0 (1)
com.revenuecat.binary-size-test.local-source

⚖️ Compare build
📦 Install build
⏱️ Analyze build performance

Total install size change: ⬆️ 22.7 kB (0.18%)
Total download size change: ⬆️ 11.5 kB (0.27%)

Largest size changes

Item Install Size Change
📝 RevenueCat.RCContainer.init(data) ⬆️ 1.7 kB
📝 RevenueCat.RCContainer.Parser.checksumString(in) ⬆️ 1.5 kB
DYLD.String Table ⬆️ 1.3 kB
📝 RevenueCat.RCContainer.Parser.base64URLString(in) ⬆️ 1.2 kB
📝 RevenueCat.RCContainer.Parser.parseElement(index) ⬆️ 920 B
View Treemap

Image of diff

BinarySizeTest 1.0 (1)
com.revenuecat.binary-size-test.cocoapods

⚖️ Compare build
📦 Install build
⏱️ Analyze build performance

Total install size change: ⬆️ 43.6 kB (0.15%)
Total download size change: ⬆️ 12.4 kB (0.19%)

Largest size changes

Item Install Size Change
DYLD.String Table ⬆️ 13.7 kB
📝 RevenueCat.RCContainer.init(data) ⬆️ 1.7 kB
📝 RevenueCat.RCContainer.Parser.checksumString(in) ⬆️ 1.5 kB
📝 RevenueCat.RCContainer.Parser.base64URLString(in) ⬆️ 1.2 kB
Code Signature ⬆️ 1.0 kB
View Treemap

Image of diff

BinarySizeTest 1.0 (1)
com.revenuecat.binary-size-test.spm

⚖️ Compare build
📦 Install build
⏱️ Analyze build performance

Total install size change: ⬆️ 18.9 kB (0.17%)
Total download size change: ⬆️ 11.9 kB (0.27%)

Largest size changes

Item Install Size Change
📝 RevenueCat.RCContainer.init(data) ⬆️ 1.7 kB
📝 RevenueCat.RCContainer.Parser.checksumString(in) ⬆️ 1.5 kB
📝 RevenueCat.RCContainer.Parser.base64URLString(in) ⬆️ 1.2 kB
Code Signature ⬆️ 936 B
📝 RevenueCat.RCContainer.Parser.parseElement(index) ⬆️ 920 B
View Treemap

Image of diff


🛸 Powered by Emerge Tools


static func create(with data: Data, httpStatusCode: HTTPStatusCode) throws -> Wrapped? {
guard httpStatusCode != .noContent else {
return nil

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not the biggest fan of having this check in here, but without it the API client would pass the 204 since it's a successful response, and a 204 wouldn't report nil for data but just empty Data(). So the API client would just pass the 204 down, and in here we'd either fail (because Data() is empty) or if we'd check for !data.isEmpty we'd suddenly allow empty payloads for all 2xx responses, potentially treating empty 200's as successful instead of only 204's.

Alternatively I could put the parsing logic in the RemoteConfigAPI, but that'd mean every implementation that uses RCContainer would have to do the parsing on the callsite, which also isn't great.

@rickvdl

rickvdl commented Jun 18, 2026

Copy link
Copy Markdown
Member Author

@RCGitBot please test

@rickvdl rickvdl marked this pull request as ready for review June 18, 2026 13:23
@rickvdl rickvdl requested a review from a team as a code owner June 18, 2026 13:23

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ 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 b985dc0. Configure here.

Comment thread Sources/Networking/HTTPClient/HTTPClient.swift
@rickvdl rickvdl force-pushed the rickvdl/remote-config-request branch from b985dc0 to 4e4ae0d Compare June 18, 2026 14:07

@tonidero tonidero left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this makes sense! I'm just unsure about cursor's comment...

Comment thread Sources/Networking/HTTPClient/HTTPClient.swift
return self.flatMap { response in // Convert the `Result` type
Result<VerifiedHTTPResponse<Value>, Error> { // Create a new `Result<Value>`
try response.mapBody { data in // Convert the from `Data` -> `Value`
try Value.create(with: data) // Decode `Data` into `Value`

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To confirm, this old create method is still used? Just to check if it could be removed.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes it's still used for all previous endpoints. Had a chat with Antonio and I'll probably revise this part a bit with the signature verification work I'm doing, so this may change in a follow up PR.

@tonidero tonidero left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah I was seeing an old version of the code. I think it's solved now indeed. Thank you!

@rickvdl

rickvdl commented Jun 18, 2026

Copy link
Copy Markdown
Member Author

@RCGitBot please test

@ajpallares ajpallares force-pushed the rickvdl/remote-config-request branch from fecb801 to 4e4ae0d Compare June 19, 2026 09:55
Base automatically changed from rickvdl/remote-config-rc-container-format to main June 19, 2026 10:38
@rickvdl rickvdl force-pushed the rickvdl/remote-config-request branch from 4e4ae0d to 60efa0c Compare June 19, 2026 10:43
@rickvdl

rickvdl commented Jun 19, 2026

Copy link
Copy Markdown
Member Author

@RCGitBot please test

@rickvdl rickvdl merged commit 6330937 into main Jun 19, 2026
43 of 44 checks passed
@rickvdl rickvdl deleted the rickvdl/remote-config-request branch June 19, 2026 12:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants