2017-01-20 5 views
0

私はこの長い関数をAPI呼び出しの束にして、データを解析し、視察場所の束を表す2つの配列を返します(1つの配列は緯度を1つ緯度を保持する)。私が抱えている問題は、2つの配列がポピュレートされた時点を判断することです。理想的には、私はどこでも私はprint文を置くしかし、私は0の配列数のいずれかを取得する私のコードでSwift - API呼び出しのトラブル/ CompletionHandler/URLSessions

print("ArrayCount = \(self.latArray.count)") 

どこかに置いて、ArrayCount = 123を読んコンソールで単一のprint文を受信できるようにしたいと思いますまたは追加されたときに値のループが印刷されます(1..2..3 .. ... .. 123)。前もって感謝します!

func someFunction() 
{ 
    let url:URL = URL(string: "...") 

    let task = URLSession.shared.dataTask(with: URLRequest(url: url)) 
    { 
     data, response, error in 

     if error != nil 
     { 
      print("ERROR IN API REQUEST: \(error!.localizedDescription)") 
     } 

     else 
     { 
      do 
      { 
       if let parsedData = try JSONSerialization.jsonObject(with: data!, options: .allowFragments) as? [String: Any] 
       { 
        if let layerOne = parsedData["one"] as? [String: Any] 
        { 
         if let layerTwo = layerOne["two"] as? [[String: Any]] 
         { 
          for layerThree in layerTwo 
          { 
           if let variableName = layerThree["value"] as? String 
           { 
            let innerUrl:URL = URL(string: "...")! 

            let innerTask = URLSession.shared.dataTask(with: URLRequest(url: innerUrl)) 
            { 
             data, response, error in 

             if error != nil 
             { 
              print("ERROR IN API REQUEST: \(error!.localizedDescription)") 
             } 

             else 
             { 
              do 
              { 
               if let parsedData = try JSONSerialization.jsonObject(with: data!, options: .allowFragments) as? [String: Any] 
               { 
                if let layerA = parsedData["A"] as? [String: Any] 
                { 
                 if let lat = layerA["Latitude"] as? String, let long = layerA["Longitude"] as? String 
                 { 
                  self.latArray.append(lat) 
                  self.longArray.append(lon) 
                 } 
                } 
               } 
              } 

              catch 
              { 
               print("ERROR IN JSON SERIALIZATION") 
              } 
             } 
            } 
            innerTask.resume() 
           } 
          } 
         } 
        } 
       } 
      } 

      catch 
      { 
       print("ERROR IN JSON SERIALIZATION") 
      } 
     } 
    } 

    task.resume() 
} 
+0

受信しているJSONのサンプルを提供できますか?このJSONを解析する方法は本当に奇妙に見えます。 – AdamPro13

+0

ランダムな任意の名前を使用するために、すべての変数とサブスクリプトを置き換えましたか?これはGoogle Places APIからのAPIレスポンスを解析しようとしているようですが、元のコードを投稿するだけではないのはなぜですか?そうすれば、他の人があなたの問題を助けやすくなります。 –

+0

'if'文ごとに複数の条件付きバインディングを行うことができます。あなたはこの狂った巣をすべて必要としません。 – Alexander

答えて

0

私はあなたが何をしようとしている正確にわからないんだけど、私はあなたの信じられないほど冗長なコードを間引いて、それを理解しようとした後、私は結論はあなただけ記録したいだろうということだと思います配列は内側のループの最後の反復の後にカウントされます。たとえば、次のように

の代わりにこれをやって:

if index == layerTwo.count - 1 //if this is our last inner loop 
{ 
    //print the array counts 
    print("Lat count: \(latArray.count)") 
    print("Long count: \(longArray.count)") 
} 

これは動作するはずです:あなたは緯度/経度の値は、このチェックを追加を追加した後、次にfor (index, layerThree) in layerTwo.enumerated()

for layerThree in layerTwo

は、これを行いますあなたの場合。しかし、私はコードの移植性と再利用性の欠如のために、これを実行することに完全に同意しません。さらに、無視されているかなりの数の良い言語構成があります。穏やかなネストされたif letブロックは、いくつかの良いguardステートメントで大幅に減らすことができました。さらに、キャッチブロックでエラーを処理していないと考えると、代わりにキャッチブロックを削除し、代わりにtry?を選択することもできます。物事を迅速に処理する方法の1つは、配列カウント印刷ロジックを別の場所で処理できるように、関数自体に補完ハンドラを含めることです。これはまだあなたの質問に基づいて、私は個人的に構築に多くの時間を置くべきであることを確認していないものの、多くの更に向上させることができ

func someFunction(completion: (([String], [String]) -> Void)?) 
{ 
    let url = URL(string: "...")! 
    var latArray: [String] = [] 
    var longArray: [String] = [] 

    let task = URLSession.shared.dataTask(with: URLRequest(url: url), 
     completionHandler: { (data, response, error) -> Void in 
      guard error == nil else 
      { 
       print("ERROR IN API REQUEST: \(error?.localizedDescription)") 
       return 
      } 

      guard let parsedData = try? JSONSerialization.jsonObject(with: data!, options: .allowFragments), 
       let parsedDict = parsedData as? [String: Any], 
       let layerOne = parsedDict["one"] as? [String: Any], 
       let layerTwo = layerOne["two"] as? [[String: Any]] else 
      { 
       print("JSON OBJECT DOES NOT MATCH EXPECTED PATTERN") 
       return 
      } 

      for (index, layerThree) in layerTwo.enumerated() 
      { 
       guard let _ = layerThree["value"] as? String else 
       { 
        print("Skip this iteration (I guess?)") 
        continue 
       } 

       let innerUrl = URL(string: "...")! 
       let innerTask = URLSession.shared.dataTask(with: URLRequest(url: innerUrl), 
        completionHandler: { (data, response, error) -> Void in 
         guard error == nil else 
         { 
          print("ERROR IN API REQUEST: \(error?.localizedDescription)") 
          return 
         } 

         guard let parsedData = try? JSONSerialization.jsonObject(with: data!, options: .allowFragments), 
          let parsedDict = parsedData as? [String: Any], 
          let layerA = parsedDict["A"] as? [String: Any], 
          let lat = layerA["Latitude"] as? String, 
          let long = layerA["Longitude"] as? String else 
         { 
          print("Something went wrong") 
          return 
         } 

         latArray.append(lat) 
         longArray.append(long) 

         if index == layerTwo.count - 1 //if this is our last inner loop 
         { 
          completion?(latArray, longArray) 
         } 
        } 
       ) 
       innerTask.resume() 
      } 
     } 
    ) 

    task.resume() 
} 

someFunction(completion: { (latArray, longArray) -> Void in 
    //print the array counts 
    print("Lat count: \(latArray.count)") 
    print("Long count: \(longArray.count)") 
}) 

:私は、私は物事をクリーンアップする方法をいくつかのサンプルコードが含まれますこれはあなたのためです。より読みやすく、再利用可能なコードを持つアプリケーションを構築するためのいくつかの方法を思いつくのが最もよいでしょう。

関連する問題