我是Xcode和Swift的新手。我需要帮助将JSON文件中的数据显示到带有节和行的TableView中。我需要在每个街区展示不同的餐馆。我想我需要在我的JSON文件中进行更改,但我无法弄清楚。我真的很感激任何帮助。欢呼声。
这是我的JSON文件:
{
"hoods": {
"neighborhoodNames": {
"marina":[
{
"name": "MARINA-1",
"dob": "December 18, 1963",
"image": "http://microblogging.wingnity.com/JSONParsingTutorial/brad.jpg"
},
{
"name": "MARINA-2",
"description": "Tom Cruise, is an American film actor and producer. He has been nominated for three Academy Awards and has won three Golden Globe Awards. He started his career at age 19 in the 1981 film Endless Love.",
"dob": "July 3, 1962",
"image": "http://microblogging.wingnity.com/JSONParsingTutorial/cruise.jpg"
},
{
"name": "MARINA-3",
"description": "John Christopher 'Johnny' Depp II is an American actor, film producer, and musician. He has won the Golden Globe Award and Screen Actors Guild award for Best Actor.",
"dob": "June 9, 1963",
"image": "http://microblogging.wingnity.com/JSONParsingTutorial/johnny.jpg"
}
],
"MISSION":[
{
"name": "MISSION-1",
"dob": "December 18, 1963",
"image": "http://microblogging.wingnity.com/JSONParsingTutorial/brad.jpg"
},
{
"name": "MISSION-2",
"dob": "July 3, 1962",
"image": "http://microblogging.wingnity.com/JSONParsingTutorial/cruise.jpg"
},
{
"name": "MISSION-3",
"dob": "June 9, 1963",
"image": "http://microblogging.wingnity.com/JSONParsingTutorial/johnny.jpg"
},
{
"name": "MISSION-4",
"dob": "June 9, 1963",
"image": "http://microblogging.wingnity.com/JSONParsingTutorial/johnny.jpg"
}
]}
}
}
这是JSON文件的链接:http://barhoppersf.com/json/hoods.json
这是我的Xcode:
import UIKit
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
let urlString = "http://barhoppersf.com/json/hoods.json"
@IBOutlet weak var tableView: UITableView!
var nameArray:[[String]] = []
var dobArray:[[String]] = []
var imgURLArray:[[String]] = []
var neighborhoodNames = [String]()
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
tableView.dataSource = self
self.downloadJsonWithURL()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func downloadJsonWithURL() {
let url = NSURL(string: urlString)
URLSession.shared.dataTask(with: (url as URL?)!, completionHandler: {(data, response, error) -> Void in
if let jsonObj = try? JSONSerialization.jsonObject(with: data!, options: .allowFragments) as? NSDictionary {
if let actorArray = jsonObj!.value(forKey: "hoods") as? NSArray {
for actor in actorArray{
if let actorDict = actor as? NSDictionary {
if let name = actorDict.value(forKey: "neighborhoodNames") {
self.neighborhoodNames.append(name as! String)
}
if let name = actorDict.value(forKey: "name") {
self.nameArray.append([name as! String])
}
if let name = actorDict.value(forKey: "dob") {
self.dobArray.append([name as! String])
}
if let name = actorDict.value(forKey: "image") {
self.imgURLArray.append([name as! String])
}
}
}
}
// self.nameArray = self.nameArray.sorted()
OperationQueue.main.addOperation({
self.tableView.reloadData()
})
}
}).resume()
}
func downloadJsonWithTask() {
let url = NSURL(string: urlString)
var downloadTask = URLRequest(url: (url as URL?)!, cachePolicy: URLRequest.CachePolicy.reloadIgnoringCacheData, timeoutInterval: 15)
downloadTask.httpMethod = "GET"
URLSession.shared.dataTask(with: downloadTask, completionHandler: {(data, response, error) -> Void in
let jsonData = try? JSONSerialization.jsonObject(with: data!, options: .allowFragments)
print(jsonData as Any)
}).resume()
}
// MARK: - changing the color, background and position of the header
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let headerView = UIView()
headerView.backgroundColor = UIColor.self.init(red: 254/255, green: 170/255, blue: 25/255, alpha: 1.0)
let headerLabel = UILabel(frame: CGRect(x: 8, y: 5, width: tableView.bounds.size.width, height: tableView.bounds.size.height))
headerLabel.font = UIFont(name: "Trebuchet MS", size: 15)
headerLabel.textColor = UIColor.darkGray
headerLabel.text = self.tableView(self.tableView, titleForHeaderInSection: section)
headerLabel.sizeToFit()
headerView.addSubview(headerLabel)
return headerView
}
// MARK: - changing the size of the header cell
// func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
// return 40
// }
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return (nameArray[section].count)
}
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return neighborhoodNames[section]
}
func numberOfSections(in tableView: UITableView) -> Int {
return neighborhoodNames.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell") as! TableViewCell
// cell.nameLabel.text = nameArray[indexPath.row]
cell.nameLabel?.text = nameArray[indexPath.section][indexPath.row]
return cell
}
// set up A_Z index
// func sectionIndexTitles(for tableView: UITableView) -> [String]? {
// return indexName
// }
// call correct section when index is tapped
func tableView(_ tableView: UITableView, sectionForSectionIndexTitle title: String, at index: Int) -> Int {
guard let index = indexName.index(of: title) else {
return -1
}
return index
}
///for showing next detailed screen with the downloaded info
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let vc = self.storyboard?.instantiateViewController(withIdentifier: "DetailViewController") as! DetailViewController
vc.imageString = imgURLArray[indexPath.section][indexPath.row]
vc.nameString = nameArray[indexPath.section][indexPath.row]
vc.dobString = dobArray[indexPath.section][indexPath.row]
self.navigationController?.pushViewController(vc, animated: true)
}
}
非常感谢! 典
答案 0 :(得分:0)
上面的JSON和该网址中的JSON是不同的,所以我在这里可以使用它们。
import UIKit
struct Actor {
var children: String
var country: String
var description: String
var dob: String
var height: String
var image: String
var name: String
var spouse: String
init?(dict:Dictionary<String,String>) {
guard
let children = dict["children"],
let country = dict["country"],
let description = dict["description"],
let dob = dict["dob"],
let height = dict["height"],
let image = dict["image"],
let name = dict["name"],
let spouse = dict["spouse"]
else {
return nil
}
self.children = children
self.country = country
self.description = description
self.dob = dob
self.height = height
self.image = image
self.name = name
self.spouse = spouse
}
}
struct Restaurant {
var name: String
var dob: String
var image: String
init?(dict:Dictionary<String,String>) {
guard
let name = dict["name"],
let dob = dict["dob"],
let image = dict["image"]
else {
return nil
}
self.name = name
self.dob = dob
self.image = image
}
}
struct NeighborhoodActors {
var name: String
var actors: Array<Actor>
init(name:String, data:Array<Dictionary<String,String>>) {
self.name = name
self.actors = Array<Actor>()
for dict in data {
if let actor = Actor(dict: dict) {
self.actors.append(actor)
}
}
}
}
struct NeighborhoodRestaurants {
var name: String
var restaurants: Array<Restaurant>
init(name:String, data:Array<Dictionary<String,String>>) {
self.name = name
self.restaurants = Array<Restaurant>()
for dict in data {
if let restaurant = Restaurant(dict: dict) {
self.restaurants.append(restaurant)
}
}
}
}
class ViewController: UITableViewController {
let urlString = "http://barhoppersf.com/json/hoods.json"
var tableData = Array<NeighborhoodRestaurants>()
override func viewDidLoad() {
super.viewDidLoad()
self.downloadJsonWithURL() // This loads tableview with data from url
load(file: "document") // This loads tableview with the json in your question, which I put in a json file to test
}
func load(file:String) {
guard let path = Bundle.main.path(forResource: file, ofType: "json") else { return }
guard let data = try? Data(contentsOf: URL(fileURLWithPath: path)) else { return }
guard let json = try? JSONSerialization.jsonObject(with: data) else { return }
guard let dict = json as? Dictionary<String,Dictionary<String,Dictionary<String,Array<Dictionary<String,String>>>>> else { return }
guard let hoods = dict["hoods"] else { return }
guard let names = hoods["neighborhoodNames"] else { return }
for (key, value) in names {
let neighborhood = NeighborhoodRestaurants(name: key, data: value)
self.tableData.append(neighborhood)
}
self.tableData.sort { $0.name > $1.name } // This will arrange the restaurants alphabetically
self.tableView.reloadData()
}
func downloadJsonWithURL() {
let url = NSURL(string: urlString)
URLSession.shared.dataTask(with: (url as URL?)!, completionHandler: {(data, response, error) -> Void in
if let error = error {
print(error.localizedDescription)
return
}
if let data = data {
guard let json = try? JSONSerialization.jsonObject(with: data) else { return }
guard let dict = json as? Dictionary<String,Dictionary<String,Dictionary<String,Array<Dictionary<String,String>>>>> else { return }
guard let hoods = dict["hoods"] else { return }
guard let names = hoods["neighborhoodNames"] else { return }
for (key, value) in names {
let neighborhood = NeighborhoodActors(name: key, data: value)
// self.tableData.append(neighborhood)
}
DispatchQueue.main.async {
self.tableView.reloadData()
}
}
}).resume()
}
// MARK: - changing the color, background and position of the header
override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let headerView = UIView()
headerView.backgroundColor = UIColor.self.init(red: 254/255, green: 170/255, blue: 25/255, alpha: 1.0)
let headerLabel = UILabel(frame: CGRect(x: 8, y: 5, width: tableView.bounds.size.width, height: tableView.bounds.size.height))
headerLabel.font = UIFont(name: "Trebuchet MS", size: 15)
headerLabel.textColor = UIColor.darkGray
headerLabel.text = self.tableView(self.tableView, titleForHeaderInSection: section)
headerLabel.sizeToFit()
headerView.addSubview(headerLabel)
return headerView
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.tableData[section].restaurants.count
}
override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return self.tableData[section].name
}
override func numberOfSections(in tableView: UITableView) -> Int {
return self.tableData.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
cell.textLabel?.text = self.tableData[indexPath.section].restaurants[indexPath.row].name
return cell
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let vc = self.storyboard?.instantiateViewController(withIdentifier: "DetailViewController") as! DetailViewController
vc.restaurant = self.tableData[indexPath.section].restaurants[indexPath.row]
self.navigationController?.pushViewController(vc, animated: true)
}
}
class DetailViewController: UIViewController {
@IBOutlet var imageView: UIImageView!
@IBOutlet weak var nameLabel: UILabel!
@IBOutlet weak var dobLabel: UILabel!
var restaurant: Restaurant!
override func viewDidLoad() {
super.viewDidLoad()
self.nameLabel.text = self.restaurant.name
self.dobLabel.text = self.restaurant.dob
if let url = URL(string: self.restaurant.image) {
let task = URLSession.shared.dataTask(with: url) { data, resonse, error in
if let error = error {
print(error.localizedDescription)
return
}
if let data = data {
let image = UIImage(data: data)
DispatchQueue.main.async {
self.imageView.image = image
}
}
}
task.resume()
}
}
}
这是打开网址,打开苹果地图和拨打电话号码的方法。
func telephone(phoneNumber:String) {
let application = UIApplication.shared
if application.openURL(URL(string: "tel://\(phoneNumber)")!) {
print("Ringing")
} else {
print("Something has gone wrong.")
}
}
func directions(address:String) {
let geocoder = CLGeocoder()
geocoder.geocodeAddressString(address) { (placemarks, error) in
if let description = error?.localizedDescription {
print(description)
return
}
if let placemark = placemarks?.first {
let pin = MKPlacemark(placemark: placemark)
let item = MKMapItem(placemark: pin)
let region = MKCoordinateRegionMakeWithDistance(pin.coordinate, 1000, 1000)
let options: Dictionary<String,Any> = {
var dict = Dictionary<String,Any>()
dict[MKLaunchOptionsMapCenterKey] = NSValue(mkCoordinate: region.center)
dict[MKLaunchOptionsMapSpanKey] = NSValue(mkCoordinateSpan: region.span)
return dict
}()
item.openInMaps(launchOptions: options)
return
}
print("An unknown error has occured.")
}
}
func website(url:String) {
if let url = URL(string: url) {
let application = UIApplication.shared
application.openURL(url)
return
}
print("The URL is invalid.")
}