2017-01-14 19 views
1

Я создал эту базовую архитектуру, чтобы справиться с моим сетевым материалом,IOS - скор 3 - DispatchGroup

я хотел сохранить его модульным и структурировано:

public class NetworkManager { 

    public private(set) var queue: DispatchQueue = DispatchQueue(label: "com.example.app.dispatchgroups", attributes: .concurrent, target: .main) 
    public private(set) var dispatchGroup: DispatchGroup = DispatchGroup() 

    private static var sharedNetworkManager: NetworkManager = { 
     let networkManager = NetworkManager() 
     return networkManager 
    }() 

    private init() {} 

    class func shared() -> NetworkManager { 
     return sharedNetworkManager 
    } 

    public func getData() { 
     dispatchGroup.enter() 

     queue.async(group: dispatchGroup) { 
      Alamofire.request(Content.url).responseJSON { response in 
       switch response.result { 
       case .success(let value): 
        let json = JSON(value) 
        // do some stuff and save to Content struct 
        Content.annotations += [Station(...)] 

       case .failure(let error): 
        print("error: ",error) 
       } 
      } 

      self.dispatchGroup.leave() 
     } 
    } 

} 

struct Content { 

    static var url = "url" 

    static var annotations = [Station]() 

} 

Так что, когда я называю это в моем отдельном классе:

class MainViewController { 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     // some stuff ... 

     NetworkManager.shared().getData() 

     NetworkManager.shared().dispatchGroup.notify(queue: DispatchQueue.main) { 
      self.mapView.removeAnnotations(Content.annotations) 
      self.mapView.addAnnotations(Content.annotations) 
     } 
    } 

} 

Buuut, похож DispatchGroup(). Notify() выполняются перед всеми запросами закончили ... потому что никаких аннотаций не добавляются MapView.

Я уже проверил и аннотации загружены.

Любой может помочь мне с этой архитектурой?

Спасибо и приветствую!

+0

Я изменил его на: networkManager.getDispatchGroup(). Notify (queue: DispatchQueue.main) {..} , но его все равно то же самое .. любое предложение? –

+1

@Creativecrypter Вы должны объявить свою диспетчерскую группу как: 'public private (set) var dispatchGroup: DispatchGroup'. Нет смысла делать вычисляемое свойство для возврата свойства. Просто используйте свойство напрямую и установите его сеттер в закрытый. – Alexander

+0

привет, я изменил свой код на одноэлемент и включил ваши изменения, все тот же результат:/вы можете проверить? –

ответ

4

Я думаю, вам нужно положить self.dispatchGroup.leave() внутри обработчика ответа Alamofire. Как написано, вы уходите, как только вы ставите в очередь запрос.

queue.async(group: dispatchGroup) { 
     Alamofire.request(Content.url).responseJSON { response in 
      switch response.result { 
      case .success(let value): 
       let json = JSON(value) 
       // do some stuff and save to Content struct 
       Content.annotations += [Station(...)] 

      case .failure(let error): 
       print("error: ",error) 
      } 
      self.dispatchGroup.leave() 
     } 
    } 
+0

спасибо, какая глупая ошибка .. –

1

Изменить код, как показано ниже.

public func getData() { 
    dispatchGroup.enter() 
    queue.async(group: dispatchGroup) { 
     Alamofire.request(Content.url).responseJSON { response in 
      switch response.result { 
      case .success(let value): 
       let json = JSON(value) 
       // do some stuff and save to Content struct 
       Content.annotations += [Station(...)] 

      case .failure(let error): 
       print("error: ",error) 
      } 
      self.dispatchGroup.leave() // This statement has been moved 
     } 
    } 
} 

Ошибка в том, что вы покинули DispatchGroup вскоре после того, как вошли в нее. Если вам нужно дождаться завершения операции в сети, вы должны выйти из обработчика ответа.