Skip to content

Make CheckoutKit configuration configure-only#85

Open
kieran-osgood-shopify wants to merge 1 commit into
kieran-osgood/swift6/mainactor-checkoutkit-uifrom
kieran-osgood/swift6/configure-only-checkoutkit-state
Open

Make CheckoutKit configuration configure-only#85
kieran-osgood-shopify wants to merge 1 commit into
kieran-osgood/swift6/mainactor-checkoutkit-uifrom
kieran-osgood/swift6/configure-only-checkoutkit-state

Conversation

@kieran-osgood-shopify

@kieran-osgood-shopify kieran-osgood-shopify commented May 13, 2026

Copy link
Copy Markdown
Contributor

Problem

Swift 6 is stricter about global/shared mutable state. In Swift 6 language mode, a mutable global like this becomes a concurrency-safety problem:

public var configuration = Configuration()

The compiler treats this as non-isolated shared mutable state: any caller in the process can read or write it, and Swift has no guarantee that those accesses are serialized.

The kind of error we are working toward eliminating is:

  var 'configuration' is not concurrency-safe because it is nonisolated global shared mutable state

This matters for ShopifyCheckoutKit.configuration because it is public process-wide configuration, and it currently also drives side effects like updating OSLogger.shared.logLevel.

Options considered

I considered both making configuration @MainActor or wrapping the configuration inside an actor
Both of these result in suboptimal results, actor would make all reads async/await, @MainActor would result in all reads needing to be MainActor isolated event for background tasks.
This is not ideal for our library code, because reading log levels or constructing user agents, which should be sync and should not cross to the main actor, all then rely on tasks and async/await, it would complicate library code significantly with workarounds for sync to async

What

The "synchronous synchronization" option is an NSLock or Semaphore
Its a bit manual and can result in deadlocks, but essentially we wrap up reading/writing to this value behind an explicit lock.

For this binary single access mutual exclusion NSLock / DispatchSemaphore perform the same, but NSLock ships with a helper withLock to guarantee release around a closure (easy enough to add to semaphore, but no actual benefit).


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 platforms/swift/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.

kieran-osgood-shopify commented May 13, 2026

Copy link
Copy Markdown
Contributor Author

Warning

This pull request is not mergeable via GitHub because a downstack PR is open. Once all requirements are satisfied, merge this PR as a stack on Graphite.
Learn more

This stack of pull requests is managed by Graphite. Learn more about stacking.

@github-actions

github-actions Bot commented Jun 10, 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)

@kieran-osgood-shopify kieran-osgood-shopify force-pushed the kieran-osgood/swift6/mainactor-checkoutkit-ui branch from 82606f0 to cd2ef3a Compare June 11, 2026 08:54
@kieran-osgood-shopify kieran-osgood-shopify force-pushed the kieran-osgood/swift6/configure-only-checkoutkit-state branch 3 times, most recently from 0955280 to c7e8091 Compare June 11, 2026 10:01
@kieran-osgood-shopify kieran-osgood-shopify force-pushed the kieran-osgood/swift6/mainactor-checkoutkit-ui branch from cd2ef3a to e5d6371 Compare June 11, 2026 10:01
@kieran-osgood-shopify kieran-osgood-shopify force-pushed the kieran-osgood/swift6/configure-only-checkoutkit-state branch 2 times, most recently from 945d4b6 to fe87622 Compare June 11, 2026 10:32
@kieran-osgood-shopify kieran-osgood-shopify force-pushed the kieran-osgood/swift6/mainactor-checkoutkit-ui branch from 1d19f91 to 87179cb Compare June 11, 2026 10:32
@kieran-osgood-shopify kieran-osgood-shopify force-pushed the kieran-osgood/swift6/configure-only-checkoutkit-state branch from fe87622 to 2fccbc2 Compare June 11, 2026 12:06
@kieran-osgood-shopify kieran-osgood-shopify force-pushed the kieran-osgood/swift6/configure-only-checkoutkit-state branch from 2fccbc2 to 63e7604 Compare June 11, 2026 13:08
@kieran-osgood-shopify kieran-osgood-shopify marked this pull request as ready for review June 11, 2026 14:31
@kieran-osgood-shopify kieran-osgood-shopify requested a review from a team as a code owner June 11, 2026 14:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

#gsd:50662 Rebase Checkout Kit on UCP

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant