Skip to content

Commit 3b620a9

Browse files
authored
Require selected site for AlamofireNetwork (#16124)
2 parents 3fd0ab9 + 9462373 commit 3b620a9

File tree

32 files changed

+416
-140
lines changed

32 files changed

+416
-140
lines changed

Modules/Sources/NetworkingCore/Network/AlamofireNetwork.swift

Lines changed: 31 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -57,21 +57,25 @@ public class AlamofireNetwork: Network {
5757

5858
public var session: URLSession { Session.default.session }
5959

60-
private var subscription: AnyCancellable?
60+
private var siteSubscription: AnyCancellable?
6161

6262
/// Thread-safe error handler for failure tracking and retry logic
6363
private let errorHandler: AlamofireNetworkErrorHandler
6464

65+
private var appPasswordSupportSubscription: AnyCancellable?
66+
6567
/// Public Initializer
6668
///
6769
/// - Parameters:
6870
/// - credentials: Authentication credentials for requests.
6971
/// - selectedSite: Publisher for site selection changes.
72+
/// This is necessary if you wish to enable network switching to direct requests while authenticated with WPCOM for better performance.
7073
/// - sessionManager: Optional pre-configured session manager.
7174
/// - ensuresSessionManagerIsInitialized: If true, the session is always set during initialization immediately to avoid lazy initialization race conditions.
7275
/// Defaults to false for backward compatibility. Set to true when making concurrent requests immediately after initialization.
7376
public required init(credentials: Credentials?,
74-
selectedSite: AnyPublisher<JetpackSite?, Never>? = nil,
77+
selectedSite: AnyPublisher<JetpackSite?, Never>?,
78+
appPasswordSupportState: AnyPublisher<Bool, Never>?,
7579
userDefaults: UserDefaults = .standard,
7680
sessionManager: Alamofire.Session? = nil,
7781
ensuresSessionManagerIsInitialized: Bool = false) {
@@ -110,17 +114,8 @@ public class AlamofireNetwork: Network {
110114
}
111115
}()
112116
updateAuthenticationMode(authenticationMode)
113-
}
114-
115-
public func updateAppPasswordSwitching(enabled: Bool) {
116-
guard let credentials, case .wpcom = credentials else { return }
117-
if enabled, let selectedSite {
118-
observeSelectedSite(selectedSite)
119-
} else {
120-
requestConverter = RequestConverter(siteAddress: nil)
121-
requestAuthenticator.updateAuthenticator(DefaultRequestAuthenticator(credentials: credentials))
122-
requestAuthenticator.delegate = nil
123-
updateAuthenticationMode(.jetpackTunnel)
117+
if let appPasswordSupportState {
118+
observeAppPasswordSupportState(appPasswordSupportState)
124119
}
125120
}
126121

@@ -277,6 +272,28 @@ public class AlamofireNetwork: Network {
277272
}
278273

279274
private extension AlamofireNetwork {
275+
276+
func observeAppPasswordSupportState(_ appPasswordSupportState: AnyPublisher<Bool, Never>) {
277+
appPasswordSupportSubscription = appPasswordSupportState
278+
.removeDuplicates()
279+
.sink { [weak self] enabled in
280+
self?.updateAppPasswordSwitching(enabled: enabled)
281+
}
282+
}
283+
284+
func updateAppPasswordSwitching(enabled: Bool) {
285+
guard let credentials, case .wpcom = credentials else { return }
286+
if enabled, let selectedSite {
287+
observeSelectedSite(selectedSite)
288+
} else {
289+
requestConverter = RequestConverter(siteAddress: nil)
290+
requestAuthenticator.updateAuthenticator(DefaultRequestAuthenticator(credentials: credentials))
291+
requestAuthenticator.delegate = nil
292+
updateAuthenticationMode(.jetpackTunnel)
293+
siteSubscription = nil
294+
}
295+
}
296+
280297
/// Creates a session manager with request retrier and adapter
281298
///
282299
func makeSession(configuration sessionConfiguration: URLSessionConfiguration) -> Alamofire.Session {
@@ -286,7 +303,7 @@ private extension AlamofireNetwork {
286303
/// Updates `requestConverter` and `requestAuthenticator` when selected site changes
287304
///
288305
func observeSelectedSite(_ selectedSite: AnyPublisher<JetpackSite?, Never>) {
289-
subscription = selectedSite
306+
siteSubscription = selectedSite
290307
.removeDuplicates()
291308
.combineLatest(userDefaults.publisher(for: \.applicationPasswordUnsupportedList))
292309
.sink { [weak self] site, unsupportedList in

Modules/Sources/Yosemite/PointOfSale/Coupons/PointOfSaleCouponFetchStrategyFactory.swift

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ import class WooFoundation.CurrencySettings
33
import protocol Storage.StorageManagerType
44
import class Networking.CouponsRemote
55
import class Networking.AlamofireNetwork
6+
import struct Combine.AnyPublisher
7+
import struct NetworkingCore.JetpackSite
68

79
public struct PointOfSaleCouponFetchStrategyFactory {
810
private let siteID: Int64
@@ -13,8 +15,12 @@ public struct PointOfSaleCouponFetchStrategyFactory {
1315
public init(siteID: Int64,
1416
currencySettings: CurrencySettings,
1517
credentials: Credentials?,
18+
selectedSite: AnyPublisher<JetpackSite?, Never>,
19+
appPasswordSupportState: AnyPublisher<Bool, Never>,
1620
storage: StorageManagerType) {
17-
let network = AlamofireNetwork(credentials: credentials)
21+
let network = AlamofireNetwork(credentials: credentials,
22+
selectedSite: selectedSite,
23+
appPasswordSupportState: appPasswordSupportState)
1824
let remote = CouponsRemote(network: network)
1925
self.siteID = siteID
2026
self.currencySettings = currencySettings

Modules/Sources/Yosemite/PointOfSale/Coupons/PointOfSaleCouponService.swift

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import class WooFoundation.CurrencyFormatter
55
import class WooFoundation.CurrencySettings
66
import Storage
77
import enum Alamofire.AFError
8+
import struct Combine.AnyPublisher
9+
import struct NetworkingCore.JetpackSite
810

911
public protocol PointOfSaleCouponServiceProtocol {
1012
func provideLocalPointOfSaleCoupons(fetchStrategy: PointOfSaleCouponFetchStrategy) async throws -> [POSItem]
@@ -30,8 +32,12 @@ public final class PointOfSaleCouponService: PointOfSaleCouponServiceProtocol {
3032
public convenience init(siteID: Int64,
3133
currencySettings: CurrencySettings,
3234
credentials: Credentials?,
35+
selectedSite: AnyPublisher<JetpackSite?, Never>,
36+
appPasswordSupportState: AnyPublisher<Bool, Never>,
3337
storage: StorageManagerType) {
34-
let network = AlamofireNetwork(credentials: credentials)
38+
let network = AlamofireNetwork(credentials: credentials,
39+
selectedSite: selectedSite,
40+
appPasswordSupportState: appPasswordSupportState)
3541
self.init(siteID: siteID,
3642
currencySettings: currencySettings,
3743
settingStoreMethods: SettingStoreMethods(storageManager: storage, network: network),

Modules/Sources/Yosemite/PointOfSale/Eligibility/POSSystemStatusService.swift

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import Foundation
22
import Networking
33
import Storage
4+
import struct Combine.AnyPublisher
45

56
public protocol POSSystemStatusServiceProtocol {
67
/// Loads WooCommerce plugin and POS feature switch value remotely for eligibility checks.
@@ -27,8 +28,13 @@ public final class POSSystemStatusService: POSSystemStatusServiceProtocol {
2728
private let storageManager: StorageManagerType
2829
private let pluginsService: PluginsServiceProtocol
2930

30-
public init(credentials: Credentials?, storageManager: StorageManagerType) {
31-
let network = AlamofireNetwork(credentials: credentials)
31+
public init(credentials: Credentials?,
32+
selectedSite: AnyPublisher<JetpackSite?, Never>,
33+
appPasswordSupportState: AnyPublisher<Bool, Never>,
34+
storageManager: StorageManagerType) {
35+
let network = AlamofireNetwork(credentials: credentials,
36+
selectedSite: selectedSite,
37+
appPasswordSupportState: appPasswordSupportState)
3238
self.remote = SystemStatusRemote(network: network)
3339
self.storageManager = storageManager
3440
self.pluginsService = PluginsService(storageManager: storageManager)

Modules/Sources/Yosemite/PointOfSale/Items/PointOfSaleBarcodeScanService.swift

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ import class Networking.ProductsRemote
44
import class WooFoundation.CurrencySettings
55
import class Networking.AlamofireNetwork
66
import enum Networking.NetworkError
7+
import struct Combine.AnyPublisher
8+
import struct NetworkingCore.JetpackSite
79

810
public protocol PointOfSaleBarcodeScanServiceProtocol {
911
func getItem(barcode: String) async throws(PointOfSaleBarcodeScanError) -> POSItem
@@ -40,8 +42,12 @@ public final class PointOfSaleBarcodeScanService: PointOfSaleBarcodeScanServiceP
4042

4143
public convenience init(siteID: Int64,
4244
credentials: Credentials?,
45+
selectedSite: AnyPublisher<JetpackSite?, Never>,
46+
appPasswordSupportState: AnyPublisher<Bool, Never>,
4347
currencySettings: CurrencySettings) {
44-
let network = AlamofireNetwork(credentials: credentials)
48+
let network = AlamofireNetwork(credentials: credentials,
49+
selectedSite: selectedSite,
50+
appPasswordSupportState: appPasswordSupportState)
4551
self.init(siteID: siteID,
4652
productsRemote: ProductsRemote(network: network),
4753
currencySettings: currencySettings)

Modules/Sources/Yosemite/PointOfSale/Items/PointOfSaleItemFetchStrategyFactory.swift

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ import Foundation
22
import class Networking.ProductsRemote
33
import class Networking.ProductVariationsRemote
44
import class Networking.AlamofireNetwork
5+
import struct Combine.AnyPublisher
6+
import struct NetworkingCore.JetpackSite
57

68
public protocol PointOfSaleItemFetchStrategyFactoryProtocol {
79
func defaultStrategy(analytics: POSItemFetchAnalyticsTracking) -> PointOfSalePurchasableItemFetchStrategy
@@ -18,9 +20,13 @@ public final class PointOfSaleItemFetchStrategyFactory: PointOfSaleItemFetchStra
1820
private let variationsRemote: ProductVariationsRemote
1921

2022
public init(siteID: Int64,
21-
credentials: Credentials?) {
23+
credentials: Credentials?,
24+
selectedSite: AnyPublisher<JetpackSite?, Never>? = nil,
25+
appPasswordSupportState: AnyPublisher<Bool, Never>? = nil) {
2226
self.siteID = siteID
23-
let network = AlamofireNetwork(credentials: credentials)
27+
let network = AlamofireNetwork(credentials: credentials,
28+
selectedSite: selectedSite,
29+
appPasswordSupportState: appPasswordSupportState)
2430
self.productsRemote = ProductsRemote(network: network)
2531
self.variationsRemote = ProductVariationsRemote(network: network)
2632
}

Modules/Sources/Yosemite/PointOfSale/OrderList/POSOrderListFetchStrategyFactory.swift

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ import Foundation
22
import class Networking.AlamofireNetwork
33
import class Networking.OrdersRemote
44
import class WooFoundationCore.CurrencyFormatter
5+
import struct Combine.AnyPublisher
6+
import struct NetworkingCore.JetpackSite
57

68
public protocol POSOrderListFetchStrategyFactoryProtocol {
79
func defaultStrategy() -> POSOrderListFetchStrategy
@@ -15,9 +17,13 @@ public final class POSOrderListFetchStrategyFactory: POSOrderListFetchStrategyFa
1517

1618
public init(siteID: Int64,
1719
credentials: Credentials?,
20+
selectedSite: AnyPublisher<JetpackSite?, Never>,
21+
appPasswordSupportState: AnyPublisher<Bool, Never>,
1822
currencyFormatter: CurrencyFormatter) {
1923
self.siteID = siteID
20-
let network = AlamofireNetwork(credentials: credentials)
24+
let network = AlamofireNetwork(credentials: credentials,
25+
selectedSite: selectedSite,
26+
appPasswordSupportState: appPasswordSupportState)
2127
self.ordersRemote = OrdersRemote(network: network)
2228
self.currencyFormatter = currencyFormatter
2329
}

Modules/Sources/Yosemite/Tools/POS/POSCatalogFullSyncService.swift

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ import protocol Networking.POSCatalogSyncRemoteProtocol
33
import class Networking.AlamofireNetwork
44
import class Networking.POSCatalogSyncRemote
55
import Storage
6+
import struct Combine.AnyPublisher
7+
import struct NetworkingCore.JetpackSite
68

79
// TODO - remove the periphery ignore comment when the catalog is integrated with POS.
810
// periphery:ignore
@@ -30,12 +32,19 @@ public final class POSCatalogFullSyncService: POSCatalogFullSyncServiceProtocol
3032
private let persistenceService: POSCatalogPersistenceServiceProtocol
3133
private let batchedLoader: BatchedRequestLoader
3234

33-
public convenience init?(credentials: Credentials?, batchSize: Int = 2, grdbManager: GRDBManagerProtocol) {
35+
public convenience init?(credentials: Credentials?,
36+
selectedSite: AnyPublisher<JetpackSite?, Never>,
37+
appPasswordSupportState: AnyPublisher<Bool, Never>,
38+
batchSize: Int = 2,
39+
grdbManager: GRDBManagerProtocol) {
3440
guard let credentials else {
3541
DDLogError("⛔️ Could not create POSCatalogFullSyncService due missing credentials")
3642
return nil
3743
}
38-
let network = AlamofireNetwork(credentials: credentials, ensuresSessionManagerIsInitialized: true)
44+
let network = AlamofireNetwork(credentials: credentials,
45+
selectedSite: selectedSite,
46+
appPasswordSupportState: appPasswordSupportState,
47+
ensuresSessionManagerIsInitialized: true)
3948
let syncRemote = POSCatalogSyncRemote(network: network)
4049
let persistenceService = POSCatalogPersistenceService(grdbManager: grdbManager)
4150
self.init(syncRemote: syncRemote, batchSize: batchSize, persistenceService: persistenceService)

Modules/Sources/Yosemite/Tools/POS/POSCatalogIncrementalSyncService.swift

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ import protocol Networking.POSCatalogSyncRemoteProtocol
33
import class Networking.AlamofireNetwork
44
import class Networking.POSCatalogSyncRemote
55
import protocol Storage.GRDBManagerProtocol
6+
import struct NetworkingCore.JetpackSite
7+
import struct Combine.AnyPublisher
68

79
// TODO - remove the periphery ignore comment when the service is integrated with POS.
810
// periphery:ignore
@@ -22,12 +24,19 @@ public final class POSCatalogIncrementalSyncService: POSCatalogIncrementalSyncSe
2224
private let persistenceService: POSCatalogPersistenceServiceProtocol
2325
private let batchedLoader: BatchedRequestLoader
2426

25-
public convenience init?(credentials: Credentials?, batchSize: Int = 1, grdbManager: GRDBManagerProtocol) {
27+
public convenience init?(credentials: Credentials?,
28+
selectedSite: AnyPublisher<JetpackSite?, Never>,
29+
appPasswordSupportState: AnyPublisher<Bool, Never>,
30+
batchSize: Int = 1,
31+
grdbManager: GRDBManagerProtocol) {
2632
guard let credentials else {
2733
DDLogError("⛔️ Could not create POSCatalogIncrementalSyncService due missing credentials")
2834
return nil
2935
}
30-
let network = AlamofireNetwork(credentials: credentials, ensuresSessionManagerIsInitialized: true)
36+
let network = AlamofireNetwork(credentials: credentials,
37+
selectedSite: selectedSite,
38+
appPasswordSupportState: appPasswordSupportState,
39+
ensuresSessionManagerIsInitialized: true)
3140
let syncRemote = POSCatalogSyncRemote(network: network)
3241
let persistenceService = POSCatalogPersistenceService(grdbManager: grdbManager)
3342
self.init(syncRemote: syncRemote, batchSize: batchSize, persistenceService: persistenceService)

Modules/Sources/Yosemite/Tools/POS/POSOrderService.swift

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ import Foundation
22
import Networking
33
import class WooFoundation.CurrencyFormatter
44
import enum WooFoundation.CurrencyCode
5+
import struct Combine.AnyPublisher
6+
import struct NetworkingCore.JetpackSite
57

68
public protocol POSOrderServiceProtocol {
79
/// Syncs order based on the cart.
@@ -17,12 +19,17 @@ public final class POSOrderService: POSOrderServiceProtocol {
1719
private let siteID: Int64
1820
private let ordersRemote: POSOrdersRemoteProtocol
1921

20-
public convenience init?(siteID: Int64, credentials: Credentials?) {
22+
public convenience init?(siteID: Int64,
23+
credentials: Credentials?,
24+
selectedSite: AnyPublisher<JetpackSite?, Never>,
25+
appPasswordSupportState: AnyPublisher<Bool, Never>) {
2126
guard let credentials else {
2227
DDLogError("⛔️ Could not create POSOrderService due to not finding credentials")
2328
return nil
2429
}
25-
let network = AlamofireNetwork(credentials: credentials)
30+
let network = AlamofireNetwork(credentials: credentials,
31+
selectedSite: selectedSite,
32+
appPasswordSupportState: appPasswordSupportState)
2633
self.init(siteID: siteID,
2734
ordersRemote: OrdersRemote(network: network))
2835
}

0 commit comments

Comments
 (0)