从 JSON 检查空数组
Posted
技术标签:
【中文标题】从 JSON 检查空数组【英文标题】:Check For Empty Array From JSON 【发布时间】:2016-05-27 13:54:43 【问题描述】:我试图从 JSON 中获取一个字符串数组,并且我试图弄清楚如果返回的数组是空的如何处理它。在某些情况下,返回值为 [],而在其他情况下,数组包含字符串值。由于意外找到 nil 值而崩溃。
为澄清起见,gyms 数组是从另一个类传递的,这里的所有内容都可以在没有图像代码的情况下运行。
这是我的相关代码:
var gyms = [AnyObject]()
var imageArrays = [[String]?]()
在 viewDidLoad() 中
getGymImages()
获取JSON数据的方法:
func getGymImages()
var index = 0
for dictionary in gyms
let id = dictionary["id"] as! String
let urlString = String("https://gyminyapp.azurewebsites.net/api/GymImage/\(id)")
let url = NSURL(string: urlString)
let data = NSData(contentsOfURL: url!)
do
let json = try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers)
for imageArray in json as! [AnyObject]
imageArrays.append((imageArray as? [String])!)
catch
print("Error")
index += 1
addImagesToGyms()
func addImagesToGyms()
var index = 0;
for array in imageArrays
var dictionary = gyms[index] as! [String:AnyObject]
dictionary["images"] = array
gyms[index] = dictionary
index += 1
在 cellForRowAtIndexPath() 中
let gymImages = dictionary["images"] as! [String]
if gymImages.count > 0
let firstImageURL = gymImages[0] as String
cell.cellImageView.sd_setImageWithURL(NSURL(string: firstImageURL))
编辑:我被要求显示更多文件,所以在这里。
import UIKit
class GymListTableViewController: UITableViewController
var gyms = [AnyObject]()
var gymName: String?
var gymAddress: String?
var gymPhoneNumber: String?
var gymWebsite: String?
var gymID: String?
var gymLatitude: String?
var gymLongitude: String?
var maxDistance: Double?
var myLocation: CLLocation?
var milesArray = [Double]()
var imageArrays = [[String]?]()
var segmentedControl: UISegmentedControl?
override func viewDidLoad()
super.viewDidLoad()
self.title = "Gyms"
tableView.registerNib(UINib(nibName: "GymListTableViewCell", bundle: nil), forCellReuseIdentifier: "gymCell")
self.navigationItem.rightBarButtonItem = UIBarButtonItem(image: UIImage(named: "waypoint_map"), style: .Done, target: self, action: #selector(showMapView))
self.navigationItem.rightBarButtonItem?.tintColor = BarItems.greenTintColor
segmentedControl = UISegmentedControl(items: ["A-Z", "Z-A", "Rating", "Distance"])
segmentedControl?.sizeToFit()
segmentedControl?.selectedSegmentIndex = 0
segmentedControl!.setTitleTextAttributes([NSFontAttributeName: UIFont(name:"Helvetica-Light", size: 15)!],
forState: UIControlState.Normal)
segmentedControl?.addTarget(self, action: #selector(changeSelectedSegmentIndex), forControlEvents: .ValueChanged)
self.navigationItem.titleView = segmentedControl
sortAlphabetically()
let backgroundImage = UIImage(named: "gray_background")
let backgroundImageView = UIImageView(image: backgroundImage)
tableView.backgroundView = backgroundImageView
addDistancesToGyms()
getGymImages()
// geocodeAddresses()
override func didReceiveMemoryWarning()
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
func addDistancesToGyms()
var index = 0
for distance in milesArray
var dictionary = gyms[index] as! [String:AnyObject]
dictionary["distance"] = distance
gyms[index] = dictionary
index += 1
func getGymImages()
var index = 0
for dictionary in gyms
let id = dictionary["id"] as! String
let urlString = String("https://gyminyapp.azurewebsites.net/api/GymImage/\(id)")
let url = NSURL(string: urlString)
let data = NSData(contentsOfURL: url!)
do
let json = try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers)
for imageArray in json as! [AnyObject]
imageArrays.append((imageArray as? [String])!)
catch
print("Error")
index += 1
addImagesToGyms()
func addImagesToGyms()
var index = 0;
for array in imageArrays
var dictionary = gyms[index] as! [String:AnyObject]
dictionary["images"] = array
gyms[index] = dictionary
index += 1
func changeSelectedSegmentIndex()
let segmentTouched = segmentedControl?.selectedSegmentIndex
if segmentTouched == 0
sortAlphabetically()
else if segmentTouched == 1
sortReverseAlphabetically()
else if segmentTouched == 2
sortByRatingAscending()
else
sortByDistanceAscending()
func sortAlphabetically()
gyms.sortInPlace
(($0 as! Dictionary<String, AnyObject>)["name"] as? String) < (($1 as! Dictionary<String, AnyObject>)["name"] as? String)
tableView.reloadData()
func sortReverseAlphabetically()
gyms.sortInPlace
(($0 as! Dictionary<String, AnyObject>)["name"] as? String) > (($1 as! Dictionary<String, AnyObject>)["name"] as? String)
tableView.reloadData()
func sortByRatingAscending()
// TODO: Sort by rating
func sortByDistanceAscending()
gyms.sortInPlace
(($0 as! Dictionary<String, AnyObject>)["distance"] as? Double) < (($1 as! Dictionary<String, AnyObject>)["distance"] as? Double)
tableView.reloadData()
func showMapView()
self.performSegueWithIdentifier("displayMapSegue", sender: self.navigationController)
// MARK: - Table view data source
override func numberOfSectionsInTableView(tableView: UITableView) -> Int
return 1
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
return gyms.count
override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat
return 131
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
let cell = tableView.dequeueReusableCellWithIdentifier("gymCell", forIndexPath: indexPath) as! GymListTableViewCell
let dictionary = gyms[indexPath.row]
let addressDictionary = dictionary["address"]
let street = addressDictionary!!["streetAddress"] as! String
let city = addressDictionary!!["city"] as! String
let state = addressDictionary!!["state"] as! String
let zipInt = addressDictionary!!["zipCode"] as! Int
let zipCode = String(zipInt)
let addressString = String("\(street) " + "\(city), " + "\(state) " + "\(zipCode)")
cell.backgroundColor = UIColor.clearColor()
cell.gymNameLabel.text = dictionary["name"] as? String
cell.gymAddressLabel.text = addressString
let miles = dictionary["distance"] as! Double
let milesString = String(format: "%.1f miles", miles)
let milesLabelString = milesString
cell.milesLabel.text = milesLabelString
let gymImages = dictionary["images"] as! [String]
if gymImages.count > 0
let firstImageURL = gymImages[0] as String
cell.cellImageView.sd_setImageWithURL(NSURL(string: firstImageURL))
return cell
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath)
let dictionary = gyms[indexPath.row]
if dictionary["name"] as? String != nil
self.gymName = dictionary["name"] as? String
let cell = tableView.cellForRowAtIndexPath(indexPath) as! GymListTableViewCell
self.gymAddress = cell.gymAddressLabel.text
if dictionary["phone"] as? String != nil
self.gymPhoneNumber = dictionary["phone"] as? String
if dictionary["website"] as? String != nil
self.gymWebsite = dictionary["website"] as? String
if dictionary["id"] as? String != nil
self.gymID = dictionary["id"] as? String
if dictionary["latitude"] as? String != nil
self.gymLatitude = dictionary["latitude"] as? String
if dictionary["longitude"] as? String != nil
self.gymLongitude = dictionary["longitude"] as? String
self.performSegueWithIdentifier("detailFromListSegue", sender: self.navigationController)
// MARK: - Navigation
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?)
if segue.identifier == "detailFromListSegue"
let gymDetailVC = segue.destinationViewController as! DetailTableViewController
if self.gymName != nil
gymDetailVC.gymName = self.gymName
else
gymDetailVC.gymName = nil
if self.gymAddress != nil
gymDetailVC.gymAddress = self.gymAddress
else
gymDetailVC.gymAddress = nil
if self.gymPhoneNumber != nil
gymDetailVC.gymPhoneNumber = self.gymPhoneNumber
else
gymDetailVC.gymPhoneNumber = nil
if self.gymWebsite != nil
gymDetailVC.gymWebsite = self.gymWebsite
else
gymDetailVC.gymWebsite = nil
if self.gymID != nil
gymDetailVC.gymID = self.gymID!
else
// gymDetailVC.gymID = nil
if self.gymLatitude != nil
gymDetailVC.gymLatitude = self.gymLatitude!
if self.gymLongitude != nil
gymDetailVC.gymLongitude = self.gymLongitude!
【问题讨论】:
你在什么时候因为意外的 nil 而崩溃?在你的cellForRowAtIndexPath
?
它在 getGymImages() 中崩溃,在将值分配给 id 之后。
看起来您在任何时候都没有向gyms
附加任何内容。 for dictionary in gyms
肯定不会做任何事吗?
gyms 数组是从另一个类传递过来的。这一切都可以在没有图像代码的情况下工作。
抱歉,只是为了确认一下——由于这一行,它返回了意外的 nil:let id = dictionary["id"] as! String
如果是这样,那么字典不包含键为“id”的记录
【参考方案1】:
numberOfRowsInSection
应该返回 gymImages.count
(如果还没有的话)。
那么作为保障,你总是可以做到的
if indexPath.row < gymImages.count
在访问cellForRowAtIndexPath
中的内容之前
【讨论】:
它正在返回gyms.count 我们能看到更多的文件吗?以上是关于从 JSON 检查空数组的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 JsonConvert 从包含空数组的 JSON 字符串中获取 DataTable?