Wire Swift kit for UCP events#65
Conversation
759d198 to
f75bc63
Compare
38999c3 to
8f4ff5b
Compare
🔍 Denylist Analysis ResultsAnalyzed 1 packages. .github/workflows/swift-test-protocol.yml✅ Known Packages - Approved for Use (1)
⏳ Package Age Warnings❓ Packages With Unknown Age (1) — unable to determine publish date
For any questions or to provide feedback, please reach out to #help-bumperbot. Generated by Bumperbot. |
bba6c9c to
a1043aa
Compare
f85ca58 to
5db6643
Compare
| #if !COCOAPODS | ||
| import ShopifyCheckoutProtocol | ||
| #endif |
There was a problem hiding this comment.
The protocol gets bundled as a source in the cocoapod
| } | ||
|
|
||
| private static let baseUserAgent = "ShopifyCheckoutSDK/\(MetaData.version)" | ||
| private static let baseUserAgent = "ShopifyCheckoutKit/\(MetaData.version)" |
There was a problem hiding this comment.
This is not final. It can be handled in a follow up either for swift specifically or across platforms in the repo
There was a problem hiding this comment.
Draft:
| public static let complete = NotificationDescriptor<Checkout>(method: "ec.complete") | ||
| public static let error = NotificationDescriptor<ErrorResponse>(method: "ec.error") | ||
| public static let lineItemsChange = NotificationDescriptor<Checkout>( | ||
| method: "ec.line_items.change") | ||
| public static let messagesChange = NotificationDescriptor<Checkout>( | ||
| method: "ec.messages.change") | ||
| public static let start = NotificationDescriptor<Checkout>(method: "ec.start") | ||
| public static let totalsChange = NotificationDescriptor<Checkout>(method: "ec.totals.change") |
There was a problem hiding this comment.
Verify all of the events here look as expected.
The window.open delegation will be handled in a follow up
| @Test func delegationsReturnsRegisteredDelegationStrings() { | ||
| let client = CheckoutProtocol.Client() | ||
| .on(CheckoutProtocol.instrumentsChangeRequest) { (_: Checkout) in | ||
| InstrumentsChangeResult( | ||
| checkout: InstrumentsChangeCheckout( | ||
| payment: InstrumentsChangePayment(instruments: nil, selectedInstrumentID: nil) | ||
| ) | ||
| ) | ||
| } | ||
| .on(CheckoutProtocol.credentialRequest) { (_: Checkout) in | ||
| CredentialResult( | ||
| checkout: CredentialCheckout( | ||
| payment: CredentialPayment(instruments: nil) | ||
| ) | ||
| ) | ||
| } | ||
|
|
||
| #expect(client.delegations.sorted() == ["payment.credential", "payment.instruments_change"]) | ||
| } | ||
|
|
||
| @Test func builderChainingCompiles() { | ||
| let client = CheckoutProtocol.Client() | ||
| .on(CheckoutProtocol.start) { (_: Checkout) in } | ||
| .on(CheckoutProtocol.complete) { (_: Checkout) in } | ||
| .on(CheckoutProtocol.credentialRequest) { (_: Checkout) in | ||
| CredentialResult( | ||
| checkout: CredentialCheckout( | ||
| payment: CredentialPayment(instruments: nil) | ||
| ) | ||
| ) | ||
| } | ||
|
|
||
| #expect(client.delegations.count == 1) | ||
| } |
There was a problem hiding this comment.
These are all based on unused delegations on an old version. Deleting so we can implement window.open fresh from 2026-04-08
CocoaPods silently drops source_files paths outside the spec dir, so
'../../protocol/languages/swift/...' globs were not bundled and 'pod
lib lint' failed with 6 'cannot find CheckoutProtocol in scope' errors.
Move the Swift protocol sources physically under
platforms/swift/Sources/ShopifyCheckoutProtocol and replace the SPM
location with a symlink so the SPM target path stays inside its
package root.
The earlier sed rename in generate_models.sh anchored on a trailing
space ('struct Binding ') but quicktype emits 'struct Binding:' with
no whitespace, so the rename never fired and the SwiftUI sample app
failed with 'Binding is ambiguous'. Switch to BSD word-boundary
anchors so all identifier sites get rewritten, and regenerate
Models.swift.
Keep one copy of the Swift protocol sources under protocol/languages/swift/Sources/ShopifyCheckoutProtocol (their conceptual home, alongside the schemas and other language ports) and expose them inside the podspec dir via a symlink at platforms/swift/Sources/ShopifyCheckoutProtocol. CocoaPods' source_files glob follows the symlink, so the Core subspec still compiles them. Point the generator OUTPUT back at the canonical path.
3bd0ec8 to
effab32
Compare
| if let response = CheckoutProtocol.acknowledgeReady(body) { | ||
| checkoutBridge.sendResponse(self, messageBody: response) |
There was a problem hiding this comment.
This is where the ec.ready response happens
| protocol MutableCopyable { | ||
| func copy(_ mutate: (inout Self) -> Void) -> Self | ||
| } | ||
|
|
||
| extension Copyable { | ||
| extension MutableCopyable { |
There was a problem hiding this comment.
Was running into conflicts with other Copyable protocols in the repo. We can likely merge them all
… in place Reverts the file move from PR #65 so ShopifyCheckoutProtocol stays under protocol/languages/swift/, and instead moves ShopifyCheckoutKit.podspec from platforms/swift/ to the repository root. With the podspec at the root, both source trees are 'inside' the pod's working directory and can be globbed without using `..` paths: core.source_files = [ 'platforms/swift/Sources/ShopifyCheckoutKit/**/*.swift', 'protocol/languages/swift/Sources/ShopifyCheckoutProtocol/**/*.swift', ] Other changes: * License path simplified from '../../LICENSE' to 'LICENSE'. * AcceleratedCheckouts subspec source/resource paths re-rooted similarly. * Updated docs that referenced the old podspec path (.github/CONTRIBUTING.md, .github/pull_request_template.md). * Restored protocol/languages/swift/{Package.swift,README.md,.gitignore}. * Root Package.swift target paths point back at protocol/languages/swift. * #if !COCOAPODS guards in ShopifyCheckoutKit are kept (under CocoaPods both targets compile into one module, so the import would be unresolvable). RESULT: works. bundle exec pod lib lint ShopifyCheckoutKit.podspec --allow-warnings -> ShopifyCheckoutKit passed validation. Both subspecs (Core and AcceleratedCheckouts) build cleanly. The only diagnostics are the pre-existing JSONAny Sendable warnings in the generated Models.swift, identical to PR #65's baseline. Lint must be invoked from the repo root, e.g.: BUNDLE_GEMFILE=platforms/swift/Gemfile bundle exec pod lib lint \ ShopifyCheckoutKit.podspec --allow-warnings Trade-offs vs PR #65: + No duplicated source tree; protocol files live in one place. + No #if !COCOAPODS source-import guards needed beyond what PR #65 already added (kept for safety). - Podspec lives at the repo root, slightly unusual for a multi-platform monorepo. CONTRIBUTING.md / PR template updated to reflect the new path. - The Gemfile remains under platforms/swift/, so contributors need to set BUNDLE_GEMFILE when running pod commands from the root (or we move the Gemfile too in a follow-up).
…he kit Reverts the file move from PR #65 so ShopifyCheckoutProtocol stays under protocol/languages/swift/, restores its standalone Package.swift, and adds a new sibling cocoapod: protocol/languages/swift/ShopifyCheckoutProtocol.podspec ShopifyCheckoutKit.podspec then declares a regular pod dependency: core.dependency 'ShopifyCheckoutProtocol', "= #{s.version}" This mirrors the SwiftPM target split exactly: in both worlds (SwiftPM and CocoaPods) ShopifyCheckoutKit is a separate module that imports ShopifyCheckoutProtocol, so the `#if !COCOAPODS` shims that PR #65 added around `import ShopifyCheckoutProtocol` can be removed (done here in CheckoutViewController.swift, CheckoutWebView.swift, ShopifyCheckoutKit.swift). RESULT: works. # Lint the protocol pod first cd protocol/languages/swift BUNDLE_GEMFILE=../../../platforms/swift/Gemfile bundle exec pod lib lint \ ShopifyCheckoutProtocol.podspec --allow-warnings -> ShopifyCheckoutProtocol passed validation. # Then the kit pod, told where to find the local protocol pod cd platforms/swift BUNDLE_GEMFILE=Gemfile bundle exec pod lib lint ShopifyCheckoutKit.podspec \ --allow-warnings \ --include-podspecs=../../protocol/languages/swift/ShopifyCheckoutProtocol.podspec -> ShopifyCheckoutKit passed validation. Both Core and AcceleratedCheckouts subspecs build cleanly. Same JSONAny Sendable warnings as the baseline. Trade-offs vs PR #65: + Single source of truth: protocol files live in protocol/languages/swift, reachable by Swift consumers (SwiftPM standalone Package, the umbrella Package, CocoaPods, and Android via the protocol/ scripts). + No source-import #if shims; the module exists in both worlds. + ShopifyCheckoutProtocol becomes independently consumable by other Swift apps that want UCP types without pulling in the WebView kit. - Two pods to publish and version. Release flow needs to push ShopifyCheckoutProtocol to trunk before ShopifyCheckoutKit (and they must share s.version, which is enforced via `= #{s.version}` in the dependency declaration). - CONTRIBUTING.md release docs need a follow-up note about pushing both podspecs (not done in this commit; intentionally left for a follow-up once we settle on the approach). Note: pod lib lint of ShopifyCheckoutKit requires --include-podspecs because the protocol pod has not been published to trunk yet. Once published, that flag is no longer needed.
| } | ||
| }, | ||
| { | ||
| "identity" : "viewinspector", |
There was a problem hiding this comment.
was the intentional?
What changes are you making?
Implements UCP bridge for 2026-04-08 in Swift kit + sample app.
Important
?brandingparam. Usesec_color_schemefor nowShopifyCheckoutProtocolis packaged in theShopifyCheckoutKitcocoapod.window.opendelegation and be handled in a fast fallow.Checklist
Before you merge
Releasing a new Swift version?
platforms/swift/ShopifyCheckoutKit.podspecplatforms/swift/Sources/ShopifyCheckoutKit/ShopifyCheckoutKit.swiftplatforms/swift/CHANGELOG.mdplatforms/swift/README.md(major version only)Releasing a new Android version?
versionNameinplatforms/android/lib/build.gradleplatforms/android/CHANGELOG.mdplatforms/android/README.md