web-dev-qa-db-ja.com

Alamofireを使用して同期リクエストを行う方法は?

Alamofireを使用して同期リクエストを実行しようとしています。 Stackoverflowを調べたところ、次の質問が見つかりました: 非同期のalamofireリクエストを同期させます

受け入れられた回答がcompletionを使用してAlamofireリクエストを同期させることを確認しましたが、機能させることができません。これは私の簡単なコードです:

_func loadData(completion: (Bool)) -> (Int, [String], [String], [String]){

    Alamofire.request(url!, method: .get, parameters: nil, encoding: JSONEncoding.default, headers: nil).responseJSON { response in

        switch(response.result) {
        case .success(_):
            if let JSON = response.result.value as! [[String : AnyObject]]!{
                 //Here I retrieve the data
            }

            completion(true)
            break

        case .failure(_):
            print("Error")
            completion(false)
            break  
        }
   }

   return (numberRows, nameArray, ageArray, birthdayArray)
}
_

このコードを使用すると、completion(bool value)を作成しようとするとエラーが発生します。私が得ているエラーは次のとおりです:

非関数型 'Bool'の値を呼び出すことはできません

補完を使用して値を同期的に取得する多くの例を使用してみました(テーブルに表示する前にデータを取得し、同時にそのテーブルの行数を取得する必要があるため)。

その完了を使用して同期応答を取得するにはどうすればよいですか?

前もって感謝します!

14

完了ハンドラを使用する場合は、returnを使用しないでください。

_func loadData(completion: @escaping (_ number: Int, _ strArr1: [String], _ strArr2: [String], _ strArr3: [String]) -> ()){

  Alamofire.request(url!, method: .get, parameters: nil, encoding: JSONEncoding.default, headers: nil).responseJSON { response in

    switch(response.result) {
    case .success(_):
        if let JSON = response.result.value as! [[String : AnyObject]]!{
            //Here I retrieve the data
        }
        completion(number: numberRows, strArr1 : nameArray, strArr2 : ageArray, strArr3: birthdayArray)
        break

    case .failure(_):
        print("Error")
        completion(number: numberRows, strArr1 : nameArray, strArr2 : ageArray, strArr3: birthdayArray)
        break
    }
  }
}

loadData (completion: { (number, strArr1, strArr2, strArr3) in
    // do it
    // for exapmple
    self.number = number
    self.strArr1 = strArr1
    // and so on

})
_

または、クロージャーで任意の値を返す場合は、任意の値を返すために完了ハンドラーを使用する必要があります。たとえば、ブール値を返す場合:

_func loadData(completion:(number: numberRows, strArr1 : nameArray, strArr2 : ageArray, strArr3: birthdayArray) -> (Bool))
_

loadData

_loadData( completion: { ( number, strArr1, strArr2, strArr3 ) -> (Bool) in
       # code 
       return False
})
_

または他の人が考える。

私はSwift 3.を使用していますが、Swiftの別のバージョンが必要な場合は、次のような外部パラメーター名と内部パラメーター名に注意してください:@escaping (_ number: Int, _ strArr1: [String], _ strArr2: [String], _ strArr3: [String]) -> ())

外部パラメーター名を設定したい場合は、___をドロップしてパラメーターの名前を設定するだけです。

4
Ali Zahedi

こちら に記載されている理由により、同期リクエストを行うことはAppleで強く推奨されていません。

この例では、呼び出しを簡略化しています。セルのコンテンツなどの詳細情報がある場合は、SwiftyJSONを確認してJSON Blob全体を返し、関連するメソッド(numberOfRowsなど)で解析することをお勧めします。)。

class TableViewJSONAsynchCalls: UIViewController, UITableViewDelegate, UITableViewDataSource {
    var tableView = UITableView()
    var numberOfRows = 0;

    override func viewDidLoad() {
        loadData { (didCompleteRequest) in
            if (didCompleteRequest) {
                tableView.delegate = self
                tableView.dataSource = self
                tableView.reloadData()
            } else {
                // Handle error if data was not loaded correctly
            }
        }
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return numberOfRows;
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        return UITableViewCell(style: UITableViewCellStyle.default, reuseIdentifier: "cell")
    }

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        print("selected")
    }

    func loadData(completion: (Bool) -> Void) {
        // Make asynchronous call using alamofire
        // This simulates you parsing the JSON and setting the relevant variables, 
        // personally I would recommend you return a JSON blob and then 
        // parse it in the relevant methods.
        sleep(2)
        // If call is successful
        self.numberOfRows = 10
        completion(true)

    }
}
1
FredLoh