APIで受け取った情報をTableviewのCellに貼り付けたいです。
以前はTestData1の形に変換して、Cellに渡そうと思っていたのですが、パースしたjsonをそのまま利用する方が好ましいとのアドバスを受け、
以下のように記述してみました。
実行するとエラーはでませんが、テーブルには何も表示されません。
swift
1import UIKit 2 3 4class TableViewController: UIViewController, UITableViewDataSource, UITableViewDelegate { 5 6 7 @IBOutlet weak var APPNAME: UILabel! 8 @IBOutlet weak var Change: UIButton! 9 @IBOutlet var ApprovalTableView: UITableView! 10 11 // 12 var TestData1 : [[String:String]] = [ 13 ["ID":"19540921","NAME":"安倍 晋三","DOCUCODE":"https://www.abcdefg.com/19540921"], 14 ["ID":"19400920","NAME":"麻生 太郎","DOCUCODE":"https://www.abcdefg.com/19400920"], 15 ["ID":"19630110","NAME":"河野 太郎","DOCUCODE":"https://www.abcdefg.com/19630110"] 16 ] 17 18 //送られてくるJSONに相当する構造体を準備する 19 struct JsonForm : Codable { 20 var ID : String 21 var NAME : String 22 var DOCUCODE : String 23 24 } 25 26 //ここが不安 27 var CellValue = [JsonForm]() 28 29 //ここからviewDidLoad 30 override func viewDidLoad() { 31 super.viewDidLoad() 32 33 // 34 ApprovalTableView.dataSource = self 35 ApprovalTableView.delegate = self 36 37 38 //APIへGET送信 39 let listUrl = "https://省略" 40 let APIurl = URL(string: listUrl)! 41 42 // 43 URLSession.shared.dataTask(with: APIurl) { (data, response, error) in 44 45 // 46 if (error == nil) { 47 // API通信成功 48 49 // 50 guard let data = data else { return } 51 52 // 53 do { 54 //パース:jsonはArray<JsonForm> 55 let json:[JsonForm] = try JSONDecoder().decode([JsonForm].self, from: data) 56 57 //変数に代入 58 self.CellValue = json 59 60 } catch { 61 62 print(error) 63 64 } 65 66 } else { 67 // API通信失敗 68 print("API NG") 69 70 } 71 72 }.resume() 73 74 } 75 76 //画面遷移させる時に値を渡す 77 override func prepare(for segue: UIStoryboardSegue, sender: Any? ) { 78 79 // 80 if let detailVC = segue.destination as? DetailViewController, let indexPath = sender as? IndexPath { 81 detailVC.message = CellValue[indexPath.row].DOCUCODE 82 83 } 84 85 } 86 87 //セクションの数 88 func numberOfSections(in tableView: UITableView) -> Int { 89 return 1 90 } 91 92 //セルの数 93 func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 94 //return TestData1.count 95 return CellValue.count 96 } 97 98 //セルに描写 99 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 100 let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath ) 101 102 //tag1 103 let Label1 = cell.viewWithTag(1) as? UILabel 104 //Label1?.text = TestData1[indexPath.row]["ID"] 105 Label1?.text = CellValue[indexPath.row].ID 106 107 //tag2 108 let Label2 = cell.viewWithTag(2) as? UILabel 109 //Label2?.text = TestData1[indexPath.row]["NAME"] 110 Label2?.text = CellValue[indexPath.row].NAME 111 112 //tag3 113 let Label3 = cell.viewWithTag(3) as? UILabel 114 //Label3?.text = TestData1[indexPath.row]["DOCUCODE"] 115 Label3?.text = CellValue[indexPath.row].DOCUCODE 116 117 // 118 return cell 119 120 } 121 122 //セルの高さを決める 123 func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { 124 return 100 125 } 126 127 //セルをタップした時 128 func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { 129 performSegue(withIdentifier: "MainToDetail", sender: indexPath) 130 131 } 132 133} 134
jsonを代入する変数の宣言の問題なのか、代入後の変数がスコープ範囲外なのか、代入後の変数の扱いが間違っているのかがわかりません。
基本的な何かが欠けていると思うのですが、ご教授お願い致します。
//変数に代入
self.CellValue = json
この下で
self.ApprovalTableView.reloadData()
では表示されませんか?
返信ありがとうございます。
真下に追記してみたところ、
self.CellValue = json
self.ApprovalTableView.reloadData()
実行すると紫色で UITableView.reloadData() must be used from main thread only となります。
そこで「メインスレッドからのみ使用」との意味のようなので、外しているかもしれませんが、resume()の次の行で実行してみましたが、エラーも出ず表示もされない状況です。
確認ありがとうございます!
非同期処理だとがすっかり抜けていました。申し訳ありません。
少し確認したいのですが、
同じ変数に代入の下に以下のような記述はできますでしょうか?
DispatchQueue.main.async {
self.ApprovalTableView.reloadData()
}
表示されました!!!
セルをタップした行の動作も問題なさそうです。
今、感動しています。
ありがとうございます。
追加のお願いで恐縮ですが、理解を深めておきたいのです。
この
DispatchQueue.main.async {
self.ApprovalTableView.reloadData()
}
を変数代入の直後に記述する事で内部的にどのような処理を行っているのかを解説頂けると助かります。
よかったです!
長くなりそうなので回答の方に記述させていただきます。
回答1件
あなたの回答
tips
プレビュー