2016-10-24 12 views
1

私の目標は、Alamofireの準備ができたら、値を返すことです。 以下のスクリプトは私のシングルトンの一部で、私のviewControllerによって呼び出されます。私は周りを見渡して、完了ハンドラがAlamofireで実装されている場所の例があります。Alamofire Swift 3で配列の値を返す方法は?

シングルトン:

func getPeople() -> [Person] { 

    var persons:[Person] = [] 

    Alamofire.request(requestURL, method: .get, parameters: nil, encoding: URLEncoding.default, headers: nil).responseJSON { (response) in 
     if let json = response.result.value as? Dictionary<String, Any> { 

      for field in json { 
       // Reference to person class 
       let person = Person() 

       // Properties will be fill in 
       ... 
       ... 

       // Add properties to the person object 
       persons.append(person) 

      } 

     } 

    } 
    return persons 

} 

のViewController

私は私のViewController.swiftに機能上記の呼び出しと人の列に追加します。

var persons = [Person]() 

override func viewDidLoad() { 
    super.viewDidLoad() 

    let request = requestHandler() 
    self.persons = request.getPeople() 
} 

Alamofireはasynchroonになるので、私は人の配列を返さない。私のviewcontroller.swiftから呼び出される関数に値personsを返すにはどうすればよいですか?私はスイフト3を使用しています。

ありがとうございます。

答えて

1

あなたは、この目的のために閉鎖を使用する必要があります。

func getPeople(success: (([Person])->Void)?, failure: ((Error)->Void)?) { 
    //create Alamofire request 
    //if everything was fine call success block with people array passed into it 
    //if failure occurred, call failure block with error. 
    //In any case you must call either `success` of `failure` here 
} 

用途:

ServerManager.sharedInstance.getPeople(
      success: { people in 
       //use people here, update UI if needed 
      }, 
      failure: { error in 
       //show an error 
     }) 

をあなたが迅速hereで閉鎖についての詳細を読むことができますが、私はあなたについてのいくつかの説明を残します特別の場合:

基本的には(([Person])->Void)?はクロージャのタイプです。これは、クロージャがPersonオブジェクトの配列を受け入れ、何も返さないことを意味します(Void)。 ?は最後にはオプションのパラメータなので、getPeople関数を呼び出すときにはnilを渡すことができます。コールバックにはまったく興味がない場合は関数に渡すことができます。

((Error)->Void)?失敗閉鎖。それを呼び出す場合は、Errorオブジェクトを渡して、実際に何が問題になったのかを記述する必要があります。

なぜ閉鎖する必要がありますか?

たとえば、ユーザーの場所をサーバーに送信するためのエンドポイントがあります。場合によっては、要求が終了した後でコードを実行したい場合があります。失敗したかどうかは気にしません(バックグラウンドで座標を送信するだけです)。コールバックが必要ない場合は、空のクロージャーまたはnilを渡すことができます。実際には{ _ in }のような空のクロージャーを使用するのに間違いはありませんが、nilを渡すと少しきれいです。あなたにもいくつかのUIKit方法で、オプションのクロージャを満たすことができます。

present(_:animated:completion:)

animate(withDuration:animations:completion:)

P.S.それは好みの問題ですけれども、それは、より明白と読みやすいですので、私は2つのクロージャを好む個人的に

func getPeople(completionHandler: (([Person]?, Error?)->Void)?) {} 

:あなたはまた、2つのoptionalsと一つだけcompletionコールバックを持っているようにあなたの方法を設計することができます。

+0

succesとfailureパラメータで何が起こっているのか教えてください。リクエストがうまくいって失敗した場合はsuccesが呼び出されますが、 '(([People]) - > Void)?'と '((Error) - > Void)私にはっきり分かりません。 – Caspert

+0

@Caspert私はちょうどクロージャの詳細について答えを更新しました。 – alexburtnik

+0

説明をありがとう。私が理解していない唯一のものは、あなたが閉鎖に何も通らないのですか?そのための例がありますか?なぜなら、私がそれを理解すれば、Voidはデフォルトで何も返さないからです。 – Caspert

関連する問題