[英]Downloading json and displaying in UITableView with swift
我進行了一次初級 iOS 工作面試的測試。 它是從 twitch.tv 獲取最新游戲並在 UITableView 上使用自定義單元格顯示它們。 代碼和注釋一起在下面。 除了使用庫獲取json之外,有人可以指出錯誤嗎? 我認為數據模型可以更好,而不是使用三個不同的表。
import UIKit
class ViewController: UIViewController, UITableViewDelegate {
@IBOutlet weak var tableView: UITableView!
//This is a the quick fix, another way would be to create a data class with objects and properties: name, viewers and image.
//Then create an arrray of objects where there are stored. Although the implemented solution is a quick faster and has a little les memory usage.
//setting up different arrays for each data type to access them globally at some point
var JSONGameName: [String] = []
var JSONViewers: [Int] = []
var JSONGameImages: [String] = []
override func viewDidLoad() {
super.viewDidLoad()
loadAndDecodeJson()
}
//this functions uses the default way to implement json in swift. For more advanced data or multiple json files
//the suggestions is to use an external library like SwiftyJson
func loadAndDecodeJson(){
//defining the url of the nsurl string to download
//if not secure URL allow it in the plist file
let url = NSURL(string: "https://api.twitch.tv/kraken/games/top")
//create the task to handle the url
let task = NSURLSession.sharedSession().dataTaskWithURL(url!) {(data, response, error) -> Void in
//when task completes this will run
//need to check if data is not nil
if error == nil {
//serialize the json to a dictionary
do {
let jsonResult = try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers) as! NSDictionary
//loop through the data but first check if it hsa something in it
if jsonResult.count > 0 {
if let items = jsonResult["top"] as? NSArray {
for item in items {
if let viewers = item["viewers"] as? NSInteger {
print(viewers)
self.JSONViewers.append(viewers)
}
if let games = item["game"] as? NSDictionary {
if let name = games["name"] as? NSString {
print (name)
self.JSONGameName.append(name as String)
}
if let logo = games["logo"] as? NSDictionary {
if let small = logo["small"] as? NSString {
print (small)
self.JSONGameImages.append(small as String)
}
}
}
}
}
}
//reload table after json parsing is done
dispatch_async(dispatch_get_main_queue(), { () -> Void in
self.tableView.reloadData()
})
} catch {
print("error: parsing json")
}
} else {
//Show error message that there is probably no connection
let alert = UIAlertController(title: "Oopps..", message: "The was an error downloading data", preferredStyle: UIAlertControllerStyle.Alert)
alert.addAction(UIAlertAction(title: "Ok", style: UIAlertActionStyle.Default, handler: nil))
self.presentViewController(alert, animated: true, completion: nil)
}
}
//execute the async task
task.resume()
}
//defining number os section
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
//function to determine the number of list items
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return JSONGameName.count
}
//the view of every cell of the list
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
//custom cell identifier
let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! ViewControllerCell
//setting up the images and casting them from strings to UIImages
let imageURL = NSURL(string: JSONGameImages[indexPath.row])
let data = NSData(contentsOfURL: imageURL!)
//setting game name, images and viewers on cells
cell.gameName?.text = JSONGameName[indexPath.row]
cell.gameViewers?.text = String (JSONViewers[indexPath.row])
cell.gameImage?.image = UIImage(data: data!)
return cell
}
}
這是自定義單元格
import UIKit
class ViewControllerCell: UITableViewCell {
@IBOutlet weak var gameImage: UIImageView!
@IBOutlet weak var gameName: UILabel!
@IBOutlet weak var gameViewers: UILabel!
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
override func setSelected(selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
}
PS:我無緣無故得到了一些反對票。 這個問題有什么問題? 我有一個解決方案並集思廣益以尋求更好的解決方案。
import UIKit
class ViewController: UIViewController, UITableViewDelegate {
@IBOutlet weak var tableView: UITableView!
//This is a the quick fix, another way would be to create a data class with objects and properties: name, viewers and image.
//Then create an arrray of objects where there are stored. Although the implemented solution is a quick faster and has a little les memory usage.
//setting up different arrays for each data type to access them globally at some point
var JSONGameName: [String] = []
var JSONViewers: [Int] = []
var JSONGameImages: [String] = []
override func viewDidLoad() {
super.viewDidLoad()
loadAndDecodeJson()
}
//this functions uses the default way to implement json in swift. For more advanced data or multiple json files
//the suggestions is to use an external library like SwiftyJson
func loadAndDecodeJson(){
//defining the url of the nsurl string to download
//if not secure URL allow it in the plist file
let url = NSURL(string: "https://api.twitch.tv/kraken/games/top")
//create the task to handle the url
let task = NSURLSession.sharedSession().dataTaskWithURL(url!) {(data, response, error) -> Void in
//when task completes this will run
//need to check if data is not nil
if error == nil {
//serialize the json to a dictionary
var errorJson:NSError?=nil
var jsonResult=NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: &errorJson) as? NSDictionary
//loop through the data but first check if it hsa something in it
if jsonResult!.count > 0 {
if let items = jsonResult!["top"] as? NSArray {
for item in items {
if let viewers = item["viewers"] as? NSInteger {
print(viewers)
self.JSONViewers.append(viewers)
}
if let games = item["game"] as? NSDictionary {
if let name = games["name"] as? NSString {
print (name)
self.JSONGameName.append(name as String)
}
if let logo = games["logo"] as? NSDictionary {
if let small = logo["small"] as? NSString {
print (small)
self.JSONGameImages.append(small as String)
}
}
}
}
}
}
//reload table after json parsing is done
dispatch_async(dispatch_get_main_queue(), { () -> Void in
self.tableView.reloadData()
})
} else {
//Show error message that there is probably no connection
let alert = UIAlertController(title: "Oopps..", message: "The was an error downloading data", preferredStyle: UIAlertControllerStyle.Alert)
alert.addAction(UIAlertAction(title: "Ok", style: UIAlertActionStyle.Default, handler: nil))
self.presentViewController(alert, animated: true, completion: nil)
}
}
//execute the async task
task.resume()
}
//defining number os section
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
//function to determine the number of list items
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return JSONGameName.count
}
//the view of every cell of the list
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
//custom cell identifier
var cell:CustomTableViewCell? = tableView.dequeueReusableCellWithIdentifier("Cell") as? CustomTableViewCell
cell=nil
if cell==nil{
cell=NSBundle.mainBundle().loadNibNamed("CustomTableViewCell", owner: self, options: nil)[0] as? CustomTableViewCell
}
//setting up the images and casting them from strings to UIImages
let imageURL = NSURL(string: JSONGameImages[indexPath.row])
let data = NSData(contentsOfURL: imageURL!)
//setting game name, images and viewers on cells
cell!.gameName?.text = JSONGameName[indexPath.row]
cell!.gameViewers?.text = String (JSONViewers[indexPath.row])
cell!.gameImage?.image = UIImage(data: data!)
return cell!
}
}
從下面的鏈接下載源代碼,它在我身邊工作。
讓我知道是否有任何錯誤? https://www.dropbox.com/sh/9ochfbi1pyxnt8l/AABlUC0PojpTmiEvYIYEJrAMA?dl=0
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.