原因
共有されたdataTaskのスレッドからの呼び出しでDispatchSemaphoreを使っているため(URLSession.sharedなど)。参考にしたサイトは下記。この実装だとURLSession.sharedを使ってスレッドを共有したときに処理が返って来ない。
上手く動かない例
import Foundation
extension URLSession {
func sync(with request:URLRequest) -> (data:Data?, response:URLResponse?, error:Error?) {
let semaphore = DispatchSemaphore(value: 0)
var _dat : Data?
var _res : URLResponse?
var _err : Error?
self.dataTask(with: request) { dat, res, err in
_dat = dat; _res = res; _err = err
semaphore.signal()
}.resume()
_ = semaphore.wait(timeout: .distantFuture)
return (_dat, _res, _err)
}
}
let request = URLRequest(url:URL(string:"https://developer.apple.com/swift/")!)
URLSession.shared.dataTask(with: request) { data, response, error in
let result = URLSession.shared.sync(with:request)
let dataString = String(describing: NSString(data: result.data!, encoding: String.Encoding.utf8.rawValue))
print(dataString)
}.resume()
解決策
別スレッドを使う。
URLSession.shared.dataTask(with: request) { data, response, error in
let session = URLSession(configuration: .default)
let result = session.sync(with:request)
let dataString = String(describing: NSString(data: result.data!, encoding: String.Encoding.utf8.rawValue))
print(dataString)
}.resume()
URLSesssion.sharedについての説明はこちら。The singleton shared session (which has no configuration object) is for basic requests. It is not as customizable as sessions that you create, but it serves as a good starting point if you have very limited requirements. You access this session by calling the shared() class method. See that method’s discussion for more information about its limitations.考えてみれば当然ちゃ当然の動きだけど、てっきりdataTaskが非同期という認識があったため原因特定に時間がかかった。備忘録として書いておく。
0 件のコメント:
コメントを投稿