我有一个JSON(目前在本地),我想对其进行解析以将这些数据放入listView中。
我已经创建了视图并尝试了一些操作(例如本教程:https://www.journaldev.com/21839/ios-swift-json-parsing-tutorial)来解析该JSON,但没有成功。
这是我尝试过的一些代码:
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。我最多拥有的是xCode控制台中的JSON(至少这意味着我能够打开JSON)。
答案 0 :(得分:0)
请使用它作为当前开发的基础代码。我已经使用Structs,它将帮助您在JSON模型上保持订单以及对其进行正确编码,并在将来将其用作对象。
结构
// 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()
// }
}
答案 1 :(得分:0)
在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匹配。可能更大了,那么您必须调整或扩展结构。