Skip to content

Commit 4a24a70

Browse files
committed
Initialize CardPresentPaymentService together with aggregate model
Implement connectedReaderPublisher in a way that subscription could be done without async call. This way initializer can be made sync as well.
1 parent f5ccde0 commit 4a24a70

File tree

3 files changed

+43
-57
lines changed

3 files changed

+43
-57
lines changed

WooCommerce/Classes/POS/Card Present Payments/CardPresentPaymentService.swift

Lines changed: 38 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,39 @@ import protocol Yosemite.StoresManager
1010
final class CardPresentPaymentService: CardPresentPaymentFacade {
1111
let paymentEventPublisher: AnyPublisher<CardPresentPaymentEvent, Never>
1212

13-
let readerConnectionStatusPublisher: AnyPublisher<CardPresentPaymentReaderConnectionStatus, Never>
14-
15-
private let connectedReaderPublisher: AnyPublisher<CardPresentPaymentCardReader?, Never>
13+
lazy var readerConnectionStatusPublisher: AnyPublisher<CardPresentPaymentReaderConnectionStatus, Never> = {
14+
connectedReaderPublisher
15+
.map({ reader -> CardPresentPaymentReaderConnectionStatus in
16+
guard let reader else {
17+
return .disconnected
18+
}
19+
return .connected(reader)
20+
})
21+
.merge(with: paymentAlertsPresenterAdaptor.readerConnectionStatusPublisher)
22+
.merge(with: readerConnectionStatusSubject)
23+
.receive(on: DispatchQueue.main)
24+
.eraseToAnyPublisher()
25+
}()
26+
27+
private let connectedReaderSubject = PassthroughSubject<CardPresentPaymentCardReader?, Never>()
28+
private lazy var connectedReaderPublisher: AnyPublisher<CardPresentPaymentCardReader?, Never> = {
29+
let action = CardPresentPaymentAction.publishCardReaderConnections { [weak self] cardReadersConnectionPublisher in
30+
guard let self else { return }
31+
cardReadersConnectionPublisher
32+
.map { readers -> CardPresentPaymentCardReader? in
33+
guard let reader = readers.first else {
34+
return nil
35+
}
36+
return CardPresentPaymentCardReader(name: reader.name ?? reader.id,
37+
batteryLevel: reader.batteryLevel)
38+
}
39+
.receive(on: DispatchQueue.main)
40+
.subscribe(self.connectedReaderSubject)
41+
.store(in: &self.subscriptions)
42+
}
43+
stores.dispatch(action)
44+
return connectedReaderSubject.eraseToAnyPublisher()
45+
}()
1646

1747
private let paymentEventSubject = PassthroughSubject<CardPresentPaymentEvent, Never>()
1848

@@ -33,8 +63,11 @@ final class CardPresentPaymentService: CardPresentPaymentFacade {
3363

3464
private var paymentTask: Task<CardPresentPaymentAdaptedCollectOrderPaymentResult, Error>?
3565

36-
@MainActor
37-
init(siteID: Int64, stores: StoresManager = ServiceLocator.stores, collectOrderPaymentAnalyticsTracker: CollectOrderPaymentAnalyticsTracking) async {
66+
private var subscriptions = Set<AnyCancellable>()
67+
68+
init(siteID: Int64,
69+
stores: StoresManager = ServiceLocator.stores,
70+
collectOrderPaymentAnalyticsTracker: CollectOrderPaymentAnalyticsTracking) {
3871
self.siteID = siteID
3972
let onboardingAdaptor = CardPresentPaymentsOnboardingPresenterAdaptor()
4073
self.onboardingAdaptor = onboardingAdaptor
@@ -61,21 +94,6 @@ final class CardPresentPaymentService: CardPresentPaymentFacade {
6194
.merge(with: paymentEventSubject)
6295
.receive(on: DispatchQueue.main) // These will be used for UI changes, so moving to the Main thread helps.
6396
.eraseToAnyPublisher()
64-
65-
let connectedReaderPublisher = await Self.createCardReaderConnectionPublisher(stores: stores)
66-
self.connectedReaderPublisher = connectedReaderPublisher
67-
68-
readerConnectionStatusPublisher = connectedReaderPublisher
69-
.map({ reader -> CardPresentPaymentReaderConnectionStatus in
70-
guard let reader else {
71-
return .disconnected
72-
}
73-
return .connected(reader)
74-
})
75-
.merge(with: paymentAlertsPresenterAdaptor.readerConnectionStatusPublisher)
76-
.merge(with: readerConnectionStatusSubject)
77-
.receive(on: DispatchQueue.main)
78-
.eraseToAnyPublisher()
7997
}
8098

8199
@MainActor
@@ -183,30 +201,6 @@ final class CardPresentPaymentService: CardPresentPaymentFacade {
183201
}
184202

185203
private extension CardPresentPaymentService {
186-
@MainActor
187-
static func createCardReaderConnectionPublisher(stores: StoresManager) async -> AnyPublisher<CardPresentPaymentCardReader?, Never> {
188-
return await withCheckedContinuation { continuation in
189-
var nillableContinuation: CheckedContinuation<AnyPublisher<CardPresentPaymentCardReader?, Never>, Never>? = continuation
190-
191-
let action = CardPresentPaymentAction.publishCardReaderConnections { cardReadersConnectionPublisher in
192-
let readerConnectionPublisher = cardReadersConnectionPublisher
193-
.map { readers -> CardPresentPaymentCardReader? in
194-
guard let reader = readers.first else {
195-
return nil
196-
}
197-
return CardPresentPaymentCardReader(name: reader.name ?? reader.id,
198-
batteryLevel: reader.batteryLevel)
199-
}
200-
.receive(on: DispatchQueue.main)
201-
.eraseToAnyPublisher()
202-
203-
nillableContinuation?.resume(returning: readerConnectionPublisher)
204-
nillableContinuation = nil
205-
}
206-
stores.dispatch(action)
207-
}
208-
}
209-
210204
func createPreflightController() -> CardPresentPaymentPreflightController<
211205
CardPresentPaymentBuiltInReaderConnectionAlertsProvider,
212206
CardPresentPaymentBluetoothReaderConnectionAlertsProvider,

WooCommerce/Classes/ViewRelated/Hub Menu/HubMenu.swift

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,10 @@ struct HubMenu: View {
3232
viewModel.setupMenuElements()
3333
}
3434
.fullScreenCover(isPresented: $viewModel.showsPOS) {
35-
if let cardPresentPaymentService = viewModel.cardPresentPaymentService,
36-
let receiptService = POSReceiptService(siteID: viewModel.siteID,
35+
let collectOrderPaymentAnalyticsTracker = POSCollectOrderPaymentAnalytics()
36+
let cardPresentPaymentService = CardPresentPaymentService(siteID: viewModel.siteID,
37+
collectOrderPaymentAnalyticsTracker: collectOrderPaymentAnalyticsTracker)
38+
if let receiptService = POSReceiptService(siteID: viewModel.siteID,
3739
credentials: viewModel.credentials),
3840
let orderService = POSOrderService(siteID: viewModel.siteID,
3941
credentials: viewModel.credentials),
@@ -46,7 +48,7 @@ struct HubMenu: View {
4648
cardPresentPaymentService: cardPresentPaymentService,
4749
orderController: PointOfSaleOrderController(orderService: orderService,
4850
receiptService: receiptService),
49-
collectOrderPaymentAnalyticsTracker: viewModel.collectOrderPaymentAnalyticsTracker)
51+
collectOrderPaymentAnalyticsTracker: collectOrderPaymentAnalyticsTracker)
5052
} else {
5153
// TODO: When we have a singleton for the card payment service, this should not be required.
5254
Text("Error creating card payment service")

WooCommerce/Classes/ViewRelated/Hub Menu/HubMenuViewModel.swift

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -135,8 +135,6 @@ final class HubMenuViewModel: ObservableObject {
135135
navigationPath: navigationPathBinding)
136136
}()
137137

138-
private(set) var cardPresentPaymentService: CardPresentPaymentFacade?
139-
private(set) var collectOrderPaymentAnalyticsTracker = POSCollectOrderPaymentAnalytics()
140138
private let analytics: Analytics
141139

142140
init(siteID: Int64,
@@ -167,7 +165,6 @@ final class HubMenuViewModel: ObservableObject {
167165
observePlanName()
168166
observeGoogleAdsEntryPointAvailability()
169167
tapToPayBadgePromotionChecker.$shouldShowTapToPayBadges.share().assign(to: &$shouldShowNewFeatureBadgeOnPayments)
170-
createCardPresentPaymentService()
171168
}
172169

173170
func viewDidAppear() async {
@@ -287,13 +284,6 @@ private extension HubMenuViewModel {
287284
// MARK: - Helper methods
288285
//
289286
private extension HubMenuViewModel {
290-
func createCardPresentPaymentService() {
291-
Task {
292-
self.cardPresentPaymentService = await CardPresentPaymentService(siteID: siteID,
293-
collectOrderPaymentAnalyticsTracker: collectOrderPaymentAnalyticsTracker)
294-
}
295-
}
296-
297287
func setupPOSElement() {
298288
posEligibilityChecker.isEligible.map { isEligibleForPOS in
299289
if isEligibleForPOS {

0 commit comments

Comments
 (0)