@@ -36,6 +36,9 @@ open class DefaultDatafileHandler: OPTDatafileHandler {
3636
3737 // and our download queue to speed things up.
3838 let downloadQueue = DispatchQueue ( label: " DefaultDatafileHandlerQueue " )
39+
40+ // network reachability
41+ let reachability = NetworkReachability ( maxContiguousFails: 1 )
3942
4043 public required init ( ) { }
4144
@@ -47,45 +50,59 @@ open class DefaultDatafileHandler: OPTDatafileHandler {
4750 completionHandler: @escaping DatafileDownloadCompletionHandler ) {
4851
4952 downloadQueue. async {
53+
54+ func returnCached( _ result: OptimizelyResult < Data ? > ? = nil ) -> OptimizelyResult < Data ? > {
55+ if let data = self . loadSavedDatafile ( sdkKey: sdkKey) {
56+ return . success( data)
57+ } else {
58+ return result ?? . failure( . datafileLoadingFailed( sdkKey) )
59+ }
60+ }
61+
62+ if self . reachability. shouldBlockNetworkAccess ( ) {
63+ let optError = OptimizelyError . datafileDownloadFailed ( " NetworkReachability down " )
64+ self . logger. e ( optError)
65+
66+ let result = OptimizelyResult< Data?> . failure( optError)
67+ completionHandler ( returnCached ( result) )
68+ return
69+ }
70+
5071 let session = self . getSession ( resourceTimeoutInterval: resourceTimeoutInterval)
5172
5273 guard let request = self . getRequest ( sdkKey: sdkKey) else { return }
5374
5475 let task = session. downloadTask ( with: request) { ( url, response, error) in
55- var result = OptimizelyResult< Data?> . failure( . datafileLoadingFailed( sdkKey) )
56-
57- let returnCached = {
58- if let data = self . loadSavedDatafile ( sdkKey: sdkKey) {
59- result = . success( data)
60- }
61- }
76+ var result = OptimizelyResult< Data?> . failure( . generic)
6277
6378 if error != nil {
64- self . logger . e ( error. debugDescription)
65- result = . failure ( . datafileDownloadFailed ( error . debugDescription ) )
66- returnCached ( ) // error recovery
79+ let optError = OptimizelyError . datafileDownloadFailed ( error. debugDescription)
80+ self . logger . e ( optError )
81+ result = returnCached ( . failure ( optError ) ) // error recovery
6782 } else if let response = response as? HTTPURLResponse {
6883 switch response. statusCode {
6984 case 200 :
7085 if let data = self . getResponseData ( sdkKey: sdkKey, response: response, url: url) {
7186 result = . success( data)
7287 } else {
73- returnCached ( ) // error recovery
88+ result = returnCached ( ) // error recovery
7489 }
7590 case 304 :
7691 self . logger. d ( " The datafile was not modified and won't be downloaded again " )
7792
7893 if returnCacheIfNoChange {
79- returnCached ( )
94+ result = returnCached ( )
8095 } else {
8196 result = . success( nil )
8297 }
8398 default :
8499 self . logger. i ( " got response code \( response. statusCode) " )
85- returnCached ( ) // error recovery
100+ result = returnCached ( ) // error recovery
86101 }
87102 }
88103
104+ self . reachability. updateNumContiguousFails ( isError: ( error != nil ) )
105+
89106 completionHandler ( result)
90107 }
91108
@@ -244,6 +261,24 @@ extension DefaultDatafileHandler {
244261 updateInterval: Int ,
245262 datafileChangeNotification: ( ( Data ) -> Void ) ? ) {
246263 let beginDownloading = Date ( )
264+
265+ let scheduleNextUpdate : ( ) -> Void = {
266+ guard self . hasPeriodicInterval ( sdkKey: sdkKey) else { return }
267+
268+ // adjust the next fire time so that events will be fired at fixed interval regardless of the download latency
269+ // if latency is too big (or returning from background mode), fire the next event immediately once
270+
271+ var interval = self . timers. property ? [ sdkKey] ? . interval ?? updateInterval
272+ let delay = Int ( Date ( ) . timeIntervalSince ( beginDownloading) )
273+ interval -= delay
274+ if interval < 0 {
275+ interval = 0
276+ }
277+
278+ self . logger. d ( " next datafile download is \( interval) seconds \( Date ( ) ) " )
279+ self . startPeriodicUpdates ( sdkKey: sdkKey, updateInterval: interval, datafileChangeNotification: datafileChangeNotification)
280+ }
281+
247282 self . downloadDatafile ( sdkKey: sdkKey) { ( result) in
248283 switch result {
249284 case . success( let data) :
@@ -255,20 +290,7 @@ extension DefaultDatafileHandler {
255290 self . logger. e ( error. reason)
256291 }
257292
258- if self . hasPeriodicInterval ( sdkKey: sdkKey) {
259- // adjust the next fire time so that events will be fired at fixed interval regardless of the download latency
260- // if latency is too big (or returning from background mode), fire the next event immediately once
261-
262- var interval = self . timers. property ? [ sdkKey] ? . interval ?? updateInterval
263- let delay = Int ( Date ( ) . timeIntervalSince ( beginDownloading) )
264- interval -= delay
265- if interval < 0 {
266- interval = 0
267- }
268-
269- self . logger. d ( " next datafile download is \( interval) seconds \( Date ( ) ) " )
270- self . startPeriodicUpdates ( sdkKey: sdkKey, updateInterval: interval, datafileChangeNotification: datafileChangeNotification)
271- }
293+ scheduleNextUpdate ( )
272294 }
273295 }
274296
0 commit comments