2017-11-03 4 views
0

私は、URLから受け取ったデータを保持する構造体を持っています。このコードはすべて、clubDictという辞書にデータを置くまでは問題なく動作しますが、tableViewにデータを表示すると、辞書のデータ数が取得されますが、表示されるのは1つのキーとその異なる値プロパティだけです繰り返す。辞書のすべてのデータをtableViewに取り込むにはどうすればよいですか?

struct Swifter: Codable { 

let id: String? 
let address: String? 

} 

class TableViewController: UITableViewController { 

var clubDict: [String: Swifter] = [:] 

override func viewDidAppear(_ animated: Bool) { 
    super.viewDidAppear(animated) 

    let locationDict: Dictionary<String, Any> = ["latitude" : 53.444101, "longitude" : -2.192934] 

    let json = ["location" : locationDict] as [String : Any] 
    guard let clubLocatorURL = URL(string: "https://us-central1-geofire-46ce2.cloudfunctions.net/Club-Locator") else { return } 

    var request = URLRequest(url: clubLocatorURL) 
    request.httpMethod = "POST" 
    guard let httpBody = try? JSONSerialization.data(withJSONObject: json, options: .prettyPrinted) else { return } 
    request.addValue("application/json", forHTTPHeaderField: "Content-Type") 
    request.httpBody = httpBody 

    let session = URLSession.shared 

    session.dataTask(with: request) { (data, response, error) in 

     if let response = response { 
      print("Response: \(response)") 
     } 
     if let data = data { 
      do { 
       let decoder = JSONDecoder() 
       self.clubDict = try decoder.decode([String: Swifter].self, from: data) 

       DispatchQueue.main.async { 
        self.tableView.reloadData() 

       } 

      } catch { 

       print("error: \(error)") 
      } 
     } 
     }.resume() 
} 

override func viewDidLoad() { 
    super.viewDidLoad() 
} 

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 
    return clubDict.count 
} 

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 
    let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) 

for (key, value) in clubDict { 
    cell.textLabel?.text = key 
    cell.detailTextLabel?.text = value.address 

} 

    return cell 
} 
} 
+0

あなたの方法は、テーブルにデータを表示するには間違っています。 'cellForRowAt'はインデックスパス(indexPath'パラメータ)ごとに1回、複数回呼び出されます。通常、データソースとして配列が使用されます。インデックスパスのオブジェクトを配列から取得し、データを表示するはずです。 – vadian

答えて

2

tableViewが順番に表示されます。辞書は発注されていません。 "for(key、value)in clubDict"で辞書をルーピングすると、表示される辞書の最後のエントリだけが表示されます。

あなたがしなければならないことは、順序付けられていない辞書を配列のような順序付けられた形式にすることです。そのような例:

let dict = ["key1" : "value1"]; // Your dictionary. Use the one you already have 
var arr : [(String, String)] = []; 
for (key, value) in dict { 
    arr.append((key, value)); 
} 

は、その後、あなたは今cellForRowAtIndexPathメソッドが呼び出される各セルについてarr.count

使用する「numberOfRowsInSection」方法を調整する必要があります。 がありますが、そのインデックスによって配列から正しいエントリを抽出します。

let (key, value) = arr[indexPath.row]; //read element for the desired cell 
cell.textLabel?.text = key 
cell.detailTextLabel?.text = value.address 

あなたは、あなたのニーズにデータ型を調整する必要があります。私はちょうど文字列の辞書を取った:文字列

+0

データを並べ替えて辞書にロードすると、それは注文されますか? –

+0

ディクショナリと同じではありませんが、インデックスを持つ配列のような構造を表していません。 「私は辞書の最初の要素がほしい」と言うことはできません。それはどれでしょうか?キーがアルファベット順に一番小さいものは?キーが別のオブジェクトの場合はどうなりますか? セットと同じように、辞書は単なる「雲」です。彼らの "索引"は彼らの鍵です。 – TMob

+0

私を許してください、しかし私はあなたが間違っていると思います。 –

関連する問題