解析JSON数据以填充TableView



我有一个JSON(现在在本地(,我想解析将这些数据放在listView中。

我已经创建了视图,并尝试了一些事情(例如本教程:https://www.journaldev.com/21839/ios-swift-json-parsing-tutorial(。

这是我尝试过的一些代码:

class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
@IBOutlet weak var labelHeader: UILabel!
@IBOutlet weak var tableView: UITableView!
var channelList = [channelData]()
override func viewDidLoad() {
    super.viewDidLoad()
let url = Bundle.main.url(forResource: "channels", withExtension: "json")
    guard let jsonData = url
        else{
            print("data not found")
            return
    }
    guard let data = try? Data(contentsOf: jsonData) else { return }
    guard let json = try? JSONSerialization.jsonObject(with: data, options: []) else{return}
    if let dictionary = json as? [String: Any] {
        if let title = dictionary["title"] as? String {
            print("in title")
            labelHeader.text = title
        }
        if let data = dictionary["data"] as? Any {
            print("data is (data)")
        }
        if let date = dictionary["date"] as? Date {
            print("date is (date)")
        }
        // And so on
        for (key, value) in dictionary {
            print("Key is: (key) and value is (value)" )
            //This print the whole JSON to the console.
        }
    }
    //Now lets populate our TableView
    let newUrl = Bundle.main.url(forResource: "channels", withExtension: "json")
    guard let j = newUrl
        else{
            print("data not found")
            return
    }
    guard let d = try? Data(contentsOf: j)
        else { print("failed")
            return
    }
    guard let rootJSON = try? JSONSerialization.jsonObject(with: d, options: [])
        else{ print("failedh")
            return
    }
    if let JSON = rootJSON as? [String: Any] {
        labelHeader.text = JSON["id"] as? String //Should update the Label in the ListView with the ID found in the JSON
        guard let jsonArray = JSON["type"] as? [[String: Any]] else {
            return
        }
        let name = jsonArray[0]["name"] as? String
        print(name ?? "NA")
        print(jsonArray.last!["date"] as? Int ?? 1970)
        channelList = jsonArray.compactMap{return channelData($0)}
        self.tableView.reloadData()
    }
}

这是JSON文件的示例:

{
"format": "json",
"data": [
    {
        "type": "channel",
        "id": "123",
        "updated_at": "2019-05-03 11:32:57",
        "context": "search",
        "relationships": {
            "recipients": [
                {
                    "type": "user",
                    "id": 321,
                    "participant_id": 456
                }
            ],
            "search": {
                "type": "search",
                "title": "Title"
            },
        }
    },

我想找到与这种JSON合作的最佳方法。

目前,我无法将数据获取到ListView。我最多的是我的JSON在Xcode的控制台中(至少意味着我能够打开JSON(。

请将其用作当前开发的基本代码。我使用的结构可以帮助您在JSON模型上保留订单,同时将其正确编码,并将其用作将来的对象。

structs

// http request response results iTunes Site.
struct SearchResult: Decodable {
    let resultCount: Int
    let results: [Result]
}
// Raw Result
struct Result: Decodable {
    let trackId: Int
    let artistId: Int
    let artistName: String
    let collectionName: String
    let trackName: String
    let artworkUrl30: String
    let artworkUrl60: String
    let artworkUrl100: String
    let primaryGenreName: String
    let trackPrice: Float
    let collectionPrice: Float
    let trackTimeMillis: Int
}

功能代码

func fetchArtists(searchTerm: String, completion: @escaping (SearchResult?, Error?) -> ()) {
        let escapedString = searchTerm.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed)!
        let urlString = "https://itunes.apple.com/search?term=(escapedString)&entity=musicTrack"
        fetchGenericJSONData(urlString: urlString, completion: completion)
    }
    func fetchGenericJSONData<T: Decodable>(urlString: String, completion: @escaping (T?, Error?) -> ()) {
        guard let url = URL(string: urlString) else { return }
        URLSession.shared.dataTask(with: url) { (data, resp, err) in
            if let err = err {
                completion(nil, err)
                return
            }
            do {
                let objects = try JSONDecoder().decode(T.self, from: data!)
                completion(objects, nil)
            } catch {
                completion(nil, error)
            }
            }.resume()
    }

请求代码如何使用它。

fetchArtists(searchTerm: searchText) { res, err in
    if let err = err {
        print("Failed to fetch artists:", err)
        return
    }
    self.iTunesResults = res?.results ?? []
    print(self.iTunesResults.artistName)
    // Uncomment this in case you have a tableview to refresh
    // DispatchQueue.main.async {
    //     self.tableView.reloadData()
    // }
}

Swift 4 中解析JSON的推荐方法是Codable协议。

创建结构

struct Root: Decodable {
    let format: String
    let data: [ChannelData]
}
struct ChannelData: Decodable {
    let type, id, updatedAt, context: String
    let relationships: Relationships
}
struct Relationships: Decodable {
    let recipients: [Recipient]
    let search: Search
}
struct Recipient: Decodable {
    let type: String
    let id: Int
    let participantId: Int
}
struct Search: Decodable {
    let type: String
    let title: String
}

由于channels.json文件在应用程序包中,因此无法修改,您可以将viewDidLoad降低到

var channelList = [ChannelData]()
override func viewDidLoad() {
    super.viewDidLoad()
    let url = Bundle.main.url(forResource: "channels", withExtension: "json")!
    let data = try! Data(contentsOf: url)
    let decoder = JSONDecoder()
    decoder.keyDecodingStrategy = .convertFromSnakeCase
    let result = try! decoder.decode(Root.self, from: data)
    channelList = result.data
    self.tableView.reloadData()
}

如果代码崩溃,它会显示出设计错误。结构在问题中与JSON匹配。大概它更大,然后您必须调整或扩展结构。

最新更新