Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@
},
"Adding..." : {

},
"Apple Pay" : {

},
"Authentication" : {
"comment" : "A section header in the settings view.",
Expand Down Expand Up @@ -71,6 +74,9 @@
},
"Clear logs" : {

},
"Configures the visual style of the Apple Pay button." : {

},
"Events" : {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,11 @@ class CartViewController: UIViewController, UITableViewDelegate, UITableViewData
private func setupAcceleratedCheckoutButtons() {
guard let cartId = CartManager.shared.cart?.id else { return }

let savedStyle = UserDefaults.standard.string(forKey: AppStorageKeys.applePayStyle.rawValue)
.flatMap(ApplePayStyleOption.init(rawValue:)) ?? .automatic

let acceleratedCheckoutButtonsView = AcceleratedCheckoutButtons(cartID: cartId)
.applePayStyle(savedStyle.style)
.wallets([.shopPay, .applePay])
.cornerRadius(10)
.onComplete { _ in
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ struct CartView: View {
@ObservedObject var cartManager: CartManager = .shared
@ObservedObject var config: AppConfiguration = appConfiguration

@AppStorage(AppStorageKeys.applePayStyle.rawValue)
var applePayStyle: ApplePayStyleOption = .automatic

var body: some View {
if let lines = cartManager.cart?.lines.nodes {
ZStack(alignment: .bottom) {
Expand All @@ -51,6 +54,7 @@ struct CartView: View {
VStack(spacing: DesignSystem.buttonSpacing) {
if let cartId = cartManager.cart?.id {
AcceleratedCheckoutButtons(cartID: cartId)
.applePayStyle(applePayStyle.style)
.wallets([.shopPay, .applePay])
.cornerRadius(DesignSystem.cornerRadius)
.onComplete { _ in
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ struct ProductView: View {
@State private var descriptionExpanded: Bool = false
@State private var addedToCart: Bool = false

@AppStorage(AppStorageKeys.applePayStyle.rawValue)
var applePayStyle: ApplePayStyleOption = .automatic

init(product: Product) {
_product = State(initialValue: product)
}
Expand Down Expand Up @@ -134,6 +137,7 @@ struct ProductView: View {

if variant.availableForSale {
AcceleratedCheckoutButtons(variantID: variant.id, quantity: 1)
.applePayStyle(applePayStyle.style)
.wallets([.applePay])
.cornerRadius(DesignSystem.cornerRadius)
.onFail { error in
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
*/

import Combine
import PassKit
@preconcurrency import ShopifyAcceleratedCheckouts
@preconcurrency import ShopifyCheckoutSheetKit
import SwiftUI
Expand All @@ -30,6 +31,7 @@ enum AppStorageKeys: String {
case acceleratedCheckoutsLogLevel
case checkoutSheetKitLogLevel
case buyerIdentityMode
case applePayStyle
}

struct SettingsView: View {
Expand All @@ -51,6 +53,9 @@ struct SettingsView: View {
}
}

@AppStorage(AppStorageKeys.applePayStyle.rawValue)
var applePayStyle: ApplePayStyleOption = .automatic

@State private var preloadingEnabled = ShopifyCheckoutSheetKit.configuration.preloading.enabled
@State private var logs: [String?] = LogReader.shared.readLogs() ?? []
@State private var selectedColorScheme = ShopifyCheckoutSheetKit.configuration.colorScheme
Expand Down Expand Up @@ -120,6 +125,26 @@ struct SettingsView: View {
}
}

Section(
header: Text("Apple Pay"),
footer: Text("Configures the visual style of the Apple Pay button.")
) {
ForEach(ApplePayStyleOption.allCases, id: \.self) { option in
HStack {
Text(option.title)
Spacer()
if option == applePayStyle {
Text("\u{2713}")
}
}
.background(Color.clear)
.contentShape(Rectangle())
.onTapGesture {
applePayStyle = option
}
}
}

Section(header: Text("Logging")) {
Picker(
"Accelerated Checkouts",
Expand Down Expand Up @@ -307,6 +332,31 @@ extension Configuration.ColorScheme {
}
}

enum ApplePayStyleOption: String, CaseIterable {
case automatic
case black
case white
case whiteOutline

var title: String {
switch self {
case .automatic: return "Automatic"
case .black: return "Black"
case .white: return "White"
case .whiteOutline: return "White Outline"
}
}

var style: PayWithApplePayButtonStyle {
switch self {
case .automatic: return .automatic
case .black: return .black
case .white: return .white
case .whiteOutline: return .whiteOutline
}
}
}

#Preview {
SettingsView()
}
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ struct ButtonSet: View {
variantID: productVariant.id,
quantity: firstVariantQuantity
)
.applePayStyle(.whiteOutline)
.applePayLabel(.buy)
.cornerRadius(24)
.wallets([.applePay, .shopPay])
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ public struct AcceleratedCheckoutButtons: View {

/// The Apple Pay button label style
private var applePayLabel: PayWithApplePayButtonLabel = .plain
private var applePayStyle: PayWithApplePayButtonStyle = .automatic

@State private var shopSettings: ShopSettings?
@State private var currentRenderState: RenderState = .loading {
Expand Down Expand Up @@ -93,7 +94,8 @@ public struct AcceleratedCheckoutButtons: View {
ApplePayButton(
identifier: identifier,
eventHandlers: eventHandlers,
cornerRadius: cornerRadius
cornerRadius: cornerRadius,
style: applePayStyle
)
.label(applePayLabel)
case .shopPay:
Expand Down Expand Up @@ -137,6 +139,12 @@ public struct AcceleratedCheckoutButtons: View {

@available(iOS 16.0, *)
extension AcceleratedCheckoutButtons {
public func applePayStyle(_ color: PayWithApplePayButtonStyle) -> AcceleratedCheckoutButtons {
var view = self
view.applePayStyle = color
return view
}

public func applePayLabel(_ label: PayWithApplePayButtonLabel) -> AcceleratedCheckoutButtons {
var view = self
view.applePayLabel = label
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,17 +49,22 @@ struct ApplePayButton: View {
/// The Apple Pay button label style
private var label: PayWithApplePayButtonLabel = .plain

/// The Apple Pay button style
private var style: PayWithApplePayButtonStyle = .automatic

/// The corner radius for the button
private let cornerRadius: CGFloat?

public init(
init(
identifier: CheckoutIdentifier,
eventHandlers: EventHandlers = EventHandlers(),
cornerRadius: CGFloat?
cornerRadius: CGFloat?,
style: PayWithApplePayButtonStyle = .automatic
) {
self.identifier = identifier.parse()
self.eventHandlers = eventHandlers
self.cornerRadius = cornerRadius
self.style = style
}

var body: some View {
Expand All @@ -70,6 +75,7 @@ struct ApplePayButton: View {
Internal_ApplePayButton(
identifier: identifier,
label: label,
style: style,
configuration: ApplePayConfigurationWrapper(
common: configuration,
applePay: applePayConfiguration,
Expand All @@ -81,7 +87,13 @@ struct ApplePayButton: View {
}
}

public func label(_ label: PayWithApplePayButtonLabel) -> some View {
func applePayStyle(_ style: PayWithApplePayButtonStyle) -> some View {
var view = self
view.style = style
return view
}

func label(_ label: PayWithApplePayButtonLabel) -> some View {
var view = self
view.label = label
return view
Expand All @@ -93,24 +105,15 @@ struct ApplePayButton: View {
@available(iOS 16.0, *)
@available(macOS, unavailable)
struct Internal_ApplePayButton: View {
/// The Apple Pay button label style
private var label: PayWithApplePayButtonLabel = .plain

/// The view controller for the Apple Pay button
private var controller: ApplePayViewController

/// The corner radius for the button
private let label: PayWithApplePayButtonLabel
private let style: PayWithApplePayButtonStyle
private let controller: ApplePayViewController
private let cornerRadius: CGFloat?

/// Initializes an Apple Pay button
/// - Parameters:
/// - identifier: The identifier to use for checkout
/// - label: The label to display on the Apple Pay button
/// - configuration: The configuration for Apple Pay
/// - eventHandlers: The event handlers for checkout events (defaults to EventHandlers())
init(
identifier: CheckoutIdentifier,
label: PayWithApplePayButtonLabel,
style: PayWithApplePayButtonStyle,
configuration: ApplePayConfigurationWrapper,
eventHandlers: EventHandlers = EventHandlers(),
cornerRadius: CGFloat?
Expand All @@ -120,6 +123,7 @@ struct Internal_ApplePayButton: View {
configuration: configuration
)
self.label = label
self.style = style
self.cornerRadius = cornerRadius
controller.onCheckoutComplete = eventHandlers.checkoutDidComplete
controller.onCheckoutFail = eventHandlers.checkoutDidFail
Expand All @@ -130,15 +134,56 @@ struct Internal_ApplePayButton: View {
}

var body: some View {
PayWithApplePayButton(
label,
action: {
Task { await controller.onPress() }
},
fallback: {
Text("errors.applePay.unsupported".localizedString)
}
)
.walletButtonStyle(cornerRadius: cornerRadius)
if PKPaymentAuthorizationController.canMakePayments() {
ApplePayButtonRepresentable(
buttonType: label.pkPaymentButtonType,
buttonStyle: style.pkPaymentButtonStyle,
cornerRadius: cornerRadius ?? 8,
action: { Task { await controller.onPress() } }
)
.id(style.pkPaymentButtonStyle.rawValue)
.frame(height: 48)
} else {
Text("errors.applePay.unsupported".localizedString)
}
}
}

// MARK: - Type Conversions

@available(iOS 16.0, *)
extension PayWithApplePayButtonStyle {
var pkPaymentButtonStyle: PKPaymentButtonStyle {
switch self {
case .black: .black
case .white: .white
case .whiteOutline: .whiteOutline
case .automatic: .automatic
default: .automatic
}
}
}

@available(iOS 16.0, *)
extension PayWithApplePayButtonLabel {
var pkPaymentButtonType: PKPaymentButtonType {
switch self {
case .buy: .buy
case .setUp: .setUp
case .inStore: .inStore
case .donate: .donate
case .checkout: .checkout
case .book: .book
case .subscribe: .subscribe
case .reload: .reload
case .addMoney: .addMoney
case .topUp: .topUp
case .order: .order
case .rent: .rent
case .support: .support
case .contribute: .contribute
case .tip: .tip
default: .plain
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import PassKit
import SwiftUI
import UIKit

@available(iOS 16.0, *)
struct ApplePayButtonRepresentable: UIViewRepresentable {
typealias UIViewType = PKPaymentButton
typealias Coordinator = Void

let buttonType: PKPaymentButtonType
let buttonStyle: PKPaymentButtonStyle
let cornerRadius: CGFloat
let action: @Sendable () -> Void

func makeUIView(context _: Context) -> PKPaymentButton {
let button = PKPaymentButton(paymentButtonType: buttonType, paymentButtonStyle: buttonStyle)
button.cornerRadius = cornerRadius
button.addAction(UIAction { _ in action() }, for: .touchUpInside)
return button
}

func updateUIView(_ button: PKPaymentButton, context _: Context) {
button.cornerRadius = cornerRadius
}
}
Loading