使用Swift解析JSON

马克·泰尔斯

我在一个自定义类中有一个异步方法,该方法返回一个包含字典的NSArray。我试图在UITableView中显示此数据。一个问题是getGenres方法调用是异步的,因此在显示表后将加载数据。主要问题是弄清楚如何实现这三种数据源方法。在目标C中,这是如此简单...

var genreList:NSArray?

override func viewDidLoad() {
    super.viewDidLoad()
    Bookshop.getGenres {
        genres in
            self.genreList = genres // copies data to the public NSArray
            self.tableView.reloadData() // this returns the data async so need to reload the tableview
            println("records: \(self.genreList?.count)") // displays the array of dictionaries correctly
    }
}

// #pragma mark - Table view data source

override func numberOfSectionsInTableView(tableView: UITableView!) -> Int {
    return 1
}

override func tableView(tableView: UITableView!, numberOfRowsInSection section: Int) -> Int {
    if self.genreList != nil {
        println("Rows in section: \(self.genreList?.objectAtIndex(0))")
        return self.genreList?.count! // Value of optional 'Int?' not wrapped; did you mean to use '!' 
    }
    return 3
}

override func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell? {
    let cell:UITableViewCell = tableView.dequeueReusableCellWithIdentifier("GenreCell", forIndexPath: indexPath) as UITableViewCell
    cell.textLabel.text = "Hello World!"
    println("ROW: \(indexPath.row)")
    println("data: \(self.genreList?.objectAtIndex(indexPath.row))")
    var item = self.genreList?.objectAtIndex(indexPath.row) Variable 'item' inferred to have type 'AnyObject?', which may be unexpected.
    //cell.textLabel.text = item.title
    //var item:NSDictionary = self.genreList?.objectAtIndex(indexPath.row) as NSDictionary
    //println("item: \(item)")
    return cell
}

我究竟做错了什么?做一件真正简单的任务似乎不必要地复杂。

这是我的实用程序类:

import Foundation

class Bookshop {
    class func getGenres(completionHandler: (genres: NSArray) -> ()) {
        //println("Hello inside getGenres")
        let urlPath = "http://creative.coventry.ac.uk/~bookshop/v1.1/index.php/genre/list"
        //println(urlPath)
        let url: NSURL = NSURL(string: urlPath)
        let session = NSURLSession.sharedSession()
        var resultsArray:NSArray!
        let task = session.dataTaskWithURL(url) {
            data, response, error in
            //println("Task completed")
            if(error) {
                println(error.localizedDescription)
            }
            //println("no error")
            var err: NSError?
            var options:NSJSONReadingOptions = NSJSONReadingOptions.MutableContainers
            var jsonResult = NSJSONSerialization.JSONObjectWithData(data, options: options, error: &err) as NSDictionary
            if(err != nil) {
                println("JSON Error \(err!.localizedDescription)")
            }
            //NSLog("jsonResults %@", jsonResult)
            let results: NSArray = jsonResult["genres"] as NSArray
            //NSLog("jsonResults %@", results)
            //resultsArray = results
            //println("calling completion handler")
            completionHandler(genres: results)
        }
        task.resume()
    }
}
戴维·贝里

swift所做的只是消除了我们实际上不应该依赖的一堆容易出错的功能,特别是依赖于设置为零的消息总是容易出错。现在,它有点冗长,但明显得多,因此很安全。

return self.genreList.countObjective-C中的等效项是:

override func tableView(tableView: UITableView!, numberOfRowsInSection section: Int) -> Int {
    if let genres = self.genreList {
        return genres.count
    }
    else {
        // Note: this is the case when you haven't yet downloaded your genre
        //  list, do whatever is appropriate, this just shows an empty list
        return 0
    }
}

由于cellForRowAtIndexPath仅当单元格计数为非零时才调用该方法,因此该方法更为简单,但实际上出于一致性/安全性考虑,您遵循相同的一般流程:

override func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell? {
    if let genres = self.genreList as? [NSDictionary] {
        let cell:UITableViewCell = tableView.dequeueReusableCellWithIdentifier("GenreCell", forIndexPath: indexPath) as UITableViewCell
        var item = genres[indexPath.row]
        cell.textLabel.text = item["title"] as String
        return cell
    }
    else {
        // Note: again, this is the case where you don't have your genre list
        //  list yet, so you can create whatever default cells needed.
        return nil
    }
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章