简体   繁体   中英

Swift 2 - Loading data from an array into cells in UITableView

I have an array var previousSongs = [PreviousSong]() .

This array is populated with information in a function called getSongs() . I know that the information is being put correctly into the previousSongs array

I want to use the information in this array in a table.

override func viewDidLoad() {
    super.viewDidLoad()

    self.tableView.contentInset = UIEdgeInsetsMake(4,0,0,0);
    self.tableView.dataSource = self

    previousSongs = [PreviousSong(song: "NAME1", artist: "ARTIST1", time: "TIME1"), PreviousSong(song: "NAME2", artist: "ARTIST2", time: "TIME2"), PreviousSong(song: "NAME3", artist: "ARTIST3", time: "TIME3"), PreviousSong(song: "NAME4", artist: "ARTIST4", time: "TIME4"), PreviousSong(song: "NAME5", artist: "ARTIST5", time: "TIME5"), PreviousSong(song: "NAME6", artist: "ARTIST6", time: "TIME6"), PreviousSong(song: "NAME7", artist: "ARTIST7", time: "TIME7"), PreviousSong(song: "NAME8", artist: "ARTIST8", time: "TIME8"), PreviousSong(song: "NAME9", artist: "ARTIST9", time: "TIME9"), PreviousSong(song: "NAME10", artist: "ARTIST10", time: "TIME10"), ]
    getSongs()
    self.tableView.reloadData()

}

func getSongs() {

    let url = NSURL(string: "http://api.vicradio.org/songs/history?amount=10")!
    let request = NSMutableURLRequest(URL: url)

    let session = NSURLSession.sharedSession()
    let task = session.dataTaskWithRequest(request) { (data: NSData?, response: NSURLResponse?, error: NSError?) in

        if error != nil {
            return
        }

        let name = NSString(data: data!, encoding: NSUTF8StringEncoding) as! String
        var songName = ""
        var artistName = ""
        var quoteNumber = 0
        var braceNumber = 0

        for character in name.characters {

            if braceNumber % 2 == 0 && braceNumber != 0 {
                if songName != "" {
                    quoteNumber = 0
                    self.previousSongs.append(PreviousSong(song: songName, artist: artistName, time: "TIME"))
                    songName = ""
                    artistName = ""
                }
            }

            if character == "{" || character == "}" {
                braceNumber++
            }

            if character == "\"" {
                quoteNumber++
            }

            if quoteNumber == 3 && character != "\""  {
                artistName += String(character)
            } else if quoteNumber == 7 && character != "\"" {
                songName += String(character)
            }

        }
        dispatch_async(dispatch_get_main_queue()) { self.getSongs() }
    }
    if self.previousSongs.count == 10 {
        task!.cancel()
    } else {
        task!.resume()
    }
}

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = self.tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as UITableViewCell

    var song : PreviousSong
    song = previousSongs[indexPath.row]

    cell.textLabel?.text = song.song + " by " + song.artist
    cell.detailTextLabel?.text = "Played at " + song.time

    return cell
}

The table will display the hard-coded array ( [PreviousSong(song: "NAME1", artist: "ARTIST1", ...), but it will not load the information from the array after I update it in the getSongs() function.

How can this be fixed, so that when I update the array with actual information in the getSongs() function, the cells will reload with the proper information? (I've already tried using the reloadData() method.)

It definitely sounds like your problem is in the getSongs() function. Would you mind providing your implementation?

Off the top of my head, it is probable that at least one of these is occurring: previousSongs is being set to nil or empty in getSongs() , your number of rows data source method is not returning the correct number ( previousSongs.count ).

Edit: After looking at your code, why would you not have the getSongs() function return an array and then use the lazy keyword on your array - then call your getSongs() function in the instantiation of the previousSongs array? That way, there would be no need to reload the table on viewDidLoad() . Pretty sure the whole thing would work a lot better.

Replace:

dispatch_async(dispatch_get_main_queue()) {
    self.getSongs() 
}

With:

dispatch_async(dispatch_get_main_queue()) { 
    self.tableView.reloadData() 
}

There's no reason that you should be calling getSongs() inside of getSongs() . You want to reload the table with reloadData() after the data has been processed. reloadData() in viewDidLoad does not execute after the data has been completely processed.

Here is one solution that I found!

Instead of appending to the array in getSongs() , use the .insert method. I think appending was adding the information I wanted to the end of the array. The data was being loaded correctly, but it wasn't the data I wanted.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM