Skip to content

[Swift] Add preload state observability - #445

Merged
markmur merged 5 commits into
mainfrom
preloading-impl
Jul 16, 2026
Merged

[Swift] Add preload state observability#445
markmur merged 5 commits into
mainfrom
preloading-impl

Conversation

@markmur

@markmur markmur commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

Adds observable lifecycle state to preloaded checkouts on iOS. preload(checkout:) returns a retained CheckoutPreload handle that exposes the current state and emits transitions — .loading → .ready → .expired, .failed(reason:) for HTTP, navigation, and keep-alive failures, and .idle on manual invalidation. State is driven from a single transition choke point in the preload cache and broadcast to a weak observer, so consumers can drive spinners or fall back to a fresh preload when a warm entry lapses.

CheckoutPreload is an ObservableObject, so you can observe it with a closure, Combine's $state, or directly in SwiftUI.

Observe with a closure

// Retain the handle for as long as you want to observe.
checkoutPreload = ShopifyCheckoutKit.preload(checkout: url)
checkoutPreload?.onStateChange = { state in
    switch state {
    case .loading:
        break
    case .ready:
        presentCheckout(url)
    case .expired:
        // warm entry is gone — kick off a fresh preload
        break
    case .failed(let reason):
        print("preload failed: \(reason)")
    case .idle:
        break
    }
}

onStateChange fires immediately with the current state on assignment, then on every transition.

Read the current state synchronously

let checkoutPreload = ShopifyCheckoutKit.preload(checkout: url)
// Synchronously check the current state of the cache
if checkoutPreload.state == .ready {
    // do something
}

Observe in SwiftUI

struct PreloadStatus: View {
    @ObservedObject var preload: CheckoutPreload

    var body: some View {
        switch preload.state {
        case .ready:
            Text("Ready")
        case .loading:
            ProgressView()
        default:
            Text("Not ready")
        }
    }
}

Fire-and-forget warming

// @discardableResult — warm the cache without retaining a handle to observe.
ShopifyCheckoutKit.preload(checkout: url)

@markmur
markmur requested a review from a team as a code owner July 13, 2026 19:38
@github-actions github-actions Bot added the #gsd:50662 Rebase Checkout Kit on UCP label Jul 13, 2026

markmur commented Jul 13, 2026

Copy link
Copy Markdown
Contributor Author

@github-actions

github-actions Bot commented Jul 13, 2026

Copy link
Copy Markdown

React Native — Coverage Report

Lines Statements Branches Functions
Coverage: 92%
91.85% (327/356) 87.98% (183/208) 100% (86/86)

Comment thread platforms/swift/Sources/ShopifyCheckoutKit/CheckoutWebView.swift Outdated
Comment thread platforms/swift/Sources/ShopifyCheckoutKit/CheckoutWebView.swift
Comment thread platforms/swift/Sources/ShopifyCheckoutKit/CheckoutWebView.swift Outdated
Comment thread platforms/swift/Sources/ShopifyCheckoutKit/CheckoutWebView.swift Outdated
Comment thread platforms/swift/Sources/ShopifyCheckoutKit/ShopifyCheckoutKit.swift Outdated
@markmur
markmur force-pushed the preloading-impl branch 5 times, most recently from 71863e5 to 2557311 Compare July 15, 2026 16:01
Comment thread platforms/swift/Sources/ShopifyCheckoutKit/CheckoutWebView.swift
Comment thread platforms/swift/Sources/ShopifyCheckoutKit/CheckoutWebView.swift
Comment thread platforms/swift/Sources/ShopifyCheckoutKit/CheckoutWebView.swift Outdated
Comment thread platforms/swift/Sources/ShopifyCheckoutKit/CheckoutWebView.swift Outdated
Comment thread platforms/swift/Sources/ShopifyCheckoutKit/ShopifyCheckoutKit.swift
@bitrise

bitrise Bot commented Jul 16, 2026

Copy link
Copy Markdown

Install this build

Open Tophat, select your target device, then click Install. Links open on the Mac running Tophat.

SDK Install
React Native Install with Tophat
Swift Install with Tophat
Kotlin Install with Tophat

Checkout Kit E2E results

Status Suite Target Platform OS version tag Device
tests/shared/launch-smoke.yaml swift ios latest iPhone 15
iOS 27 Beta

markmur added 2 commits July 16, 2026 16:09
- Add terminate(with:disconnect:) to unify invalidate + state transition
- Emit terminal state (.expired/.idle) on cache miss/stale in view(for:)
- Ignore cancelled provisional navigations (redirects/policy cancels)
- Clear cache before notifying so re-entrant preload survives expiry
Comment thread platforms/swift/Sources/ShopifyCheckoutKit/CheckoutWebView.swift Outdated
@markmur
markmur merged commit 84022d1 into main Jul 16, 2026
35 checks passed
@markmur
markmur deleted the preloading-impl branch July 16, 2026 19:40
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.

3 participants