我需要解析一些JSON数据的帮助

时间:2019-10-21 15:07:33

标签: json swift xcode

我对解析json数据还很陌生,我试图从rss feed生成器中解析一些json数据,但是遇到了一个问题,我可以成功打印得到的数据,但无法保存数据到一个对象。

我浏览了大部分使用可解码/可编码的教程,但是我可以使用urlSession和jsonSerialization对象来满足我的需要。

class JSONSongs {

    // initialize song array...
    var songArray: [Song] = []

    func getSongs() {

        let jsonSongUrl = "https://rss.itunes.apple.com/api/v1/us/apple-music/top-songs/all/50/explicit.json"
        let songUrl = URL(string: jsonSongUrl) // convert string to usable url

        // start url session task with apple music api url...
            // we get some data(hopefully), a response code and an error(hoepfully not)
        let songTask = URLSession.shared.dataTask(with: songUrl!) { (data, response, error) in

            // checking for an error
            if error != nil {
                print(Error.self)
                print(error?.localizedDescription)
                return
            } else {

                // lets store our data in a variable
                if let content = data {
                    do {
                        // taking the json data and converting it so we can make objects
                        let json = try JSONSerialization.jsonObject(with: content, options: JSONSerialization.ReadingOptions.mutableContainers)
                        //print(json) // making sure data is present

                        // checking to see if our json data is there
                        guard let jsonOne = json as? [String: Any] else {
                            print("invalid operation!")
                            return
                        }

                        // accessing top root of the json file
                        if let feed = jsonOne["feed"] as? [String: Any] {
                            //print("it worked") // testing

                            // accessing the results array where the albums are stored
                                // there are arrays in the nested json data so we need the double brackets to access them
                            if let result = feed["results"] as? [[String: Any]]{
                                for item in result {
                                    // attempting to store data in Song object, this is where problems appear
                                    if let songName = (item["name"] as AnyObject? as? String),
                                        let artistName = (item["artistName"] as AnyObject? as? String),
                                        let coverArt = (item["artworkUrl100"] as AnyObject? as? String),
                                        let artistPage = (item["artistUrl"] as AnyObject? as? String) {
                                        self.songArray.append(Song(songName: songName, artistName: artistName, coverArt: coverArt, artistPage: artistPage))

                                        // printing the data to the console works here but I can't save the data to an object
                                    }
                                }
                            }
                        }

                    } catch {
                        print(error.localizedDescription)
                        print(Error.self)
                        return
                    }
                }
            }
        }
        songTask.resume()
    }
}

当我尝试打印字符串值时,我得到的要么是nil,要么当我尝试计算songArray数组中存在的对象的数量时,我得到的只是0。

1 个答案:

答案 0 :(得分:1)

基本上,您的代码是正确的并且应该可以使用,但是这是使用Decodable的版本。

songs属性将包含歌曲数据

struct Root : Decodable {
    let feed : Feed
}

struct Feed : Decodable {
    let results : [Song]
}

struct Song : Decodable {
    let name, artistName : String
    let artworkUrl100, artistUrl : URL
}

class JSONSongs {

    var songs = [Song]()

    func getSongs() {

        let jsonSongUrl = "https://rss.itunes.apple.com/api/v1/us/apple-music/top-songs/all/50/explicit.json"
        let songUrl = URL(string: jsonSongUrl) // convert string to usable url

        // start url session task with apple music api url...
        // we get some data(hopefully), a response code and an error(hoepfully not)
        let songTask = URLSession.shared.dataTask(with: songUrl!) { [weak self] data, _, error in

            // checking for an error
            if let error = error { print(error); return }
            do {
                // taking the json data and converting it so we can make objects
                let result = try JSONDecoder().decode(Root.self, from: data!)
                self?.songs = result.feed.results
                print(self?.songs)
            } catch {
                print(error)
            }
        }
        songTask.resume()
    }
}