Repository navigation
Conversation
markmur
left a comment
There was a problem hiding this comment.
Three implementation notes for reviewers.
| } catch (IOException e) { | ||
| Log.e(TAG, "Error emitting link click event", e); | ||
| } | ||
| return linkAction; |
There was a problem hiding this comment.
The native SDK needs an immediate link decision, so linkAction is chosen before presentation. onLinkClick is an asynchronous notification; returning a value from JS cannot change the native action.
| return; | ||
| } | ||
| case 'dismiss': | ||
| options.onTerminal?.(); |
There was a problem hiding this comment.
Completion keeps the subscription alive while the confirmation page remains visible. Dismissal and failure clean up before invoking app code, allowing those callbacks to safely present another checkout.
| } | ||
|
|
||
| export function decodeCheckout(value: unknown): Checkout { | ||
| return decodeCheckoutSnapshot(value) as unknown as Checkout; |
There was a problem hiding this comment.
Kit snapshots omit protocol metadata but still need schema-aware decoding. This converts known fields such as line_items to lineItems while preserving arbitrary extension keys and values.
6c54c36 to
5a1262b
Compare
Bundle Size Budgets
Bundle and package sizeWeb bundle sizes cover shipped runtime JavaScript. Package sizes cover the full published archive, including any source maps, declarations, and documentation it contains.
React Native package files (uncompressed)These are uncompressed file sizes; they do not sum to the compressed package size above.
How sizes are measuredMeasured from the PR base SHA and PR head SHA. Web bundle rows sum shipped |
Bitrise buildsInstall this buildOpen Tophat, select your target device, then click Install. Links open on the Mac running Tophat.
Checkout Kit E2E results
|
1ea9ad7 to
cb7bb33
Compare
cb7bb33 to
eeae337
Compare
tiagocandido
left a comment
There was a problem hiding this comment.
iOS E2E is failing on all four React Native flows (launch, present/close, guest, buyer identity), while Android passes. Do you know if that is related to this change?
| ): void { | ||
| /** Presents checkout with lifecycle callbacks. */ | ||
| public present(checkoutUrl: string, callbacks?: PresentCallbacks): void { | ||
| this.releaseDispatchSubscription(); |
There was a problem hiding this comment.
Is presenting from two ShopifyCheckout instances supported? With a.present() then b.present(), only b's old subscription is removed. a's listener never sees a dismiss after that, so it stays alive forever.
There was a problem hiding this comment.
Fixed in 7369c47. The latest present() owns the single native sheet across instances and removes the previous subscription. A regression test also verifies that tearing down the old instance cannot remove the new owner’s callbacks.
There was a problem hiding this comment.
The fix for this seems off to me
In the Android sdk we noop subsequent presents if a checkout is presented
val alreadyPresented = livePresentations[context]?.takeIf { it.isShowing() }
if (alreadyPresented != null) log.w(..., "A checkout is already presented, ignoring this presentation.")
return alreadyPresented?.handle ?: startPresentation(...)UIKit has this built in effectively so we dont have a direct guard, but UIKit prevents multiple modally presented views on a single vc
Seems like RN goes around this slightly with the way it searches for a vc
I feel like we should add a similar guard to the swift sdk as android and remove this timeout/polling behaviour
There was a problem hiding this comment.
i think if we went down that route, and the second present is rejected, we'd be able to remove all the requestId wiring too
There was a problem hiding this comment.
Addressed in this update:
- Added the Swift presentation guard in Ignore duplicate Swift checkout presentations #942.
- Duplicate RN calls preserve the original checkout and callbacks, including across instances.
- Removed polling/timeouts and presentation request IDs. Attempts while closing are ignored; an internal bridge acknowledgement releases the rejected JS subscription without firing consumer callbacks.
- Pending geolocation responses are cancelled on close or teardown, so an old response cannot affect a later checkout.
The RN guards work with the published SDK pins. onDismiss/onFail timing is unchanged, so a present() from those callbacks may be ignored while the sheet is closing. Regression tests cover both platforms, late geolocation responses, and subsequent explicit presentations.
7369c47 to
9e0ab13
Compare
75ebf71 to
330756f
Compare
330756f to
462c7c4
Compare
441abf4 to
9719c85
Compare
9719c85 to
06fd61e
Compare
06fd61e to
bf5a884
Compare
Replace raw protocol callbacks with
onStart,onUpdate,onComplete,onFail, andonDismissfor checkout sheets and accelerated buttons. Events expose Kit checkout snapshots through the shared schema-aware decoder, and completion keeps observations alive until dismissal or failure.Ignore duplicate presentations across
ShopifyCheckoutinstances, preserving the active checkout and its callbacks. Attempts during closing are also ignored; the bridge acknowledges rejected attempts so JS can release their subscriptions without firing consumer callbacks. There is no polling or dismissal timeout.Cancel pending geolocation responses on dismiss, failure, or teardown, and remove presentation request IDs. Teardown clears consumer callbacks while internal tracking remains until the native session ends. The sample clears completed carts on dismissal or failure.
Pin Swift to 4.0.0-alpha.8 and Android to 4.0.0-alpha.8, update published CocoaPods lockfiles, remove the public protocol handler API, and document the migration. The wrapper guards work with these published SDKs. Link opening uses native defaults; explicit link policy is added in the next PR.
Stack