2016-11-02 6 views
1
public func dataTaskWithRequest(request: NSURLRequest, completionHandler: (NSData?, NSURLResponse?, NSError?) -> Void) -> NSURLSessionDataTask 

私は上記の使用方法を知っています。dataTaskWithRequestメソッドはどこで使用されていますか?

public func dataTaskWithRequest(request: NSURLRequest) -> NSURLSessionDataTask 

しかし、この方法の使い方は?私はそれがどのように使用されているのか混乱しています。私が見るすべての例は、最初の方法を使用しています。このメソッドはデータを返さず、処理するエラーも応答も返しません。または、これを何らかの形でエンベロープとしてエンベロープし、後でキューで実行するということですか?

答えて

2

カスタムNSURLSessionの代理人を指定した場合、後者の方法を使用します。データはクロージャに返されませんが、セッションで代理人のdidReceiveDataが呼び出されます。これは個別に実装する必要があります。

デリゲートメソッドを実装するにはもっと多くの作業が必要です。したがって、絶対に必要な場所でのみ行う必要があります(たとえば、すべてのデータが入るのを待つのではなく、リダイレクトやチャレンジのカスタム処理のためのデリゲートメソッドが必要であり、データタスクではなくダウンロードまたはアップロードタスクを伴う背景NSURLSessionなど)を実行する必要があります。


例えば、JSONレスポンスを期待し、シンプルなGETリクエストを発行するために、必要に応じて、URLSessionTaskDelegateは(客観的に、それぞれ、NSURLSessionDelegateNSURLSessionDataDelegateNSURLSessionTaskDelegateと呼ばれ、URLSessionDelegateURLSessionDataDelegateに準拠するように、あなたのクラスを定義し、かもしれません-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)") 
    } 
} 

さらに複雑なデリゲートメソッドが必要な場合を除いて、これを行うことはできませんが、ミニマリスト実装を示したいと思います(補完ハンドラのレンディションに感謝します)。完了ハンドラに直接

+1

更新された回答ありがとうございました – Honey

+0

** 1)**ライブストリームは、「入ってくるデータを処理する」という良い例ですか? ** 2)**単一のクラスで複数のタスクを持つのは少し難しいでしょうか?つまり、各デリゲートメソッドでifステートメントを使用し続ける必要があります。 ** 3)** 'DidReceiveData'メソッドは基本的には*のようにタスクを消費するだけです。*' didCompleteWithError'は完了後に何をするのですか? ** 4)** "あなたのデータを処理したい" < - そのようにすると、 'DidReceiveData'の権利になりますか? – Honey

+1

1.はい、ストリーミングプロトコルは良い例ですが、非常に頻繁に行う必要はありません。 2.単一のクラスで複数のリクエストを処理するのは難しいことではありませんが、完了ハンドラのパターンよりもはるかに面倒です。 3。そうです、それは一般的なパターンです。データを 'didReceiveData'で取得します(' Data'オブジェクトに付加するか 'OutputStream'に追加する)し、' didComplete'で後処理を開始します。はい。 – Rob

1
public func dataTaskWithRequest(request: NSURLRequest, completionHandler: (NSData?, NSURLResponse?, NSError?) -> Void) -> NSURLSessionDataTask 
data

戻り、responseerror


public func dataTaskWithRequest(request: NSURLRequest) -> NSURLSessionDataTask 

URLSessionDataDelegateプロトコルと共に使用されます。いくつかのメソッドを実装する必要があります。いくつかの段階の間に、データを処理するためにデリゲートメソッドが呼び出されます。

プロトコルメソッドは、資格情報要求とリダイレクト制御を処理するなど、ロードプロセスをより細かく制御します。

+0

完了ハンドラなしでそれを行う利点は何ですか? – Honey

+1

私はちょうど答えを更新しました。 – vadian

関連する問題