@@ -30,33 +30,34 @@ import UIKit
3030
3131// MARK: - AcceleratedCheckout Components
3232
33- @available ( iOS 17 . 0 , * )
33+ @available ( iOS 16 . 0 , * )
3434class AcceleratedCheckoutConfiguration {
3535 static let shared = AcceleratedCheckoutConfiguration ( )
3636 var configuration : ShopifyAcceleratedCheckouts . Configuration ?
37+ var applePayConfiguration : ShopifyAcceleratedCheckouts . ApplePayConfiguration ?
3738 var wallets : [ Wallet ] = [ Wallet . shopPay, Wallet . applePay]
3839
39- private init ( ) {
40- setupApplePay ( )
40+ var available : Bool {
41+ if #available( iOS 16 . 0 , * ) {
42+ return configuration != nil
43+ } else {
44+ return false
45+ }
4146 }
4247
43- private func setupApplePay( ) {
44- // Configure Apple Pay environment
45- // This should be called during app initialization
46- if let merchantID = Bundle . main. object ( forInfoDictionaryKey: " ApplePayMerchantID " ) as? String {
47- // Apple Pay is configured via merchant ID in Info.plist
48- // The actual Apple Pay setup is handled by the ShopifyAcceleratedCheckouts framework
49- print ( " ✅ Apple Pay configured with Merchant ID: \( merchantID) " )
48+ var applePayAvailable : Bool {
49+ if #available( iOS 16 . 0 , * ) {
50+ return applePayConfiguration != nil
5051 } else {
51- print ( " ⚠️ Apple Pay Merchant ID not found in Info.plist. Add 'ApplePayMerchantID' key to enable Apple Pay. " )
52+ return false
5253 }
5354 }
5455}
5556
5657@objc ( RCTAcceleratedCheckoutButtonsManager)
5758class RCTAcceleratedCheckoutButtonsManager : RCTViewManager {
5859 override func view( ) -> UIView ! {
59- if #available( iOS 17 . 0 , * ) {
60+ if #available( iOS 16 . 0 , * ) {
6061 return RCTAcceleratedCheckoutButtonsView ( )
6162 }
6263
@@ -73,12 +74,16 @@ class RCTAcceleratedCheckoutButtonsManager: RCTViewManager {
7374 }
7475}
7576
76- @available ( iOS 17 . 0 , * )
77+ @available ( iOS 16 . 0 , * )
7778class RCTAcceleratedCheckoutButtonsView : UIView {
7879 private var hostingController : UIHostingController < AnyView > ?
7980 private var configuration : ShopifyAcceleratedCheckouts . Configuration ?
8081 private weak var parentViewController : UIViewController ?
8182
83+ @objc var onSizeChange : RCTDirectEventBlock ?
84+
85+ // MARK: - Props
86+
8287 @objc var cartId : String ? {
8388 didSet {
8489 updateView ( )
@@ -104,6 +109,16 @@ class RCTAcceleratedCheckoutButtonsView: UIView {
104109 }
105110
106111 @objc var wallets : [ String ] ? {
112+ didSet {
113+ let height = calculateRequiredHeight ( )
114+ onSizeChange ? ( [ " height " : height] )
115+ invalidateIntrinsicContentSize ( )
116+ setNeedsLayout ( )
117+ updateView ( )
118+ }
119+ }
120+
121+ @objc var applePayLabel : String ? {
107122 didSet {
108123 updateView ( )
109124 }
@@ -128,6 +143,16 @@ class RCTAcceleratedCheckoutButtonsView: UIView {
128143 setupView ( )
129144 }
130145
146+ override func layoutSubviews( ) {
147+ super. layoutSubviews ( )
148+ hostingController? . view. frame = bounds
149+ }
150+
151+ override var intrinsicContentSize : CGSize {
152+ let height = calculateRequiredHeight ( )
153+ return CGSize ( width: UIView . noIntrinsicMetric, height: height)
154+ }
155+
131156 private func setupView( ) {
132157 // Configuration will be set via a static method from the main module
133158 configuration = AcceleratedCheckoutConfiguration . shared. configuration
@@ -146,6 +171,20 @@ class RCTAcceleratedCheckoutButtonsView: UIView {
146171 name: Notification . Name ( " AcceleratedCheckoutConfigurationUpdated " ) ,
147172 object: nil
148173 )
174+
175+ NotificationCenter . default. addObserver (
176+ self ,
177+ selector: #selector( configurationUpdated) ,
178+ name: Notification . Name ( " CheckoutKitConfigurationUpdated " ) ,
179+ object: nil
180+ )
181+
182+ // Fire initial size change event
183+ DispatchQueue . main. async { [ weak self] in
184+ guard let self else { return }
185+ let height = self . calculateRequiredHeight ( )
186+ self . onSizeChange ? ( [ " height " : height] )
187+ }
149188 }
150189
151190 private func findViewController( ) -> UIViewController ? {
@@ -167,8 +206,9 @@ class RCTAcceleratedCheckoutButtonsView: UIView {
167206 private func createCartButtons(
168207 cartId: String ,
169208 wallets: [ Wallet ] ,
209+ applePayLabel: PayWithApplePayButtonLabel ? ,
170210 config: ShopifyAcceleratedCheckouts . Configuration ,
171- applePayConfig: ShopifyAcceleratedCheckouts . ApplePayConfiguration
211+ applePayConfig: ShopifyAcceleratedCheckouts . ApplePayConfiguration ?
172212 ) -> some View {
173213 AcceleratedCheckoutButtons ( cartID: cartId)
174214 . wallets ( wallets)
@@ -190,17 +230,19 @@ class RCTAcceleratedCheckoutButtonsView: UIView {
190230 . onWebPixelEvent { [ weak self] event in
191231 self ? . handleWebPixelEvent ( event)
192232 }
233+ . applePayLabel ( applePayLabel ?? . plain)
193234 . cornerRadius ( CGFloat ( cornerRadius. doubleValue) )
194- . environment ( config)
195- . environment ( applePayConfig)
235+ . environmentObject ( config)
236+ . conditionalEnvironmentObject ( applePayConfig)
196237 }
197238
198239 private func createVariantButtons(
199240 variantId: String ,
200241 quantity: Int ,
201242 wallets: [ Wallet ] ,
243+ applePayLabel: PayWithApplePayButtonLabel ? ,
202244 config: ShopifyAcceleratedCheckouts . Configuration ,
203- applePayConfig: ShopifyAcceleratedCheckouts . ApplePayConfiguration
245+ applePayConfig: ShopifyAcceleratedCheckouts . ApplePayConfiguration ?
204246 ) -> some View {
205247 AcceleratedCheckoutButtons ( variantID: variantId, quantity: quantity)
206248 . wallets ( wallets)
@@ -222,9 +264,10 @@ class RCTAcceleratedCheckoutButtonsView: UIView {
222264 . onWebPixelEvent { [ weak self] event in
223265 self ? . handleWebPixelEvent ( event)
224266 }
267+ . applePayLabel ( applePayLabel ?? . plain)
225268 . cornerRadius ( CGFloat ( cornerRadius. doubleValue) )
226- . environment ( config)
227- . environment ( applePayConfig)
269+ . environmentObject ( config)
270+ . conditionalEnvironmentObject ( applePayConfig)
228271 }
229272
230273 private func updateView( ) {
@@ -240,29 +283,24 @@ class RCTAcceleratedCheckoutButtonsView: UIView {
240283 // Use wallets from props, or fallback to default
241284 let shopifyWallets = wallets. map ( convertToShopifyWallets) ?? AcceleratedCheckoutConfiguration . shared. wallets
242285
243- // Create Apple Pay configuration
244- let applePayConfig = ShopifyAcceleratedCheckouts . ApplePayConfiguration (
245- merchantIdentifier: Bundle . main. object (
246- forInfoDictionaryKey: " ApplePayMerchantID " ) as? String ?? " merchant.com.shopify " ,
247- contactFields: [ . email, . phone]
248- )
249-
250286 let swiftUIView : AnyView
251287
252288 if let cartId {
253289 swiftUIView = AnyView ( createCartButtons (
254290 cartId: cartId,
255291 wallets: shopifyWallets,
292+ applePayLabel: PayWithApplePayButtonLabel . from ( applePayLabel) ,
256293 config: config,
257- applePayConfig: applePayConfig
294+ applePayConfig: AcceleratedCheckoutConfiguration . shared . applePayConfiguration
258295 ) )
259296 } else if let variantId {
260297 swiftUIView = AnyView ( createVariantButtons (
261298 variantId: variantId,
262299 quantity: quantity. intValue,
263300 wallets: shopifyWallets,
301+ applePayLabel: PayWithApplePayButtonLabel . from ( applePayLabel) ,
264302 config: config,
265- applePayConfig: applePayConfig
303+ applePayConfig: AcceleratedCheckoutConfiguration . shared . applePayConfiguration
266304 ) )
267305 } else {
268306 // Empty view if no cart or variant ID is provided
@@ -331,13 +369,13 @@ class RCTAcceleratedCheckoutButtonsView: UIView {
331369 onClickLink ? ( ShopifyEventSerialization . serialize ( clickEvent: url) )
332370 }
333371
334- override func layoutSubviews( ) {
335- super. layoutSubviews ( )
336- hostingController? . view. frame = bounds
337- }
372+ private func calculateRequiredHeight( ) -> CGFloat {
373+ let shopifyWallets = wallets. map ( convertToShopifyWallets) ?? AcceleratedCheckoutConfiguration . shared. wallets
374+ let numberOfWallets = max ( shopifyWallets. count, 1 )
375+ let buttonHeight : CGFloat = 48
376+ let gapHeight : CGFloat = 8
377+ let totalHeight = ( CGFloat ( numberOfWallets) * buttonHeight) + ( CGFloat ( numberOfWallets - 1 ) * gapHeight)
338378
339- override var intrinsicContentSize : CGSize {
340- // Provide a default size for the button
341- return CGSize ( width: UIView . noIntrinsicMetric, height: 50 )
379+ return totalHeight
342380 }
343381}
0 commit comments