Skip to content

Commit 6374efc

Browse files
committed
14869 Basic implementation of Observable for POS
This adds a thin Observable layer on top of the underlying combine code
1 parent 4df70c1 commit 6374efc

File tree

1 file changed

+62
-34
lines changed

1 file changed

+62
-34
lines changed

WooCommerce/Classes/POS/Models/PointOfSaleAggregateModel.swift

Lines changed: 62 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import Foundation
22
import Combine
3+
import Observation
34

45
import protocol Yosemite.POSOrderableItem
56
import protocol WooFoundation.Analytics
@@ -38,24 +39,24 @@ protocol PointOfSaleAggregateModelProtocol {
3839
}
3940

4041
@available(iOS 17.0, *)
41-
class PointOfSaleAggregateModel: ObservableObject, PointOfSaleAggregateModelProtocol {
42-
@Published private(set) var orderStage: PointOfSaleOrderStage = .building
43-
44-
@Published private(set) var cardReaderConnectionStatus: CardPresentPaymentReaderConnectionStatus = .disconnected
45-
@Published private(set) var paymentState: PointOfSalePaymentState
46-
@Published var cardPresentPaymentAlertViewModel: PointOfSaleCardPresentPaymentAlertType?
47-
@Published private(set) var cardPresentPaymentInlineMessage: PointOfSaleCardPresentPaymentMessageType?
48-
@Published var cardPresentPaymentOnboardingViewModel: CardPresentPaymentsOnboardingViewModel?
42+
@Observable final class PointOfSaleAggregateModel: ObservableObject, PointOfSaleAggregateModelProtocol {
43+
private(set) var orderStage: PointOfSaleOrderStage = .building
44+
45+
private(set) var cardReaderConnectionStatus: CardPresentPaymentReaderConnectionStatus = .disconnected
46+
private(set) var paymentState: PointOfSalePaymentState
47+
var cardPresentPaymentAlertViewModel: PointOfSaleCardPresentPaymentAlertType?
48+
private(set) var cardPresentPaymentInlineMessage: PointOfSaleCardPresentPaymentMessageType?
49+
var cardPresentPaymentOnboardingViewModel: CardPresentPaymentsOnboardingViewModel?
4950
private var onOnboardingCancellation: (() -> Void)?
5051

51-
@Published private(set) var itemsViewState: ItemsViewState = ItemsViewState(containerState: .loading,
52-
itemsStack: ItemsStackState(root: .loading([]),
53-
itemStates: [:]))
52+
private(set) var itemsViewState: ItemsViewState = ItemsViewState(containerState: .loading,
53+
itemsStack: ItemsStackState(root: .loading([]),
54+
itemStates: [:]))
5455

55-
@Published private(set) var cart: [CartItem] = []
56+
private(set) var cart: [CartItem] = []
5657

57-
@Published private(set) var orderState: PointOfSaleOrderState = .idle
58-
@Published private var internalOrderState: PointOfSaleInternalOrderState = .idle
58+
private(set) var orderState: PointOfSaleOrderState = .idle
59+
private var internalOrderState: PointOfSaleInternalOrderState = .idle
5960

6061
private let itemsController: PointOfSaleItemsControllerProtocol
6162

@@ -90,7 +91,10 @@ class PointOfSaleAggregateModel: ObservableObject, PointOfSaleAggregateModelProt
9091
@available(iOS 17.0, *)
9192
extension PointOfSaleAggregateModel {
9293
private func publishItemsViewState() {
93-
itemsController.itemsViewStatePublisher.assign(to: &$itemsViewState)
94+
itemsController.itemsViewStatePublisher.sink { [weak self] state in
95+
self?.itemsViewState = state
96+
}
97+
.store(in: &cancellables)
9498
}
9599

96100
@MainActor
@@ -155,8 +159,11 @@ extension PointOfSaleAggregateModel {
155159
@available(iOS 17.0, *)
156160
extension PointOfSaleAggregateModel {
157161
private func publishCardReaderConnectionStatus() {
158-
// When adopting Observable, we can use `assign(to: on:)` here instead
159-
cardPresentPaymentService.readerConnectionStatusPublisher.assign(to: &$cardReaderConnectionStatus)
162+
cardPresentPaymentService.readerConnectionStatusPublisher
163+
.sink(receiveValue: { [weak self] connectionStatus in
164+
self?.cardReaderConnectionStatus = connectionStatus
165+
})
166+
.store(in: &cancellables)
160167
}
161168

162169
func connectCardReader() {
@@ -177,7 +184,7 @@ extension PointOfSaleAggregateModel {
177184
/// e.g. when the TotalsView goes offscreen.
178185
private func startPaymentWhenCardReaderConnected() async {
179186
guard case .connected = cardReaderConnectionStatus else {
180-
return startPaymentOnCardReaderConnection = $cardReaderConnectionStatus
187+
return startPaymentOnCardReaderConnection = cardPresentPaymentService.readerConnectionStatusPublisher
181188
.filter { status in
182189
switch status {
183190
case .connected:
@@ -259,17 +266,19 @@ extension PointOfSaleAggregateModel {
259266
await collectCardPayment()
260267
}
261268

262-
private func setupReaderReconnectionObservation() {
263-
$orderStage.sink(receiveValue: { [weak self] stage in
269+
@Sendable private func setupReaderReconnectionObservation() {
270+
withObservationTracking { [weak self] in
264271
guard let self else { return }
265-
switch stage {
266-
case .building:
267-
cancelCardReaderPreparation()
268-
case .finalizing:
269-
observeReaderReconnection()
272+
switch orderStage {
273+
case .building:
274+
cancelCardReaderPreparation()
275+
case .finalizing:
276+
observeReaderReconnection()
270277
}
271-
})
272-
.store(in: &cancellables)
278+
} onChange: { [weak self] in
279+
guard let self else { return }
280+
DispatchQueue.main.async(execute: setupReaderReconnectionObservation)
281+
}
273282
}
274283

275284
private func cancelCardReaderPreparation() {
@@ -279,7 +288,7 @@ extension PointOfSaleAggregateModel {
279288
}
280289

281290
private func observeReaderReconnection() {
282-
cardReaderDisconnection = $cardReaderConnectionStatus
291+
cardReaderDisconnection = cardPresentPaymentService.readerConnectionStatusPublisher
283292
.filter({ $0 == .disconnected })
284293
.sink { [weak self] _ in
285294
Task { @MainActor [weak self] in
@@ -321,13 +330,19 @@ private extension PointOfSaleAggregateModel {
321330
}
322331
return alertType
323332
}
324-
.assign(to: &$cardPresentPaymentAlertViewModel)
333+
.sink(receiveValue: { [weak self] alertType in
334+
self?.cardPresentPaymentAlertViewModel = alertType
335+
})
336+
.store(in: &cancellables)
325337

326338
cardPresentPaymentService.paymentEventPublisher
327339
.map { [weak self] event -> PointOfSaleCardPresentPaymentMessageType? in
328340
self?.mapCardPresentPaymentEventToMessageType(event)
329341
}
330-
.assign(to: &$cardPresentPaymentInlineMessage)
342+
.sink(receiveValue: { [weak self] message in
343+
self?.cardPresentPaymentInlineMessage = message
344+
})
345+
.store(in: &cancellables)
331346

332347
cardPresentPaymentService.paymentEventPublisher
333348
.compactMap { [weak self] paymentEvent -> PointOfSalePaymentState? in
@@ -338,7 +353,10 @@ private extension PointOfSaleAggregateModel {
338353

339354
return newPaymentState
340355
}
341-
.assign(to: &$paymentState)
356+
.sink(receiveValue: { [weak self] paymentState in
357+
self?.paymentState = paymentState
358+
})
359+
.store(in: &cancellables)
342360

343361
cardPresentPaymentService.paymentEventPublisher
344362
.map { [weak self] event -> CardPresentPaymentsOnboardingViewModel? in
@@ -349,7 +367,10 @@ private extension PointOfSaleAggregateModel {
349367
onOnboardingCancellation = onCancel
350368
return viewModel
351369
}
352-
.assign(to: &$cardPresentPaymentOnboardingViewModel)
370+
.sink(receiveValue: { [weak self] onboardingViewModel in
371+
self?.cardPresentPaymentOnboardingViewModel = onboardingViewModel
372+
})
373+
.store(in: &cancellables)
353374
}
354375

355376
/// Maps PaymentEvent to POSMessageType and annonates additional information if necessary
@@ -413,9 +434,16 @@ extension PointOfSaleAggregateModel {
413434
func publishOrderState() {
414435
orderController.orderStatePublisher
415436
.map { $0.externalState }
416-
.assign(to: &$orderState)
437+
.sink(receiveValue: { [weak self] orderState in
438+
self?.orderState = orderState
439+
})
440+
.store(in: &cancellables)
417441

418-
orderController.orderStatePublisher.assign(to: &$internalOrderState)
442+
orderController.orderStatePublisher
443+
.sink(receiveValue: { [weak self] internalOrderState in
444+
self?.internalOrderState = internalOrderState
445+
})
446+
.store(in: &cancellables)
419447
}
420448
}
421449

0 commit comments

Comments
 (0)