JSON到UITableView Swift 4最近播放了歌曲

时间:2018-03-05 02:49:15

标签: ios json swift uitableview

我对编码仍然很陌生,所以请放轻松。我遇到的问题是我正在尝试将我最近播放的歌曲添加到我的电台的应用程序中。我添加了一个tableviewcontroller并添加了单元格。单元格设置有专辑封面(封面),歌曲标题(标题)和歌曲艺术家(艺术家)。我只是坚持把JSON信息放到我的手机中。这是我的JSON数据的样子。任何帮助表示赞赏。感谢

我改变了这一行:

guard let urlText = URL (string: "http://streamdb3web.securenetsystems.net/player_status_update/JACKSON1_history.txt")

到这一行:

guard let urlText = URL (string: currentStation.longDesc)

这是我得到的错误:线程1:致命错误:在展开可选值时意外发现nil

1 个答案:

答案 0 :(得分:0)

正如@nayem所说,最好通读一些教程来了解解析JSON以及如何处理你的回复。

以下是我刚刚复制JSON数据并在MainBundle中创建JSON文件的示例:

//---------------------
//MARK: Your CustomCell
//---------------------

class YourCell: UITableViewCell{

@IBOutlet var songTitle: UILabel!
@IBOutlet var artistLabel: UILabel!
@IBOutlet var songCover: UIImageView!
}

//----------
//MARK: JSON
//----------

//The Initial Response From The JSON
struct Response: Codable {

var playHistory: Album


}

//The Album Received Which Is An Array Of Song Data
struct Album: Codable {
var song: [SongData]

}

//The SongData From The PlayHistory Album
struct SongData: Codable{

var album: String
var artist: String
var cover: String
var duration: String
var programStartTS: String
var title: String

}

//-----------------
//MARK: UITableView
//-----------------

extension ViewController: UITableViewDataSource{


func numberOfSections(in tableView: UITableView) -> Int {
    return 1
}

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


   override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    //1. Create A Cell
    let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! YourCell

    //2. Set It's Text
    cell.songTitle.text = songs[indexPath.row].title
    cell.artistLabel.text = songs[indexPath.row].artist

    //3. Get The Image
    if let imageURL = URL(string: songs[indexPath.row].cover){

        let request = URLSession.shared.dataTask(with: imageURL) { (imageData, response, error) in

            if let error = error{

                print(error)

            }else{

                guard let image = imageData else { return }

                DispatchQueue.main.async {
                    cell.songCover.image = UIImage(data: image)
                    cell.setNeedsLayout()
                    cell.layoutIfNeeded()
                }

            }
        }


        request.resume()
    }

    return cell

}

extension ViewController: UITableViewDelegate{

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

    print("""
        **Album \(indexPath.row) Selected**
        Album = \(songs[indexPath.row].album)
        Artist = \(songs[indexPath.row].artist)
        Cover = \(songs[indexPath.row].cover)
        Duration = \(songs[indexPath.row].duration)
        Start = \(songs[indexPath.row].programStartTS)
        Title = \(songs[indexPath.row].title)
        """)
   }

  }

class ViewController: UIViewController {

//1. Create An Array To Store The SongData
var songs = [SongData]()

//2. Create A UITableView As An IBOutlet
@IBOutlet var albumTableView: UITableView!

override func viewDidLoad() { super.viewDidLoad()

    albumTableView.delegate = self
    albumTableView.dataSource = self

    //2. Load The JSON From The URL
    guard let urlText = URL(string:"https://streamdb3web.securenetsystems.net/player_status_update/JACKSON1_history.txt") else { return }

    do{
        //a. Get The Data From The From The File
        let data = try Data(contentsOf: urlText)

        //b. Decode The Data To Our Structs
        let albumData = try JSONDecoder().decode(Response.self, from: data)

        //c. Append The Songs Array With The PlayHistory
        albumData.playHistory.song.forEach { songs.append($0) }

        //d. Test Some Data
        print("""
            **The First Album Details**
            Album = \(songs[0].album)
            Artist = \(songs[0].artist)
            Cover = \(songs[0].cover)
            Duration = \(songs[0].duration)
            Start = \(songs[0].programStartTS)
            Title = \(songs[0].title)
        """)

        //3. Load The Data
        DispatchQueue.main.async {
            self.albumTableView.reloadData()
        }
    }catch{

        print(error)
    }

   }
}

<强>更新 使用UITableViewController中的示例:

//---------------------
//MARK: Your CustomCell
//---------------------

class YourCell: UITableViewCell{

@IBOutlet var songTitle: UILabel!
@IBOutlet var artistLabel: UILabel!
@IBOutlet var songCover: UIImageView!

}

//----------
//MARK: JSON
//----------

//The Initial Response From The JSON
struct Response: Codable {

var playHistory: Album

}

//The Album Received Which Is An Array Of Song Data
struct Album: Codable {
var song: [SongData]

}

//The SongData From The PlayHistory Album
struct SongData: Codable{

var album: String
var artist: String
var cover: String
var duration: String
var programStartTS: String
var title: String
}


class ViewController: UITableViewController {

//1. Create An Array To Store The SongData
var songs = [SongData]()

override func viewDidLoad() { super.viewDidLoad()


    self.tableView.delegate = self
    self.tableView.dataSource = self

    //2. Load The JSON From The Main Bundle

    guard let urlText = URL(string:"https://streamdb3web.securenetsystems.net/player_status_update/JACKSON1_history.txt") else { return }


    do{
        //a. Get The Data From The From The File
        let data = try Data(contentsOf: urlText)

        //b. Decode The Data To Our Structs
        let albumData = try JSONDecoder().decode(Response.self, from: data)

        //c. Append The Songs Array With The PlayHistory
        albumData.playHistory.song.forEach { songs.append($0) }

        //d. Test Some Data
        print("""
            **The First Album Details**
            Album = \(songs[0].album)
            Artist = \(songs[0].artist)
            Cover = \(songs[0].cover)
            Duration = \(songs[0].duration)
            Start = \(songs[0].programStartTS)
            Title = \(songs[0].title)
            """)

        //3. Load The Data
        DispatchQueue.main.async {
            self.tableView.reloadData()
        }
    }catch{

        print(error)
    }

}

//-----------------
//MARK: UITableView
//-----------------


override func numberOfSections(in tableView: UITableView) -> Int {
    return 1
}

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


override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    //1. Create A Cell
    let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! YourCell

    //2. Set It's Text
    cell.songTitle.text = songs[indexPath.row].title
    cell.artistLabel.text = songs[indexPath.row].artist

    //3. Get The Image
    if let imageURL = URL(string: songs[indexPath.row].cover){

        let request = URLSession.shared.dataTask(with: imageURL) { (imageData, response, error) in

            if let error = error{

                print(error)

            }else{

                guard let image = imageData else { return }

                DispatchQueue.main.async {
                    cell.songCover.image = UIImage(data: image)
                    cell.setNeedsLayout()
                    cell.layoutIfNeeded()
                }

            }
        }


        request.resume()
    }

    return cell

}


override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

    print("""
        **Album \(indexPath.row) Selected**
        Album = \(songs[indexPath.row].album)
        Artist = \(songs[indexPath.row].artist)
        Cover = \(songs[indexPath.row].cover)
        Duration = \(songs[indexPath.row].duration)
        Start = \(songs[indexPath.row].programStartTS)
        Title = \(songs[indexPath.row].title)
        """)
   }

  }