15
18

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

SwiftyJSONとAlamofireとTableView。

15
Posted at

単純なんですけど、JSONを読み込んでその項目分のセクション、行数を作成するときにハマりました。

import UIKit
import SwiftyJSON
import Alamofire
class SearchViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
    var jsonURLString = "http://◯◯◯◯◯◯.json"
    // セクションのタイトル
    var sectionArray: NSMutableArray = []
    // 各要素
    var itemArray: NSMutableArray = []
    var sectionKosu: Int = Int()
    override func viewDidLoad() {
        super.viewDidLoad()
        // JSONのパース
        Alamofire.request(.GET, jsonURLString, parameters: nil, encoding: .JSON)
            .responseJSON { (request, response, responseData, error) -> Void in
                if let data: AnyObject = responseData {
                    let results = JSON(data)
                    let count: Int = results["responseData"]["feed"]["entries"].count
                    
                    for index in 0..<count {
                        // タイトルの抜き出し
                        let title = results["responseData"]["feed"]["entries"][index]["ttl"].string!
                        self.sectionArray.addObject(title)
                        
                        // セルの項目
                        let items: AnyObject = results["responseData"]["feed"]["entries"][index]["item"].rawValue
                        self.itemArray.addObject(items)
                    }
                    let barHeight: CGFloat = UIApplication.sharedApplication().statusBarFrame.size.height
                    let displayWidth: CGFloat = self.view.frame.width
                    let displayHeight: CGFloat = self.view.frame.height
                }
        }
        let myTableView: UITableView = UITableView(frame: CGRect(x: 0, y: 140 + barHeight, width: displayWidth, height: displayHeight - (140 + barHeight)))
        myTableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: "MyCell")
        myTableView.dataSource = self
        myTableView.delegate = self
        self.view.addSubview(myTableView)
   }
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
    // セクションごとの行数を返す
    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return self.itemArray[section].count
    }
    // 各行に表示するセルを返す
    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCellWithIdentifier("MyCell", forIndexPath: indexPath) as! UITableViewCell
        // セルに表示するテキストを設定
        cell.textLabel?.text = "セル" + (indexPath.row).description
        cell.detailTextLabel?.text = "サブタイトル"
        return cell
    }
    // セクション数
    func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        return self.sectionArray.count
    }
    // セクションタイトル
    func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
        return sectionArray[section] as? String
    }
    func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
        println("セクション\(indexPath.section)のセル\(indexPath.row)が選択された")
    }
}

ざっとコードはこんな感じ。

// セクション数
    func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        return self.sectionArray.count
    }

JSONをパースしてからセクション数を決定するのですが、上記のコードでは必ずセクション数は0になります。
セクションのタイトルも無ければ行数も0。
何でかなー?とハマること数時間。。

何故かというと
パースしてる最中にテーブルを作成してしまっている
から。

self.view.addSubview(myTableView)

これを書いている位置が悪かったわけで、

Alamofire.request(.GET, jsonURLString, parameters: nil, encoding: .JSON)
            .responseJSON { (request, response, responseData, error) -> Void in
                
                (中略)
                    self.view.addSubview(myTableView)
                }
                
        }

JSONデータを受け取って処理してからaddSubViewしないとダメ。
.responseJSON {} の中ですね。

import UIKit
import SwiftyJSON
import Alamofire
class SearchViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
    var jsonURLString = "◯◯◯◯◯◯.json"
    // セクションのタイトル
    var sectionArray: NSMutableArray = []
    // 各要素
    var itemArray: NSMutableArray = []
    var sectionKosu: Int = Int()
    override func viewDidLoad() {
        super.viewDidLoad()
        // JSONのパース
        Alamofire.request(.GET, jsonURLString, parameters: nil, encoding: .JSON)
            .responseJSON { (request, response, responseData, error) -> Void in
                if let data: AnyObject = responseData {
                    let results = JSON(data)
                    let count: Int = results["responseData"]["feed"]["entries"].count
                    for index in 0..<count {
                        // タイトルの抜き出し
                        let title = results["responseData"]["feed"]["entries"][index]["ttl"].string!
                        self.sectionArray.addObject(title)
                        // セルの項目
                        let items: AnyObject = results["responseData"]["feed"]["entries"][index]["item"].rawValue
                        self.itemArray.addObject(items)
                    }
                 self.sectionKosu = self.sectionArray.count
                    let barHeight: CGFloat = UIApplication.sharedApplication().statusBarFrame.size.height
                    let displayWidth: CGFloat = self.view.frame.width
                    let displayHeight: CGFloat = self.view.frame.height
                    let myTableView: UITableView = UITableView(frame: CGRect(x: 0, y: 140 + barHeight, width: displayWidth, height: displayHeight - (140 + barHeight)))
                    myTableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: "MyCell")
                    myTableView.dataSource = self
                    myTableView.delegate = self
                    self.view.addSubview(myTableView)
                }
        }
   }
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
    // セクションごとの行数を返す
    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return self.itemArray[section].count
    }
    // 各行に表示するセルを返す
    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCellWithIdentifier("MyCell", forIndexPath: indexPath) as! UITableViewCell
        // セルに表示するテキストを設定
        cell.textLabel?.text = "セル" + (indexPath.row).description
        cell.detailTextLabel?.text = "サブタイトル"
        return cell
    }
    // セクション数
    func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        return self.sectionArray.count
    }
    // セクションタイトル
    func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
        return sectionArray[section] as? String
    }
    func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
        println("セクション\(indexPath.section)のセル\(indexPath.row)が選択された")
    }
}

上から順番に処理してくれると思い込んでいたので、「あれ?」っとなったのですが、考えてみれば当たり前のことでした。

15
18
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
15
18

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?