2016-03-22 11 views
0

JSONを返すAPIを呼び出すフレームワークがあります。問題は、NSURLSessionを使用し、DataTaskWithRequestを呼び出してデータを取得するSDK内の関数があることです。問題は、私の関数は、データが適切にフェッチされる前でも値を返すことです。 DataTaskWithRequestでCompletion Handlerを使用しようとしましたが、現在、whileループを使用してデータを受信するまで待機しています。 、それは委任とプロトコルを使用してiOSのdataTaskWithRequestからデータを返すSwift

コード

public func getDetails() -> AnyObject { 
    if Reachability.isConnectedToNetwork() 
    { 
     received = false 
     let baseUrl = "API_URL Here" 
     let url = NSURL(string: baseUrl) 
     let request = NSURLRequest(URL: url!) 
     let session = NSURLSession.sharedSession() 

     print("Starting the connection") 
     let task = session.dataTaskWithRequest(request, completionHandler : { 
      (data, response, error) in 

      //Proper JSON Form 

      do 
      { 
       self.JSON = try NSJSONSerialization.JSONObjectWithData(data!, options: .AllowFragments) 
      } 
      catch 
      { 
       print("Error") 
       return 
      } 

      self.received = true 

     }) 
     task.resume() 

     print("Going through the loop") 
     while(!received) 
     { 
      print("Searching") 
     } 
     print(JSON) 
      return JSON 
    } 
    else 
    { 

     let alert = UIAlertView(title: "No Internet Connection", message: "Make sure your device is connected to the internet.", delegate: nil, cancelButtonTitle: "OK") 
     alert.show() 
     return 0 

    } 
} 
+0

あなたのコードを投稿してください... –

答えて

0

あなたの問題は、何かを非同期に同期しようとしていることです。擬似コードで要約すると、あなたはこれをやっている: -

let myData = getDetails(blah) 
doSomeAction(myData) 

それにアプローチする方法は、指標としての地位を完了ブロックを使用して非同期のすべてのものを作ることです。 このコードは

public typealias CompletionHandler = (success: Bool, message: String, json: JSON?, error: NSError?) -> Void 

func getDetailsAsync(completion: CompletionHandler) { 
    if Reachability.isConnectedToNetwork() 
    { 
     received = false 
     let baseUrl = "API_URL Here" 
     let url = NSURL(string: baseUrl) 
     let request = NSURLRequest(URL: url!) 
     let session = NSURLSession.sharedSession() 

     print("Starting the connection") 
     let task = session.dataTaskWithRequest(request, completionHandler : { 
      (data, response, error) in 

      //Proper JSON Form 
      if error != nil { 
       completion(false, "error", nil, error) 
      } 
      else { 
       do 
       { 
        self.JSON = try NSJSONSerialization.JSONObjectWithData(data!, options: .AllowFragments) 
        completion(true, "OK", self.JSON, nil) 
       } 
       catch 
       { 
        print("Error") 
        completion(false, "JSON parsing failed", nil, nil) 
       } 
      } 

     }) 
     task.resume() 
    } 
    else { 
     completion(false, "No network", nil, nil) 
    } 
} 

をテストされていない。このようにそれを呼び出します。

getDetailsAsync() { 
    (success, message, json, error) in 
    if success == true { 
     print(json) 

    } 
    else { 
     // Do your alert here 
     print(message) 
     print(error) 
    } 
} 

This答えは役に立つかもしれません。

+0

ありがとう!私の問題を解決した –

0

はい行うプロセスを監視し、それはあなたのプロトコルを通してメッセージを送信するために取得するために別のスレッドを使用するために、他の可能な方法はあります。

newQueue = NSOperationQueue() 

    let operation2 = NSBlockOperation(block: { 


     }) 

    operation2.completionBlock = { 
     print("Operation 2 completed") 
    } 

    let operation1 = NSBlockOperation(block: { 


     }) 

    operation1.completionBlock = { 

     self.newQueue.addOperation(operation2) 
    } 

    operation1.qualityOfService = .UserInitiated 
    newQueue.addOperation(operation1) 
} 

ここにコードの概要を示します。つまり、ブロック1でセッションを開始し、完了したらブロック2でダウンロードの検証を開始します。ブロック1はブロック2が完了したらブロック2を起動しますが、ブロック1で完了したデータ構造がダウンロードされるまでブロック2は起動しません。

+0

すぐにスレッドに慣れていないともう少し説明できます –

+0

これはまっすぐ進むSinghです。私がここでやっているのは、もはや上から下に流れることのないコードを書くことですが、op1からop2までです。 addOperationはop1を開始し、完了すると完了ブロックを起動し、次に実行されたoperation2を追加して完了ブロックを起動します。オペレーション1でセッションを開始し、オペレーション2で稼働していることを確認したらその完了を監視できます。 – user3069232

+0

ここでのサービス品質は、上記のプロセスの優先順位をIOSに伝えるための迅速な2.0機能です。だから、ここでは、単純に監視と操作が1〜2ノッチ高く、サービスの品質をチェックするのがNSOperationsであれば、ここでは操作2をできるだけ低くします。 – user3069232

関連する問題