1

ich diese grundlegende Architektur erstellt meine Vernetzung Sachen zu handhaben,iOS - swift 3 - DispatchGroup

ich wollte es behalten modular und strukturiert:

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]() 

} 

Also, wenn ich das nenne in meiner separaten Klasse:

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, scheint es wie DispatchGroup(). notify() ausgeführt wird, bevor alle Anforderungen fertig ... da keine Anmerkungen zu mapview hinzugefügt werden.

Ich bereits überprüft und Anmerkungen werden geladen.

Jeder könnte mir bei dieser Architektur helfen?

Danke und Grüße!

+0

ich habe es geändert in: networkManager.getDispatchGroup(). Notify (queue: DispatchQueue.main) {..} aber es ist immer noch die gleichen .. irgendeinen Vorschlag? –

+1

@Creativecrypter Sie sollten Ihre DispatchGroup wie folgt deklarieren: 'public private (set) var dispatchGroup: DispatchGroup'. Es macht keinen Sinn, eine berechnete Eigenschaft für die Rückgabe einer Eigenschaft zu erstellen. Verwenden Sie einfach die Eigenschaft direkt und legen Sie ihren Setter auf privat fest. – Alexander

+0

hi, ich habe meinen Code in einen Singleton geändert und Ihre Änderung eingeschlossen, immer noch das gleiche Ergebnis:/Können Sie das überprüfen? –

Antwort

4

Ich denke, Sie müssen self.dispatchGroup.leave() innerhalb der Alamofire Antwort Handler setzen. Wie geschrieben, verlassen Sie, sobald Sie die Anfrage in die Warteschlange stellen.

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

danke, was für ein dummer Fehler .. –

1

Ändern Sie Ihren Code wie unten gezeigt.

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 
     } 
    } 
} 

Der Fehler war, dass Sie die DispatchGroup verlassen haben, kurz nachdem Sie es eingegeben haben. Wenn Sie warten müssen, bis der Netzwerkvorgang abgeschlossen ist, sollten Sie den Antworthandler verlassen.