[Swift] 4.0.0-alpha.4
Pre-releaseBreaking changes
New checkout failure case
Checkout now reports WebKit content-process termination as a terminal failure through checkoutDidFail(error:) or .onFail.
CheckoutErrorCode includes a new case. Exhaustive switches must handle it:
switch error.code {
case .networkError:
showRetry()
+case .webContentProcessTerminated:
+ showRetry()
case .sdkError:
showBrowserFallback()
// Other cases...
}Checkout Kit does not automatically reload after the process terminates. The buyer must explicitly retry or reopen checkout.
New preload failure case
PreloadState.FailureReason also includes a new case. Exhaustive switches over preload failures must be updated:
switch reason {
case .httpError(let statusCode):
recordHTTPFailure(statusCode)
case .navigationFailed:
recordNavigationFailure()
-case .keepAliveLost, .protocolError:
+case .keepAliveLost, .webContentProcessTerminated, .protocolError:
discardPreload()
}A terminated background WebView now transitions the preload to:
.failed(reason: .webContentProcessTerminated)This failure applies only to the preload. A subsequent checkout presentation can still load normally.
Additive changes
Incoming message origin validation
Checkout messages can now be restricted to explicitly trusted origins using allowedMessageOrigins:
ShopifyCheckoutKit.configure {
+ $0.allowedMessageOrigins = [
+ "https://checkout.example.com",
+ "https://*.example.com"
+ ]
}The loaded checkout origin and shop.app are always trusted. An empty list preserves the previous behavior and accepts messages from all origins.
Rejected messages can be observed with onMessageRejected:
ShopifyCheckoutKit.configure {
+ $0.onMessageRejected = { rejection in
+ logger.warning(
+ "Rejected message from \(rejection.origin): \(rejection.reason)"
+ )
+ }
}The MessageRejection payload is untrusted and should only be used for diagnostics.
Enumerate checkout error codes
CheckoutErrorCode now conforms to CaseIterable:
-public enum CheckoutErrorCode: String, Codable, Sendable {
+public enum CheckoutErrorCode: String, Codable, CaseIterable, Sendable {This allows applications and tests to enumerate every known error code:
for code in CheckoutErrorCode.allCases {
registerAnalyticsValue(code.rawValue)
}Behavior changes
WebKit content-process termination no longer fails silently
When WebKit terminates an active checkout's content process, Checkout Kit now reports .webContentProcessTerminated.
For a background preload, Checkout Kit evicts the cached WebView and reports:
.failed(reason: .webContentProcessTerminated)Checkout header layout changed
The checkout navigation bar now uses a transparent background, and checkout content extends behind the navigation bar:
-checkoutView.scrollView.contentInsetAdjustmentBehavior = .never
+checkoutView.scrollView.contentInsetAdjustmentBehavior = .automatic
-checkoutView.topAnchor.constraint(
- equalTo: view.safeAreaLayoutGuide.topAnchor
-)
+checkoutView.topAnchor.constraint(
+ equalTo: view.topAnchor
+)Apps that visually test or customize checkout presentation should verify their header, title, close button, and content positioning after upgrading.
What's Changed
- add multipass deprecation warning by @kiftio in #564
- Document checkout lifecycle errors by @kiftio in #538
- Handle WebView process termination by @kiftio in #539
- feat: incoming message origin validation for ios by @michaeljsXu in #476
- ci: cache Mint packages in the Swift test workflow by @kieran-osgood-shopify in #586
- [Swift]: conform CheckoutErrorCode to CaseIterable by @kieran-osgood-shopify in #571
- ci: extract Mint provisioning into a setup-mint composite action by @kieran-osgood-shopify in #591
- Readme discrepancies by @markmur in #526
- Add sample app test seams and run them in CI by @kieran-osgood-shopify in #553
- [Swift] Drop header background, anchor webview to top by @markmur in #615
- feat: setup nightly for testflight swift by @kieran-osgood-shopify in #605
- Release Swift 4.0.0-alpha.4 by @tiagocandido in #622
Full Changelog: 4.0.0-alpha.3...4.0.0-alpha.4