从JSON检查空数组

时间:2016-05-27 13:54:44

标签: ios arrays json swift

我正在尝试从JSON获取一个字符串数组,并且我试图弄清楚如果返回的数组为空则如何处理它。在某些情况下,返回值为[],而对于其他情况,数组包含字符串值。由于意外地找到了零值,它正在崩溃。

为了澄清,健身房数组是从另一个类传递的,这里的一切都没有图像代码。

以下是我的相关代码:

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!
            } 
        }
    }
}

1 个答案:

答案 0 :(得分:0)

numberOfRowsInSection应该返回gymImages.count(如果尚未返回)。

然后作为保障,你可以随时

if indexPath.row < gymImages.count {

}

访问cellForRowAtIndexPath

中的内容之前