Skip to content

Use typed Swift JSON-RPC envelopes#299

Merged
kiftio merged 1 commit into
mainfrom
json-rpc-typing/swift-typed-envelope
Jun 18, 2026
Merged

Use typed Swift JSON-RPC envelopes#299
kiftio merged 1 commit into
mainfrom
json-rpc-typing/swift-typed-envelope

Conversation

@kiftio

@kiftio kiftio commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

What changes are you making?

Replaces ad-hoc JSONSerialization usage throughout the Swift protocol layer with typed Codable models, and introduces a proper JSONRPCID enum to correctly handle string, integer, and floating-point JSON-RPC request IDs.

Previously, the JSON-RPC id field was decoded as String?, meaning numeric IDs (e.g. "id": 7) were silently dropped. This caused issues where responses to requests with numeric IDs could not be correctly correlated. The new JSONRPCID enum handles String, Int64, and Null variants, and is used consistently across UCPMessage, DelegationEntry, JSONRPCResponse, JSONRPCErrorResponse, and the encode/decode helpers.

The monolithic JSONRPCRequest / JSONRPCParams types have been replaced with:

  • JSONRPCEnvelope — a lightweight type for reading method and id before committing to a full decode
  • JSONRPCRequest<Params> — a generic typed request for each specific params shape (JSONRPCReadyParams, JSONRPCCheckoutParams, JSONRPCErrorParams, JSONRPCWindowOpenParams)

The requestParamsData(for:from:) function now dispatches on method name to decode and re-encode only the known fields for a given request type, which means unknown params are stripped before being forwarded to handlers.

How to test

  1. Run the Swift protocol test suite: swift test from protocol/languages/swift/
  2. Verify the new test cases pass:
    • decodesReadyRequestWithNumericID — confirms .ready is produced when id is an integer
    • encodesReadyResponseWithNumericID — confirms the encoded response preserves a numeric id
    • methodNotFoundResponsePreservesNumericRequestID — confirms error responses echo back numeric IDs
    • windowOpenRequestDropsUnknownParamsBeforeDispatch — confirms unknown params are not forwarded

Before you merge

Important

  • I've added tests to support my implementation
  • I have read and agree with the Contribution Guidelines
  • I have read and agree with the Code of Conduct
  • I've updated the relevant platform README (platforms/swift/README.md and/or platforms/android/README.md)

Releasing a new Swift version?
  • I have bumped the version in ShopifyCheckoutKit.podspec
  • I have bumped the version in platforms/swift/Sources/ShopifyCheckoutKit/ShopifyCheckoutKit.swift
  • I have updated platforms/swift/CHANGELOG.md
  • I have updated the SwiftPM/CocoaPods version snippets in platforms/swift/README.md (major version only)
Releasing a new Android version?
  • I have bumped the versionName in platforms/android/lib/build.gradle
  • I have updated platforms/android/CHANGELOG.md
  • I have updated the Gradle/Maven version snippets in platforms/android/README.md

Tip

See the Contributing documentation for the full release process per platform.

kiftio commented Jun 18, 2026

Copy link
Copy Markdown
Contributor Author

@kiftio kiftio mentioned this pull request Jun 18, 2026
11 tasks
@kiftio kiftio marked this pull request as ready for review June 18, 2026 14:03
@kiftio kiftio requested a review from a team as a code owner June 18, 2026 14:03
@github-actions

github-actions Bot commented Jun 18, 2026

Copy link
Copy Markdown

React Native — Coverage Report

Lines Statements Branches Functions
Coverage: 92%
91.66% (319/348) 87.86% (181/206) 100% (82/82)

Comment on lines +36 to +37
case double(Double)

@kieran-osgood-shopify kieran-osgood-shopify Jun 18, 2026

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.

JSONRPC id seems like it should be string / number / null - and not contain fractions, should double be replaced with a case null

@kieran-osgood-shopify kieran-osgood-shopify Jun 18, 2026

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.

Possible new shape

 enum JSONRPCID: Codable, Equatable, ExpressibleByStringLiteral, ExpressibleByIntegerLiteral {
       case string(String)
       case int(Int64)
       case null

       init(stringLiteral value: String) {
           self = .string(value)
       }

       init(integerLiteral value: Int64) {
           self = .int(value)
       }

       var stringValue: String? {
           guard case let .string(value) = self else {
               return nil
           }

           return value
       }

       init(from decoder: Decoder) throws {
           let container = try decoder.singleValueContainer()

           if container.decodeNil() {
               self = .null
           } else if let value = try? container.decode(String.self) {
               self = .string(value)
           } else if let value = try? container.decode(Int64.self) {
               self = .int(value)
           } else {
               throw DecodingError.typeMismatch(
                   JSONRPCID.self,
                   DecodingError.Context(
                       codingPath: decoder.codingPath,
                       debugDescription: "JSON-RPC id must be a string, integer, or null"
                   )
               )
           }
       }

       func encode(to encoder: Encoder) throws {
           var container = encoder.singleValueContainer()

           switch self {
           case let .string value:
               try container.encode(value)
           case let .int value:
               try container.encode(value)
           case .null:
               try container.encodeNil()
           }
       }
   }

@kiftio kiftio force-pushed the json-rpc-typing/swift-typed-envelope branch 3 times, most recently from b042647 to 940fa40 Compare June 18, 2026 15:45

kiftio commented Jun 18, 2026

Copy link
Copy Markdown
Contributor Author

Merge activity

  • Jun 18, 7:46 PM UTC: A user started a stack merge that includes this pull request via Graphite.
  • Jun 18, 7:48 PM UTC: Graphite rebased this pull request as part of a merge.
  • Jun 18, 8:02 PM UTC: @kiftio merged this pull request with Graphite.

@kiftio kiftio changed the base branch from 06-16-respond_to_unknown_requests_with_error to graphite-base/299 June 18, 2026 19:46
@kiftio kiftio changed the base branch from graphite-base/299 to main June 18, 2026 19:47
@kiftio kiftio force-pushed the json-rpc-typing/swift-typed-envelope branch from 940fa40 to b99d3d3 Compare June 18, 2026 19:47
@kiftio kiftio merged commit 71879f5 into main Jun 18, 2026
26 checks passed
@kiftio kiftio deleted the json-rpc-typing/swift-typed-envelope branch June 18, 2026 20:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants