カスタムNSURLSession
の代理人を指定した場合、後者の方法を使用します。データはクロージャに返されませんが、セッションで代理人のdidReceiveData
が呼び出されます。これは個別に実装する必要があります。
デリゲートメソッドを実装するにはもっと多くの作業が必要です。したがって、絶対に必要な場所でのみ行う必要があります(たとえば、すべてのデータが入るのを待つのではなく、リダイレクトやチャレンジのカスタム処理のためのデリゲートメソッドが必要であり、データタスクではなくダウンロードまたはアップロードタスクを伴う背景NSURLSession
など)を実行する必要があります。
例えば、JSONレスポンスを期待し、シンプルなGETリクエストを発行するために、必要に応じて、URLSessionTaskDelegate
は(客観的に、それぞれ、NSURLSessionDelegate
、NSURLSessionDataDelegate
とNSURLSessionTaskDelegate
と呼ばれ、URLSessionDelegate
、URLSessionDataDelegate
に準拠するように、あなたのクラスを定義し、かもしれません-Cとスウィフト2)、その後、スウィフト3で、次のような何か:スウィフト2に、
var responseData: Data?
func performRequest() {
let url = URL(string: "http://ip.jsontest.com/")!
var request = URLRequest(url: url)
request.setValue("application/json", forHTTPHeaderField: "Accept")
let configuration = URLSessionConfiguration.default
let session = URLSession(configuration: configuration, delegate: self, delegateQueue: nil)
responseData = Data()
let task = session.dataTask(with: request)
task.resume()
}
func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data) {
responseData!.append(data)
}
func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) {
guard error == nil else {
print(error!)
return
}
do {
guard let jsonObject = try JSONSerialization.jsonObject(with: responseData!) as? [String: AnyObject] else {
print("response was not JSON dictionary")
print("responseString: \(String(data: responseData!, encoding: .utf8))")
return
}
print(jsonObject)
} catch let parseError {
print("JSON Error: \(parseError)")
}
}
をまたは:
var responseData: NSMutableData?
func performRequest() {
let url = NSURL(string: "http://ip.jsontest.com/")!
let request = NSMutableURLRequest(URL: url)
request.setValue("application/json", forHTTPHeaderField: "Accept")
let configuration = NSURLSessionConfiguration.defaultSessionConfiguration()
let session = NSURLSession(configuration: configuration, delegate: self, delegateQueue: nil)
responseData = NSMutableData()
let task = session.dataTaskWithRequest(request)
task.resume()
}
func URLSession(session: NSURLSession, dataTask: NSURLSessionDataTask, didReceiveData data: NSData) {
responseData!.appendData(data)
}
func URLSession(session: NSURLSession, task: NSURLSessionTask, didCompleteWithError error: NSError?) {
guard error == nil else {
print(error!)
return
}
do {
guard let jsonObject = try NSJSONSerialization.JSONObjectWithData(responseData!, options: []) as? [String: AnyObject] else {
print("response was not JSON dictionary")
print("responseString: \(String(data: responseData!, encoding: NSUTF8StringEncoding))")
return
}
print(jsonObject)
} catch let parseError {
print("JSON Error: \(parseError)")
}
}
を
さらに複雑なデリゲートメソッドが必要な場合を除いて、これを行うことはできませんが、ミニマリスト実装を示したいと思います(補完ハンドラのレンディションに感謝します)。完了ハンドラに直接
出典
2016-11-02 18:55:06
Rob
更新された回答ありがとうございました – Honey
** 1)**ライブストリームは、「入ってくるデータを処理する」という良い例ですか? ** 2)**単一のクラスで複数のタスクを持つのは少し難しいでしょうか?つまり、各デリゲートメソッドでifステートメントを使用し続ける必要があります。 ** 3)** 'DidReceiveData'メソッドは基本的には*のようにタスクを消費するだけです。*' didCompleteWithError'は完了後に何をするのですか? ** 4)** "あなたのデータを処理したい" < - そのようにすると、 'DidReceiveData'の権利になりますか? – Honey
1.はい、ストリーミングプロトコルは良い例ですが、非常に頻繁に行う必要はありません。 2.単一のクラスで複数のリクエストを処理するのは難しいことではありませんが、完了ハンドラのパターンよりもはるかに面倒です。 3。そうです、それは一般的なパターンです。データを 'didReceiveData'で取得します(' Data'オブジェクトに付加するか 'OutputStream'に追加する)し、' didComplete'で後処理を開始します。はい。 – Rob