2017-01-14 27 views
1

私は私のネットワーキングのものを処理するために、この基本的なアーキテクチャを作成し、iOSの - SWIFT 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ように思える。通知()すべての要求が終了する前に...何の注釈がのMapViewに追加されていないため、実行されます。

既にチェックしてあり、アノテーションが読み込まれています。

誰でもこのアーキテクチャで私を助けることができますか?

ありがとうございました!

+0

networkManager.getDispatchGroup()。notify(キュー:DispatchQueue.main){..} しかし、それでも同じです..任意の提案? –

+1

@CreativecrypterあなたはあなたのdispatchGroupを 'public private(set)var dispatchGroup:DispatchGroup'として宣言する必要があります。プロパティを返す計算されたプロパティを作ることは何の意味もありません。プロパティを直接使用し、そのセッターをprivateに設定するだけです。 – Alexander

+0

こんにちは、私はシングルトンに自分のコードを変更し、あなたの変更を含めましたが、依然として同じ結果です:/あなたはチェックできますか? –

答えて

4

私はレスポンスハンドラの中にself.dispatchGroup.leave()を入れる必要があると思います。書かれているように、リクエストをキューに入れるとすぐに出ます。

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を離れることが間違っていました。ネットワーク操作が完了するのを待つ必要がある場合は、応答ハンドラ内から離れる必要があります。