@@ -28,6 +28,15 @@ public class AppSettingsStore: Store {
2828 return documents!. appendingPathComponent ( Constants . shipmentProvidersFileName)
2929 } ( )
3030
31+ /// URL to the plist file that we use to store the user selected
32+ /// custom shipment tracing provider. Not declared as `private` so it can
33+ /// be overridden in tests
34+ ///
35+ lazy var customSelectedProvidersURL : URL = {
36+ let documents = FileManager . default. urls ( for: . documentDirectory, in: . userDomainMask) . first
37+ return documents!. appendingPathComponent ( Constants . customShipmentProvidersFileName)
38+ } ( )
39+
3140 /// Registers for supported Actions.
3241 ///
3342 override public func registerSupportedActions( in dispatcher: Dispatcher ) {
@@ -47,10 +56,21 @@ public class AppSettingsStore: Store {
4756 addTrackingProvider ( siteID: siteID,
4857 providerName: providerName,
4958 onCompletion: onCompletion)
50-
5159 case . loadTrackingProvider( let siteID, let onCompletion) :
5260 loadTrackingProvider ( siteID: siteID,
5361 onCompletion: onCompletion)
62+ case . addCustomTrackingProvider( let siteID,
63+ let providerName,
64+ let providerURL,
65+ let onCompletion) :
66+ addCustomTrackingProvider ( siteID: siteID,
67+ providerName: providerName,
68+ providerURL: providerURL,
69+ onCompletion: onCompletion)
70+ case . loadCustomTrackingProvider( let siteID,
71+ let onCompletion) :
72+ loadCustomTrackingProvider ( siteID: siteID,
73+ onCompletion: onCompletion)
5474 case . resetStoredProviders( let onCompletion) :
5575 resetStoredProviders ( onCompletion: onCompletion)
5676 }
@@ -64,34 +84,59 @@ private extension AppSettingsStore {
6484 func addTrackingProvider( siteID: Int ,
6585 providerName: String ,
6686 onCompletion: ( Error ? ) -> Void ) {
67- guard FileManager . default. fileExists ( atPath: selectedProvidersURL. path) else {
87+ addProvider ( siteID: siteID,
88+ providerName: providerName,
89+ fileURL: selectedProvidersURL,
90+ onCompletion: onCompletion)
91+
92+ }
93+
94+ func addCustomTrackingProvider( siteID: Int ,
95+ providerName: String ,
96+ providerURL: String ? ,
97+ onCompletion: ( Error ? ) -> Void ) {
98+ addProvider ( siteID: siteID,
99+ providerName: providerName,
100+ providerURL: providerURL,
101+ fileURL: customSelectedProvidersURL,
102+ onCompletion: onCompletion)
103+ }
104+
105+ func addProvider( siteID: Int ,
106+ providerName: String ,
107+ providerURL: String ? = nil ,
108+ fileURL: URL ,
109+ onCompletion: ( Error ? ) -> Void ) {
110+ guard FileManager . default. fileExists ( atPath: fileURL. path) else {
68111 insertNewProvider ( siteID: siteID,
69112 providerName: providerName,
113+ providerURL: providerURL,
114+ toFileURL: fileURL,
70115 onCompletion: onCompletion)
71116 onCompletion ( nil )
72117 return
73118 }
74119
75120 do {
76- let data = try fileStorage. data ( for: selectedProvidersURL )
121+ let data = try fileStorage. data ( for: fileURL )
77122 let decoder = PropertyListDecoder ( )
78123 let settings = try decoder. decode ( [ PreselectedProvider ] . self, from: data)
79124 upsertTrackingProvider ( siteID: siteID,
80125 providerName: providerName,
81126 preselectedData: settings,
127+ toFileURL: fileURL,
82128 onCompletion: onCompletion)
83129 } catch {
84130 let error = AppSettingsStoreErrors . parsePreselectedProvider
85131 onCompletion ( error)
86132
87133 DDLogError ( " ⛔️ Saving a tracking provider locally failed: siteID \( siteID) . Error: \( error) " )
88134 }
89-
90135 }
91136
92137 func loadTrackingProvider( siteID: Int ,
93138 onCompletion: ( ShipmentTrackingProvider ? , ShipmentTrackingProviderGroup ? , Error ? ) -> Void ) {
94- guard let allSavedProviders = read ( ) else {
139+ guard let allSavedProviders = read ( from : selectedProvidersURL ) else {
95140 let error = AppSettingsStoreErrors . readPreselectedProvider
96141 onCompletion ( nil , nil , error)
97142 return
@@ -115,12 +160,43 @@ private extension AppSettingsStore {
115160 onCompletion ( provider? . toReadOnly ( ) , provider? . group? . toReadOnly ( ) , nil )
116161 }
117162
163+ func loadCustomTrackingProvider( siteID: Int ,
164+ onCompletion: ( ShipmentTrackingProvider ? , Error ? ) -> Void ) {
165+ guard let allSavedProviders = read ( from: customSelectedProvidersURL) else {
166+ let error = AppSettingsStoreErrors . readPreselectedProvider
167+ onCompletion ( nil , error)
168+ return
169+ }
170+
171+ let providerName = allSavedProviders. filter {
172+ $0. siteID == siteID
173+ } . first? . providerName
174+
175+ let providerURL = allSavedProviders. filter {
176+ $0. siteID == siteID
177+ } . first? . providerURL
178+
179+ guard let name = providerName else {
180+ let error = AppSettingsStoreErrors . readPreselectedProvider
181+ onCompletion ( nil , error)
182+ return
183+ }
184+
185+ let customProvider = ShipmentTrackingProvider ( siteID: siteID,
186+ name: name,
187+ url: providerURL ?? " " )
188+ onCompletion ( customProvider, nil )
189+ }
190+
118191 func upsertTrackingProvider( siteID: Int ,
119192 providerName: String ,
193+ providerURL: String ? = nil ,
120194 preselectedData: [ PreselectedProvider ] ,
195+ toFileURL: URL ,
121196 onCompletion: ( Error ? ) -> Void ) {
122197 let newPreselectedProvider = PreselectedProvider ( siteID: siteID,
123- providerName: providerName)
198+ providerName: providerName,
199+ providerURL: providerURL)
124200
125201 var dataToSave = preselectedData
126202
@@ -131,34 +207,37 @@ private extension AppSettingsStore {
131207 dataToSave. append ( newPreselectedProvider)
132208 }
133209
134- write ( dataToSave, onCompletion: onCompletion)
210+ write ( dataToSave, to : toFileURL , onCompletion: onCompletion)
135211 }
136212
137213 func insertNewProvider( siteID: Int ,
138214 providerName: String ,
215+ providerURL: String ? = nil ,
216+ toFileURL: URL ,
139217 onCompletion: ( Error ? ) -> Void ) {
140218 let preselectedProvider = PreselectedProvider ( siteID: siteID,
141- providerName: providerName)
219+ providerName: providerName,
220+ providerURL: providerURL)
142221
143- write ( [ preselectedProvider] , onCompletion: onCompletion)
222+ write ( [ preselectedProvider] , to : toFileURL , onCompletion: onCompletion)
144223 }
145224
146- func write( _ data: [ PreselectedProvider ] , onCompletion: ( Error ? ) -> Void ) {
225+ func write( _ data: [ PreselectedProvider ] , to fileURL : URL , onCompletion: ( Error ? ) -> Void ) {
147226 let encoder = PropertyListEncoder ( )
148227 encoder. outputFormat = . xml
149228 do {
150229 let encodedData = try encoder. encode ( data)
151- try fileStorage. write ( encodedData, to: selectedProvidersURL )
230+ try fileStorage. write ( encodedData, to: fileURL )
152231 onCompletion ( nil )
153232 } catch {
154233 let error = AppSettingsStoreErrors . writePreselectedProvider
155234 onCompletion ( error)
156235 }
157236 }
158237
159- func read( ) -> [ PreselectedProvider ] ? {
238+ func read( from url : URL ) -> [ PreselectedProvider ] ? {
160239 do {
161- let data = try fileStorage. data ( for: selectedProvidersURL )
240+ let data = try fileStorage. data ( for: url )
162241 let decoder = PropertyListDecoder ( )
163242 return try decoder. decode ( [ PreselectedProvider ] . self, from: data)
164243 } catch {
@@ -169,6 +248,7 @@ private extension AppSettingsStore {
169248 func resetStoredProviders( onCompletion: ( ( Error ? ) -> Void ) ? = nil ) {
170249 do {
171250 try fileStorage. deleteFile ( at: selectedProvidersURL)
251+ try fileStorage. deleteFile ( at: customSelectedProvidersURL)
172252 onCompletion ? ( nil )
173253 } catch {
174254 let error = AppSettingsStoreErrors . deletePreselectedProvider
@@ -196,4 +276,5 @@ enum AppSettingsStoreErrors: Error {
196276///
197277private enum Constants {
198278 static let shipmentProvidersFileName = " shipment-providers.plist "
279+ static let customShipmentProvidersFileName = " custom-shipment-providers.plist "
199280}
0 commit comments