0

I am fetching data from server in a method for eg - fetchData().

I want to write logic in such a way that if fetchData() called twice(one after another) from different classes, both classes should be notified once network call is completed. My fetchData() method is block based.

Basically, I want to achieve following- If n/w call is in progress, then another call to fetchDAta() should not initiate n/w call to get same data.

For Example

fetchData() method is used to display data on two view controller Eg A and B.

If user is on controller A, then **fetchData()** call will be initiated and if before its completion user moved to controller B which also calls fetchData() to show data. Then again network call or other operation will happen.

If we know that data is same, is there any way we can pass same data to controller B once first call to that method finishes without initiating the n/w call again?

how to call completion handler for both controllers A and B?

srus2017
  • 394
  • 2
  • 14

2 Answers2

2

1- Since there is a one - many notifications , then the best is using NSNotificationCenter to send data is ready messages to all listeners , regarding the data itself you may send it when posting the notification using object or userInfo of the Notification center or share it in a singleton

2- With NotificationCenter no need for that , the one who needs the data should register as an observer

Shehata Gamal
  • 98,760
  • 8
  • 65
  • 87
0

Assuming your fetchData is in the singleton class, one approach would be using delegates in your singleton class to directly notify them with the changes. Add Class A and Class B as delegate.

protocol FetchDataProtocol {
    func didfinishDownloadingData()    
}


class SingletonClass {
    private var observers: [FetchDataProtocol] = []

    func add(observer: FetchDataProtocol) {
        if observers.index(where: { $0 === observer }) == nil {
           observers.append(observer)
        }
    }

    func remove(observer: FetchDataProtocol) {
        //find the object from observers then remove
    }

    private func notifyAll() {
         observers.forEach{ observer in 
            observer.didfinishDownloadingData()
         }
    }

   public function fetchData(){
      //When finished
      self.notifyAll()
   }
}

Add your classes as observers to fetchData changes.

// Do the same for ClassB
ClassA: FetchDataProtocol {
   init() {
     SingletonClass.shared.add(self)
  }

  func didfinishDownloadingData() {
       //notified here
  }

  deinit() {
     SingletonClass.shared.remove(self)
  }
}
janusfidel
  • 8,036
  • 4
  • 30
  • 53
  • @janusbalabat, Why are you adding observers in array?. Can't we use simple delegate pattern here? Although request can come from multiple controllers but at a time only one will be in memory. Can we use this single approach by setting delegate to nil which view is disappear. That is set delegate to nil in every viewController's viewDidDisapperar? and get reference of singleton again in viewWillApperar() and set delegate? – srus2017 Jul 26 '18 at 12:50