2017-02-15 12 views
1

は、我々は基本的なHTTPリクエストを作成し、実行するために管理している:あなたはtask.responseが設定されるまで、我々はすでにビジー待つことに注意しましょうHTTPリクエストが完了するのを待つ方法を教えてください。 SO上でいくつかの答えを使用して

import Foundation 

let url:URL = URL(string: "http://jsonplaceholder.typicode.com/posts")! 
let session = URLSession.shared 

var request = URLRequest(url: url) 
request.httpMethod = "POST" 
let paramString = "data=Hello" 
request.httpBody = paramString.data(using: String.Encoding.utf8) 

let task = session.dataTask(with: request as URLRequest) { 
    (data, response, error) in 

    guard let data = data, let _:URLResponse = response, error == nil else { 
     print("error") 
     return 
    } 

    let dataString: String = String(data: data, encoding: String.Encoding.utf8)! 
    print("here") 

    print("Data: \(dataString)") 
    print("Response: \(response!)") 
} 

task.resume() 
while task.response == nil {} 
print("Done") 

。ただし、データも応答も印刷されず、hereのみが出力されます。

は包むものと無限の試行私たちはここに特異なバグを持っていることを決定し、このまたはそのようにした後:コードに何も変更しない、時々hereは、時には何も印刷されていない、と非常に、非常にまれdataString(おろかresponse)。

print("Done")の前にsleep(3)を挿入してみてください。

私たちはちょっと叫んだ(私は実際に何かを投げたかもしれない)、スウィフトを完全に放棄することについて簡単に考えたが、その後、教師のように正面に向かい、ここに投稿する。

明らかに、メインスレッドは、非同期タスク(スレッド?)がまだ実行中であるかどうかにかかわらず終了し、すべてのスポーンを強制終了します。そのことをどうやって防ぐか、それはスレッドに「参加」しますか?

ボーナス質問:アラモファイアはこれをカバーしていますか?マット・ギャラガーによってCwUtilsを使用して

+0

[密接に関連する質問](http://stackoverflow.com/questions/26784315/can-i-somehow-do-a-synchronous-http-request-迅速な通告)。 – Raphael

答えて

0

アクティブ待機がGCDの唯一の方法と思われます。標準ライブラリの材料を使用して、これはどのような作品です:

import Foundation 

<...> 

var done = false 

let task = session.dataTask(with: request as URLRequest) { 
    (data, response, error) in 

    <...> 
    done = true 
} 

task.resume() 

repeat { 
    RunLoop.current.run(until: Date(timeIntervalSinceNow: 0.1)) 
} while !done 
0

は、私が仕事をして、簡単なCountdownLatchを実装:

import Foundation 
import CwlUtils 

<...> 

let task = session.dataTask(with: request as URLRequest) { 
    (data, response, error) in 

    <...> 
    latch.countDown() 
} 

task.resume() 
latch.await() 
-1

最もストレートフォワード(および組み込みの)方法はDispatchSemaphoreを使用することが考えられます:

<...> 

let sem = DispatchSemaphore(value: 0) 

let task = session.dataTask(with: request as URLRequest) { 
    (data, response, error) in 

    <...> 
    sem.signal() 
} 

task.resume() 
sem.wait() 
+0

downvoterは、なぜこれが悪い解決策だと思うのか、理想的にはより良い選択肢を提示するのか説明してください。 – Raphael

+0

これは、非同期タスクが 'sem.signal()'の前にメインキュー(または 'sem.wait()'ブロック)に何かを送ると問題になります。私たちはデッドロックを持っています、[ここ](http://stackoverflow.com/q/42644111/539599)。 – Raphael

関連する問題