2016-09-12 13 views
1

私は自分のアプリケーションの4つの異なる要求を持って、それらの3つがコールを1つだけ必要とし、最後は1から必要です - - 私は私を反復処理するとき10.Alamofire複数の要求の繰り返し

すべてが最後の要求まで正常に動作しますデータを収集し、電話をかける。これは、Class1ので私のコードです:

var data = ... 
var points = ... 

// I create a new group 
let getPointGroup = dispatch_group_create() 

// I iterate through my data 
for d in data{ 
    // I enter the group 
    dispatch_group_enter(getPointGroup) 
    dataService.getPoints(d.point), success: { points -> Void in 
     points.append(points) 

     // I leave the group so that I go to the next iteration 
     dispatch_group_leave(getPointGroup) 
    } 
} 

Alamofire要求がクラス2で次のようになります。

let headers = [ 
    "Authorization": "Bearer \(token)", 
    "Content-Type": "application/x-www-form-urlencoded" 
] 

Alamofire.request(.GET, url, headers:headers) 
    .responseJSON { response in 
     switch response.result { 
     case .Success: 
      let json = JSON(data: response.data!) 
      print(json) 
      success(json) 
     case .Failure(let error): 
      print(error) 
     } 
} 

しかし、私は完全に反復し、ちょうど呼び出しを削除した場合、私は、GETリクエストを打つことはありませんAlamofireの要求は一度完全に動作します。

Alamofireの反復要求を解決する方法のアイデアはありますか?あなたがdispatch_group_waitを使用する場合

編集
そうでもない複製、私はこれが実行されていない場合は別のクラスとの例では、以下のスニペットは本当に私の問題

+0

デッドロックが発生している可能性があります。メインスレッド内でこのグループ分け 'dispatch_group_enter()'をしていますか?もしそうなら、あなたは[この回答](http://stackoverflow.com/questions/39264454/how-to-wait-until-all-nsoperations-is-finished/39265681#39265681)を見たいかもしれません。 – ozgur

+0

@ozgur、その答えは良いですが、私は2つの異なるクラスにこれらのスニペットを持っているので、本当に私を助けません。 – user5855868

+0

@Rob、.Failureは決して呼び出されません。 – user5855868

答えて

2

を解決していない持っている、あなたがデッドロックすることができそのスレッドをブロックし、Alamofireがその完了ハンドラ(メインスレッドを必要とする)を実行しないようにします。これは解決されます(あなたが実際にdispatch_group_waitを使用していると仮定して)、それをdispatch_group_notifyに置き換えて解決します。したがって

let group = dispatch_group_create() 

for d in data { 
    // I enter the group 
    dispatch_group_enter(group) 
    dataService.getPoints(d.point)) { additionalPoints, error in 
     defer { dispatch_group_leave(group) } 

     guard let let additionalPoints = additionalPoints else { 
      print(error) 
      return 
     } 

     points.append(additionalPoints) 
    } 
} 

dispatch_group_notify(group, dispatch_get_main_queue()) { 
    // go to the next iteration here 
} 

:さて、私はあなたの様々なパラメータの型は何であったか分からないので、私は推測しておいたので、中で迷子にしないでください

func getPoints(point: WhateverThisIs, completionHandler: (JSON?, NSError?) ->()) { 
    let headers = [ 
     "Authorization": "Bearer \(token)" 
    ] 

    Alamofire.request(.GET, url, headers: headers) 
     .responseJSON { response in 
      switch response.result { 
      case .Success: 
       let json = JSON(data: response.data!) 
       completionHandler(json, nil) 
      case .Failure(let error): 
       completionHandler(nil, error) 
      } 
    } 
} 

それ。しかし重要なのは、(a)Alamofireメソッド内のすべてのパスが完了ハンドラを呼び出すことを確認する必要があります。 (b)呼び出し元がdispatch_group_waitではなくdispatch_group_notifyを使用して、スレッドのブロックを回避する必要があります。

ネットワークリクエストが失敗した場合でも完了ハンドラを呼び出し可能にするために、そのクロージャへのパラメータをオプションにする必要がありました。私がそこにいる間に、オプションのエラーパラメータも追加しました。上記のサンプルに含ま


いくつかの無関係な変更:

  1. 私はあなたの閉鎖のパラメータに別の変数名を使用してお勧めしたいです。元のコードスニペットのpoints.append(points)には、points配列とクロージャーに戻されたpointsの混乱が示唆されています。

  2. Content-Typeヘッダーを設定する必要はありません.Alamofireがこれを行います。

  3. 私は上記のそれを変更していないが、(JSONを解析するためにNSJSONSerializationを使用する)responseJSONを使用し、再度NSJSONSerializationで生dataを解析するSwiftyJSONを使用することは非効率的です。個人的には、私はSwiftyJSONを気にしませんが、使用したい場合は、Alamofireのresponseメソッド(responseJSON)を使用することをお勧めします。 JSONを2回解析する必要はありません。

+0

ご回答いただきありがとうございます。私が理解していないことは、 'dispatch_group_notify(group、dispatch_get_main_queue()){ //こちらの次の反復に行く }'次の反復を進めるにはどうすればいいですか? – user5855868

+0

それぞれの反復を独自のメソッドに持つことができるので、中括弧の中の次のメソッドを "ここで次の繰り返しに進む"というところで呼び出します。 – Rob

+0

あなたのコードから少し変更を加えましたが、今はうまくいきます。あなたの助けを借りてくれてありがとうRob。 – user5855868

関連する問題